Skip to content

Commit 63f43bd

Browse files
crisbetojelbourn
authored andcommitted
perf(progress-circle): clean up animation on destroy (#617)
The indeterminate animation is based on an interval that keeps running, even after the element has been destroyed. This change cleans up when the element is destroyed. Also adds an extra null check for `performance.now`.
1 parent fda5617 commit 63f43bd

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

src/components/progress-circle/progress-circle.spec.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,27 @@ describe('MdProgressCircular', () => {
7474
done();
7575
});
7676
});
77+
78+
it('should clean up the indeterminate animation when the element is destroyed',
79+
(done: () => void) => {
80+
let template = `<md-progress-circle
81+
mode="indeterminate"
82+
*ngIf="!isHidden"></md-progress-circle>`;
83+
84+
builder
85+
.overrideTemplate(TestApp, template)
86+
.createAsync(TestApp)
87+
.then((fixture) => {
88+
fixture.detectChanges();
89+
let progressElement = getChildDebugElement(fixture.debugElement, 'md-progress-circle');
90+
expect(progressElement.componentInstance.interdeterminateInterval).toBeTruthy();
91+
92+
fixture.debugElement.componentInstance.isHidden = true;
93+
fixture.detectChanges();
94+
expect(progressElement.componentInstance.interdeterminateInterval).toBeFalsy();
95+
done();
96+
});
97+
});
7798
});
7899

79100

src/components/progress-circle/progress-circle.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
HostBinding,
44
ChangeDetectorRef,
55
ChangeDetectionStrategy,
6+
OnDestroy,
67
Input
78
} from '@angular/core';
89

@@ -41,13 +42,23 @@ type EasingFn = (currentTime: number, startValue: number,
4142
styleUrls: ['progress-circle.css'],
4243
changeDetection: ChangeDetectionStrategy.OnPush,
4344
})
44-
export class MdProgressCircle {
45+
export class MdProgressCircle implements OnDestroy {
4546
/** The id of the last requested animation. */
4647
private _lastAnimationId: number = 0;
4748

4849
/** The id of the indeterminate interval. */
4950
private _interdeterminateInterval: number;
5051

52+
/** @internal */
53+
get interdeterminateInterval() {
54+
return this._interdeterminateInterval;
55+
}
56+
/** @internal */
57+
set interdeterminateInterval(interval: number) {
58+
clearInterval(this._interdeterminateInterval);
59+
this._interdeterminateInterval = interval;
60+
}
61+
5162
/** The current path value, representing the progres circle. */
5263
private _currentPath: string;
5364
get currentPath() {
@@ -60,6 +71,11 @@ export class MdProgressCircle {
6071
this._changeDetectorRef.markForCheck();
6172
}
6273

74+
/** Clean up any animations that were running. */
75+
ngOnDestroy() {
76+
this._cleanupIndeterminateAnimation();
77+
}
78+
6379
/**
6480
* Value of the progress circle.
6581
*
@@ -162,8 +178,8 @@ export class MdProgressCircle {
162178
end = -temp;
163179
};
164180

165-
if (!this._interdeterminateInterval) {
166-
this._interdeterminateInterval = setInterval(
181+
if (!this.interdeterminateInterval) {
182+
this.interdeterminateInterval = setInterval(
167183
animate, duration + 50, 0, false);
168184
animate();
169185
}
@@ -174,10 +190,7 @@ export class MdProgressCircle {
174190
* Removes interval, ending the animation.
175191
*/
176192
private _cleanupIndeterminateAnimation() {
177-
if (this._interdeterminateInterval) {
178-
clearInterval(this._interdeterminateInterval);
179-
this._interdeterminateInterval = null;
180-
}
193+
this.interdeterminateInterval = null;
181194
}
182195
}
183196

@@ -219,7 +232,7 @@ function clamp(v: number) {
219232
* Returns the current timestamp either based on the performance global or a date object.
220233
*/
221234
function now() {
222-
if (typeof performance !== 'undefined') {
235+
if (typeof performance !== 'undefined' && performance.now) {
223236
return performance.now();
224237
}
225238
return Date.now();

0 commit comments

Comments
 (0)