UNPKG

vevet

Version:

Vevet is a JavaScript library for creative development that simplifies crafting rich interactions like split text animations, carousels, marquees, preloading, and more.

198 lines 6.14 kB
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; import { Module } from '../../base/Module'; import { isFiniteNumber } from '../../internal/isFiniteNumber'; import { isUndefined } from '../../internal/isUndefined'; import { noopIfDestroyed } from '../../internal/noopIfDestroyed'; import { clamp, easing } from '../../utils/math'; import { MUTABLE_PROPS, STATIC_PROPS } from './props'; export * from './types'; /** * A timeline class for managing animations with easing and precise progress control. * It provides methods for playing, reversing, pausing, and resetting the timeline. * * [Documentation](https://vevetjs.com/docs/Timeline) * * @group Components */ export class Timeline extends Module { /** Get default static properties. */ _getStatic() { return Object.assign(Object.assign({}, super._getStatic()), STATIC_PROPS); } /** Get default mutable properties. */ _getMutable() { return Object.assign(Object.assign({}, super._getMutable()), MUTABLE_PROPS); } constructor(props, onCallbacks) { super(props, onCallbacks); // Initialize default values this._progress = 0; this._eased = 0; this._raf = undefined; this._time = 0; this._isReversed = false; this._isPaused = false; } /** * Get or set the linear progress of the timeline. * Setting this triggers an update and associated callbacks. */ get progress() { return this._progress; } set progress(val) { this._progress = clamp(val); this._onUpdate(); } /** * Get the eased progress of the timeline, derived from the easing function. */ get eased() { return this._eased; } /** * Whether the timeline is currently playing. */ get isPlaying() { return !isUndefined(this._raf); } /** * Whether the timeline is reversed (progress decreases over time). */ get isReversed() { return this._isReversed; } /** * Whether the timeline is paused. */ get isPaused() { return this._isPaused; } /** * Get the timeline duration, ensuring it is at least 0 ms. */ get duration() { const source = this.props.duration; if (!isFiniteNumber(source) || source < 0) { return 0; } return this.props.duration; } /** * Play the timeline, advancing progress toward completion. * Does nothing if the timeline is destroyed or already completed. */ play() { if (this.progress === 1) { return; } this._isReversed = false; this._isPaused = false; if (!this.isPlaying) { this._time = Date.now(); this._animate(); } } /** * Reverse the timeline, moving progress toward the start. * Does nothing if the timeline is destroyed or already at the start. */ reverse() { if (this.progress === 0) { return; } this._isReversed = true; this._isPaused = false; if (!this.isPlaying) { this._time = Date.now(); this._animate(); } } /** * Pause the timeline, halting progress without resetting it. */ pause() { this._isPaused = true; if (this._raf) { window.cancelAnimationFrame(this._raf); } this._raf = undefined; } /** * Reset the timeline to the beginning (progress = 0). */ reset() { this.pause(); this.progress = 0; } /** * Animate the timeline, updating progress based on elapsed time. */ _animate() { if (this.isPaused) { return; } const { isReversed, duration } = this; if (duration <= 0) { this.progress = isReversed ? 1 : 0; this.progress = isReversed ? 0 : 1; return; } const currentTime = Date.now(); const frameDiff = Math.abs(this._time - currentTime); this._time = currentTime; const progressIterator = frameDiff / duration / (isReversed ? -1 : 1); const progressTarget = this.progress + progressIterator; this.progress = progressTarget; if ((this.progress === 1 && !isReversed) || (this.progress === 0 && isReversed)) { this._isReversed = false; this._isPaused = false; this._raf = undefined; return; } this._raf = window.requestAnimationFrame(() => this._animate()); } /** * Handle progress updates and trigger callbacks. */ _onUpdate() { this._eased = easing(this._progress, this.props.easing); this.callbacks.emit('update', { progress: this._progress, eased: this._eased, }); if (this.progress === 0) { this.callbacks.emit('start', undefined); return; } if (this.progress === 1) { this.callbacks.emit('end', undefined); } } /** * Destroy the timeline, stopping any active animation and cleaning up resources. */ _destroy() { this.pause(); super._destroy(); } } __decorate([ noopIfDestroyed ], Timeline.prototype, "play", null); __decorate([ noopIfDestroyed ], Timeline.prototype, "reverse", null); __decorate([ noopIfDestroyed ], Timeline.prototype, "pause", null); __decorate([ noopIfDestroyed ], Timeline.prototype, "reset", null); //# sourceMappingURL=index.js.map