UNPKG

@stimulus-library/controllers

Version:

A library of useful controllers for Stimulus

79 lines (78 loc) 2.54 kB
import { BaseController, EasingFunctions } from "@stimulus-library/utilities"; import { useIntersection } from "@stimulus-library/mixins"; export class TweenNumberController extends BaseController { get start() { if (this.hasStartValue) { return this.startValue; } else { throw new Error("Required value `start` is missing"); } } get end() { if (this.hasEndValue) { return this.endValue; } else { throw new Error("Required value `end` is missing"); } } get durationMs() { if (this.hasDurationValue) { return this.durationValue; } else { throw new Error("Required value `duration` is missing"); } } get easingFunction() { const str = this.hasEasingValue ? this.easingValue : null; const fallback = EasingFunctions.linear; if (str == null) { return fallback; } return EasingFunctions[str] || fallback; } connect() { const { observer, observe, unobserve, teardown, } = useIntersection(this, this.el, this.appear); this.observer = observer; this.observe = observe; this.unobserve = unobserve; this.teardownObserver = teardown; this.formatter = new Intl.NumberFormat(Intl.NumberFormat().resolvedOptions().locale, this.formattingValue); } appear(_entry) { this.tween(); } tween() { let startTimestamp = null; const self = this; const step = (timestamp) => { var _a, _b; if (!startTimestamp) { startTimestamp = timestamp; } const elapsed = timestamp - startTimestamp; const progress = Math.min(elapsed / this.durationMs, 1); this.element.innerHTML = this.formatter.format(Math.floor(this.easingFunction(progress) * (this.end - this.start) + this.start)); if (progress < 1) { requestAnimationFrame(step); } else { (_a = self.unobserve) === null || _a === void 0 ? void 0 : _a.call(self); (_b = self.teardownObserver) === null || _b === void 0 ? void 0 : _b.call(self); } }; requestAnimationFrame(step); } } TweenNumberController.values = { start: Number, end: Number, duration: Number, easing: String, formatting: { type: Object, default: {}, }, };