UNPKG

motion

Version:

The Motion library for the web

132 lines (127 loc) 4.44 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var defaults = require('../dom/utils/defaults.cjs.js'); var easing = require('../dom/utils/easing.cjs.js'); var getFunction = require('./easing/get-function.cjs.js'); var interpolate = require('./utils/interpolate.cjs.js'); class Animation { constructor(output, keyframes, // TODO Merge in defaults { easing: easing$1 = defaults.defaults.easing, duration = defaults.defaults.duration, delay = defaults.defaults.delay, endDelay = defaults.defaults.endDelay, offset, repeat = defaults.defaults.repeat, direction = "normal", }) { this.startTime = 0; this.rate = 1; this.t = 0; this.cancelT = 0; this.playState = "idle"; this.finished = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject; }); const totalDuration = duration * (repeat + 1); const interpolate$1 = interpolate.slowInterpolateNumbers(keyframes, offset, easing.isEasingList(easing$1) ? easing$1.map(getFunction.getEasingFunction) : getFunction.getEasingFunction(easing$1)); this.tick = (timestamp) => { if (this.playState === "finished") { const latest = interpolate$1(1); output(latest); this.resolve(latest); return; } if (this.pauseTime) { timestamp = this.pauseTime; } let t = (timestamp - this.startTime) * this.rate; this.t = t; // Convert to seconds t /= 1000; // Rebase on delay t = Math.max(t - delay, 0); const progress = t / duration; // TODO progress += iterationStart let currentIteration = Math.floor(progress); let iterationProgress = progress % 1.0; if (!iterationProgress && progress >= 1) { iterationProgress = 1; } if (iterationProgress === 1) { currentIteration--; } // Reverse progress const iterationIsOdd = currentIteration % 2; if (direction === "reverse" || (direction === "alternate" && iterationIsOdd) || (direction === "alternate-reverse" && !iterationIsOdd)) { iterationProgress = 1 - iterationProgress; } const interpolationIsFinished = t >= totalDuration; const interpolationProgress = interpolationIsFinished ? 1 : Math.min(iterationProgress, 1); const latest = interpolate$1(interpolationProgress); output(latest); const isFinished = t >= totalDuration + endDelay; if (isFinished) { this.playState = "finished"; this.resolve(latest); } else if (this.playState !== "idle") { requestAnimationFrame(this.tick); } }; this.play(); } play() { const now = performance.now(); this.playState = "running"; if (this.pauseTime) { this.startTime = now - (this.pauseTime - this.startTime); } else if (!this.startTime) { this.startTime = now; } this.pauseTime = undefined; requestAnimationFrame(this.tick); } pause() { this.playState = "paused"; this.pauseTime = performance.now(); } finish() { this.playState = "finished"; this.tick(0); } cancel() { this.playState = "idle"; this.tick(this.cancelT); this.reject(false); } reverse() { this.rate *= -1; } commitStyles() { this.cancelT = this.t; } get currentTime() { return this.t; } set currentTime(t) { if (this.pauseTime || this.rate === 0) { this.pauseTime = t; } else { this.startTime = performance.now() - t / this.rate; } } get playbackRate() { return this.rate; } set playbackRate(rate) { this.rate = rate; } } function animateNumber(output, keyframes = [0, 1], options = {}) { return new Animation(output, keyframes, options); } exports.Animation = Animation; exports.animateNumber = animateNumber;