Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(progress-spinner): switch to css-based animation #6551

Merged
merged 2 commits into from
Oct 5, 2017

Conversation

crisbeto
Copy link
Member

@crisbeto crisbeto commented Aug 19, 2017

Reworks the progress spinner to use a CSS-based indeterminate animation. For IE and Edge where we can't pull of the animation reliably, it falls back to a non-spec animation.

Demo: https://material-cb7ec.firebaseapp.com/progress-spinner

@googlebot googlebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Aug 19, 2017
@crisbeto crisbeto force-pushed the progress-spinner-rewrite branch 2 times, most recently from 283306a to c5a54d0 Compare August 20, 2017 16:59
Copy link
Member

@jelbourn jelbourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, one minor comment

// stylelint-enable
}

@keyframes mat-progress-spinner-stroke-rotate-fallback {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add comment describing this animation?

// For IE11 and Edge, we fall back to simply rotating the spinner because
// animating stroke-dashoffset is not supported. The fallback uses multiple
// iterations to vary where the spin "lands".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. FWIW, animating stroke-dashoffset is supported in Edge, but rotation the circle with a CSS transform isn't.

@crisbeto crisbeto added the action: merge The PR is ready for merge by the caretaker label Aug 21, 2017
@kara kara added the presubmit failures This PR has failures in Google's internal presubmit process and cannot be immediately merged label Aug 23, 2017
@kara
Copy link
Contributor

kara commented Aug 23, 2017

@crisbeto @jelbourn This PR breaks internal tests because some projects are relying on being able to set [style.width.px] and [style.height.px] on the spinner element. Thoughts?

@kara kara added needs: discussion Further discussion with the team is needed before proceeding and removed action: merge The PR is ready for merge by the caretaker labels Aug 23, 2017
@crisbeto
Copy link
Member Author

crisbeto commented Aug 23, 2017

@jelbourn The reason I removed the width and height from the CSS was because we need control over the height due to the strokeWidth option. If the stroke width is greater than the default 10px it will overflow the element, which is why I ended up making it smaller to compensate. My guess is that the option isn't widely used anyway so we could get rid of it and let users override it with CSS. If they decide to override it, they can also tweak the margins/padding/width or height depending on their setup.

@jelbourn jelbourn added the P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful label Sep 15, 2017
@crisbeto crisbeto force-pushed the progress-spinner-rewrite branch 6 times, most recently from 1d9e9d8 to f7f4b07 Compare September 22, 2017 19:45
@kara kara added pr: needs review and removed pr: lgtm needs: discussion Further discussion with the team is needed before proceeding labels Sep 22, 2017
return this.mode == 'determinate' ? 0 : null;
}
/** Tracks diameters of existing instances to de-dupe generated styles. */
static diameters = new Set<number>([100]);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment about 100 being the default diameter?

if (this._interdeterminateInterval) {
clearInterval(this._interdeterminateInterval);
set diameter(size: number) {
this._setDiameterClass(size);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Break the content of this setter into its own function?

}

return null;
}

private _setDiameterClass(size: number): void {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsDoc descriptions for these functions?

}
}

_getStrokeDashOffset() {
get _circleRadius() {
return this._diameter / 2 - 5;
Copy link
Member Author

@crisbeto crisbeto Sep 22, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the 5 come from? I assume it's half the stroke width?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that's what it's supposed to be, yes; fixing.

$end: (1 - 0.8) * $_mat-progress-spinner-default-circumference; // end the animation at 80%
$fallback-iterations: 4;

@keyframes mat-progress-spinner-stroke-rotate-100 {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we keep this one around, considering that the keyframes are being generated at runtime?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We won't generate a style tag at runtime for the default diameter - only for custom diameters (the set starts with 100 included).

// Boilerplate for applying mixins to MdProgressSpinner.
/** @docs-private */
export class MdProgressSpinnerBase {
constructor(public _renderer: Renderer2, public _elementRef: ElementRef) {}
}
export const _MdProgressSpinnerMixinBase = mixinColor(MdProgressSpinnerBase, 'primary');

/* tslint:disable:max-line-length */
const INDETERMINATE_ANIMATION_TEMPLATE = `
.mat-progress-spinner-DIAMETER.mat-progress-spinner-indeterminate-animation[mode="indeterminate"] circle {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than constructing this selector, it might be better to just assign the animation-name: mat-progress-spinner-stroke-rotate-DIAMETER as an inline style. That way people can still override the timing and duration through CSS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh hey, that's a great idea. Should simplify this a lot.

set diameter(size: number) {
this._setDiameterClass(size);
this._diameter = size;
if (!MdProgressSpinner.diameters.has(this.diameter)) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't support the spec animation on IE and Edge, we shouldn't append the keyframes either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call

@kara kara force-pushed the progress-spinner-rewrite branch 2 times, most recently from 9b453c3 to 71c5cb6 Compare September 22, 2017 22:19
Copy link
Member Author

@crisbeto crisbeto left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, one nit. I'm not allowed to approve my own PR.

[style.animation-name]="'mat-progress-spinner-stroke-rotate-' + diameter"
[style.stroke-dashoffset.px]="_strokeDashOffset"
[style.stroke-dasharray.px]="_strokeCircumference"
[style.transform.rotate]="'360deg'"
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need this? It doesn't look like it does anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know, I thought that was from your commit, but now I have no idea. Maybe it's a weird rebase error? Don't remember adding it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, I haven't pulled in your changes into my local branch yet. I tried checking it out and it's not in there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I must have been testing something at some point? I'll remove it, in any case.

@crisbeto crisbeto added pr: lgtm action: merge The PR is ready for merge by the caretaker and removed pr: needs review labels Sep 26, 2017
@crisbeto
Copy link
Member Author

@kara this one needs a rebase.

@crisbeto crisbeto added pr: needs rebase and removed action: merge The PR is ready for merge by the caretaker labels Sep 29, 2017
crisbeto and others added 2 commits October 4, 2017 19:00
Reworks the progress spinner to use a CSS-based indeterminate animation. For IE and Edge where we can't pull of the animation reliably, it falls back to a non-spec animation.
@kara kara added action: merge The PR is ready for merge by the caretaker and removed pr: needs rebase presubmit failures This PR has failures in Google's internal presubmit process and cannot be immediately merged labels Oct 5, 2017
@kara kara merged commit 630dfad into angular:master Oct 5, 2017
@pabx06
Copy link

pabx06 commented Oct 23, 2017

@kara i am using the latest beta.
Changing the width & height style i still get 100px*100px spinner ...
i am using the spinner as

<mat-form-field ...> <input...> <span matSuffix style="height: 18px" align="end" *ngIf="searching"> <mat-progress-spinner mode="indeterminate" ng-disabled="true" style="height: 18px" align="end"> </mat-progress-spinner> </mat-form-field>

on debounced by 300ms keystroke

any idea how i could set the spinner to fit the text input field ?

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 7, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes PR author has agreed to Google's Contributor License Agreement P1 Impacts a large percentage of users; if a workaround exists it is partial or overly painful
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants