@mui/x-charts
Version:
The community edition of MUI X Charts components.
83 lines (77 loc) • 2.22 kB
JavaScript
import { timer, now, timeout, timerFlush } from '@mui/x-charts-vendor/d3-timer';
/**
* A resumable transition class inspired by d3-transition.
* Allows for starting, and stopping and resuming transitions.
*
* The transition is started automatically.
* A transition cannot be restarted after it has finished.
* Resuming a transition will continue from the point it was stopped, i.e., easing will continue from the point it was
* stopped.
*/
export class Transition {
/**
* Create a new ResumableTransition.
* @param duration Duration in milliseconds
* @param easingFn The easing function
* @param onTick Callback function called on each animation frame with the eased time in range [0, 1].
*/
constructor(duration, easingFn, onTick) {
this.duration = void 0;
this.elapsed = 0;
this.easingFn = void 0;
this.timer = null;
this.onTickCallback = void 0;
this.duration = duration;
this.easingFn = easingFn;
this.onTickCallback = onTick;
this.resume();
}
get running() {
return this.timer !== null;
}
timerCallback(elapsed) {
this.elapsed = Math.min(elapsed, this.duration);
const t = this.duration === 0 ? 1 : this.elapsed / this.duration;
const easedT = this.easingFn(t);
// Call the tick callback with the current value
this.onTickCallback(easedT);
if (this.elapsed >= this.duration) {
this.stop();
}
}
/**
* Resume the transition
*/
resume() {
if (this.running || this.elapsed >= this.duration) {
return this;
}
/* If we're resuming the transition, then subtract elapsed to continue the easing. */
const time = now() - this.elapsed;
this.timer = timer(elapsed => this.timerCallback(elapsed), 0, time);
timerFlush();
return this;
}
/**
* Stops the transition.
*/
stop() {
if (!this.running) {
return this;
}
if (this.timer) {
this.timer.stop();
this.timer = null;
}
return this;
}
/**
* Immediately finishes the transition and calls the tick callback with the final value.
*/
finish() {
this.stop();
timeout(() => this.timerCallback(this.duration));
timerFlush();
return this;
}
}