Skip to content

Commit 40b384b

Browse files
committed
Timer: simplify update interval
1 parent be619d2 commit 40b384b

File tree

1 file changed

+19
-31
lines changed

1 file changed

+19
-31
lines changed

src/components/Timer.vue

Lines changed: 19 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class Timer extends Vue {
139139
: Timer.BASE_RADIUS);
140140
private fullCircleLength: number = 2 * Math.PI * this.radius.currentValue;
141141
private timeoutId: number | null = null;
142-
private updateIntervalId: number | null = null;
142+
private updateTimeoutId: number | null = null;
143143
private requestAnimationFrameId: number | null = null;
144144
private size: number = Timer.BASE_SIZE;
145145
@@ -151,7 +151,7 @@ class Timer extends Vue {
151151
152152
private destroyed() {
153153
clearTimeout(this.timeoutId);
154-
clearInterval(this.updateIntervalId);
154+
clearTimeout(this.updateTimeoutId);
155155
cancelAnimationFrame(this.requestAnimationFrameId);
156156
window.removeEventListener('resize', this._onResize);
157157
}
@@ -209,7 +209,8 @@ class Timer extends Vue {
209209
return { length, lengthWithLineCaps, gap, offset, strokeWidth };
210210
}
211211
212-
private get _updateInterval(): number {
212+
private _calculateUpdateInterval(): number {
213+
// Not a getter / computed prop to avoid unnecessary updates when not needed.
213214
const scaleFactor = this.size / Timer.BASE_SIZE;
214215
const circleLengthPixels = this.fullCircleLength * scaleFactor;
215216
const steps = circleLengthPixels * 3; // update every .33 pixel change for smooth transitions
@@ -226,7 +227,7 @@ class Timer extends Vue {
226227
this.radius.tweenTo(this.detailsShown || this.alwaysShowTime
227228
? Timer.RADIUS_GROWTH_FACTOR * Timer.BASE_RADIUS
228229
: Timer.BASE_RADIUS, 300);
229-
this._animateRadius();
230+
this._rerender();
230231
}
231232
232233
@Watch('startTime', { immediate: true })
@@ -238,39 +239,26 @@ class Timer extends Vue {
238239
if (this.startTime && this.endTime) {
239240
this.timeoutId = window.setTimeout(() => this.$emit(Timer.Events.END, this.endTime),
240241
this.endTime - this.sampledTime);
241-
this._setupUpdateInterval();
242-
}
243-
}
244-
245-
@Watch('_updateInterval')
246-
private _setupUpdateInterval() {
247-
if (this._timeLeft === 0 || this.requestAnimationFrameId !== null) return;
248-
249-
clearInterval(this.updateIntervalId);
250-
this.updateIntervalId = window.setInterval(() => {
251-
this._rerender();
252-
if (this._timeLeft !== 0) return;
253-
clearInterval(this.updateIntervalId);
254-
}, this._updateInterval);
255-
}
256-
257-
private _animateRadius() {
258-
if (this.requestAnimationFrameId !== null || this.radius.finished) return;
259-
clearInterval(this.updateIntervalId); // stop interval while we render via requestAnimationFrame
260-
this.requestAnimationFrameId = requestAnimationFrame(() => {
261242
this._rerender();
262-
this.requestAnimationFrameId = null;
263-
if (this.radius.finished) {
264-
this._setupUpdateInterval(); // start update interval again
265-
} else {
266-
this._animateRadius();
267-
}
268-
});
243+
}
269244
}
270245
271246
private _rerender() {
272247
this.sampledTime = Date.now() + this.timeOffset;
273248
this.fullCircleLength = 2 * Math.PI * this.radius.currentValue;
249+
250+
if (this._timeLeft === 0 && this.radius.finished) return;
251+
252+
clearTimeout(this.updateTimeoutId);
253+
cancelAnimationFrame(this.requestAnimationFrameId);
254+
255+
if (!this.radius.finished) {
256+
// animate radius with high frame rate
257+
this.requestAnimationFrameId = requestAnimationFrame(() => this._rerender());
258+
} else {
259+
// update with low frame rate
260+
this.updateTimeoutId = window.setTimeout(() => this._rerender(), this._calculateUpdateInterval());
261+
}
274262
}
275263
276264
private _onResize() {

0 commit comments

Comments
 (0)