UNPKG

additween

Version:

Additive tweening library for smooth animations

1 lines 10.9 kB
{"version":3,"file":"additween.mjs","sources":["../src/PlainObjectReducer.ts","../node_modules/@babel/runtime/helpers/esm/createClass.js","../node_modules/@babel/runtime/helpers/esm/defineProperty.js","../src/AdditiveTweening.ts","../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","../src/getCurrentTime.ts"],"sourcesContent":["export interface IStateReducer<T extends Record<string, number>> {\n clone: (state: T) => T;\n reduce: (targetState: T, toState: T, fromState: T, pos: number) => T;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport const PlainObjectReducer: IStateReducer<any> = {\n clone: function (obj) {\n const target: Record<string, number> = {};\n for (const key in obj) {\n target[key] = obj[key];\n }\n return target;\n },\n\n reduce: function (targetState, toState, fromState, pos) {\n for (const key in targetState) {\n targetState[key] -= (toState[key] - fromState[key]) * pos;\n }\n return targetState;\n },\n};\n","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n return Constructor;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import { getCurrentTime } from \"./getCurrentTime\";\nimport { PlainObjectReducer } from \"./PlainObjectReducer\";\nimport type { IStateReducer } from \"./PlainObjectReducer\";\n\nfunction noop() {}\n\nfunction identity(t: number): number {\n return t;\n}\n\nexport type EasingFunction = (t: number) => number;\n\ntype TAnimationStackEntry<T> = {\n duration: number;\n end: number;\n fromState: T;\n toState: T;\n easing: EasingFunction;\n};\n\nexport type TAdditiveTweeningOptions<T extends Record<string, number>> = {\n onRender: (state: T) => void;\n onFinish?: (finalState: T) => void;\n onCancel?: () => void;\n stateReducer?: IStateReducer<T>;\n};\n\nexport class AdditiveTweening<T extends Record<string, number>> {\n tween: (\n fromState: T,\n toState: T,\n duration: number,\n easing?: EasingFunction\n ) => void;\n\n isTweening: () => boolean;\n\n finish: () => void;\n\n cancel: () => void;\n\n constructor(options: TAdditiveTweeningOptions<T>) {\n let frame = 0,\n lastTargetState: T | null = null,\n currentState = null,\n animationStack: Array<TAnimationStackEntry<T>> = [];\n\n const onRender = options.onRender || noop;\n const stateReducer: IStateReducer<T> =\n options.stateReducer || PlainObjectReducer;\n const onFinish = options.onFinish || noop;\n const onCancel = options.onCancel || noop;\n\n function filterOutdatedTargetsFromStack(time: number) {\n const filteredStack = [];\n for (let i = animationStack.length - 1; i >= 0; i--) {\n if (animationStack[i].end > time) {\n filteredStack.push(animationStack[i]);\n }\n }\n\n animationStack = filteredStack;\n }\n\n function getCurrentState(time: number) {\n let animation, remain;\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let target = stateReducer.clone(lastTargetState!);\n\n for (let i = animationStack.length - 1; i >= 0; i--) {\n animation = animationStack[i];\n if (animation.end < time) {\n continue;\n }\n remain = (animation.end - time) / animation.duration;\n target = stateReducer.reduce(\n target,\n animation.toState,\n animation.fromState,\n animation.easing(remain)\n );\n }\n\n return target;\n }\n\n function hasActiveAnimation(time: number): boolean {\n for (let i = animationStack.length - 1; i >= 0; i--) {\n const animation = animationStack[i];\n if (animation.end >= time) {\n return true;\n }\n }\n return false;\n }\n\n const animationStep = () => {\n if (lastTargetState === null) {\n return;\n }\n\n const time = this.now();\n\n currentState = getCurrentState(time);\n\n onRender(currentState);\n\n if (hasActiveAnimation(time)) {\n frame = this.scheduleAnimationFrame(animationStep);\n } else {\n this.finish();\n }\n };\n\n /**\n * Returns true if any tweening is in process\n * @returns {boolean}\n */\n this.isTweening = function () {\n return !!lastTargetState;\n };\n\n /**\n * Immediately sets tweening to its final state.\n */\n this.finish = function () {\n if (lastTargetState !== null) {\n onFinish(lastTargetState);\n\n lastTargetState = null;\n currentState = null;\n }\n };\n\n /**\n * Cancels all active tweening processes\n */\n this.cancel = function () {\n if (lastTargetState !== null) {\n if (window.cancelAnimationFrame) {\n window.cancelAnimationFrame(frame);\n frame = 0;\n }\n onCancel();\n\n lastTargetState = null;\n currentState = null;\n }\n };\n\n /**\n * Starts new tweening process\n * @param fromState\n * @param toState\n * @param {Number} duration Duration in ms\n * @param {Function} easing An easing function. It should take a number from [0,1] range and return a number from [0,1] range.\n */\n this.tween = function (fromState, toState, duration, easing) {\n const time = this.now();\n\n const animation = {\n duration: duration,\n end: time + duration,\n fromState:\n lastTargetState === null ? fromState : lastTargetState,\n toState: toState,\n easing: easing || identity,\n };\n\n filterOutdatedTargetsFromStack(time);\n\n animationStack.push(animation);\n\n lastTargetState = toState;\n\n frame = this.scheduleAnimationFrame(animationStep);\n };\n }\n\n scheduleAnimationFrame(cb: () => void): number {\n return window.requestAnimationFrame(cb);\n }\n\n now(): number {\n return getCurrentTime();\n }\n}\n","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","export function getCurrentTime(): number {\n if (window.performance && window.performance.now) {\n return window.performance.now();\n }\n\n if (Date.now) {\n return Date.now();\n }\n\n return new Date().getTime();\n}\n"],"names":["PlainObjectReducer","clone","obj","target","key","reduce","targetState","toState","fromState","pos","_defineProperties","props","i","length","descriptor","enumerable","configurable","writable","Object","defineProperty","_defineProperty","value","noop","identity","t","AdditiveTweening","options","instance","Constructor","TypeError","frame","lastTargetState","currentState","animationStack","onRender","stateReducer","onFinish","onCancel","animationStep","time","_this","now","animation","remain","end","duration","easing","getCurrentState","hasActiveAnimation","finish","scheduleAnimationFrame","isTweening","cancel","window","cancelAnimationFrame","tween","this","filteredStack","push","filterOutdatedTargetsFromStack","protoProps","staticProps","cb","requestAnimationFrame","performance","Date","getTime","prototype"],"mappings":"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"}