@wbe/interpol
Version:
Interpolates values with a GSAP-like API ~ 3kB
1 lines • 55.3 kB
Source Map (JSON)
{"version":3,"sources":["../src/index.ts","../src/utils/deferredPromise.ts","../src/utils/clamp.ts","../src/utils/round.ts","../src/utils/compute.ts","../src/utils/noop.ts","../src/core/ease.ts","../src/utils/env.ts","../src/core/Ticker.ts","../src/core/options.ts","../src/core/Interpol.ts","../src/core/Timeline.ts","../src/core/styles.ts"],"sourcesContent":["// Types\nexport type { InterpolConstruct, Props, TimelineConstruct, Value } from \"./core/types\"\nexport type { Ease, EaseFn, EaseName, EaseType, EaseDirection, Power } from \"./core/ease\"\nexport type { IAdd } from \"./core/Timeline\"\n\n// Core\nexport { Interpol } from \"./core/Interpol\"\nexport { Timeline } from \"./core/Timeline\"\nexport { Ticker } from \"./core/Ticker\"\nexport { InterpolOptions } from \"./core/options\"\n\n// Aditional core utils\nexport { Power1, Power2, Power3, Power4, Expo, easeAdapter } from \"./core/ease\"\nexport { styles } from \"./core/styles\"\n","export type TDeferredPromise<T = any> = {\n promise: Promise<T>\n resolve: (resolve?: T) => void\n}\n\n/**\n * @name deferredPromise\n * @return TDeferredPromise\n */\nexport function deferredPromise<T>(): TDeferredPromise<T> {\n const deferred: TDeferredPromise<T> | any = {}\n deferred.promise = new Promise((resolve) => {\n deferred.resolve = resolve\n })\n return deferred\n}\n","export function clamp(min: number, value: number, max: number): number {\n return Math.max(min, Math.min(value, max))\n}\n","export const round = (v: number, decimal = 1000): number =>\n Math.round(v * decimal) / decimal\n","export const compute = (p) => (typeof p === \"function\" ? p() : p)\n","export const noop = () => {}\n","// Power1: Quad\nexport const Power1: Power = {\n in: (t) => t * t,\n out: (t) => t * (2 - t),\n inOut: (t) => (t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t),\n}\n\n// Power2: Cubic\nexport const Power2: Power = {\n in: (t) => t * t * t,\n out: (t) => 1 - Math.pow(1 - t, 3),\n inOut: (t) => (t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2),\n}\n\n// Power3: Quart\nexport const Power3: Power = {\n in: (t) => t * t * t * t,\n out: (t) => 1 - Math.pow(1 - t, 4),\n inOut: (t) => (t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2),\n}\n\n// Power4: Quint\nexport const Power4: Power = {\n in: (t) => t * t * t * t * t,\n out: (t) => 1 - Math.pow(1 - t, 5),\n inOut: (t) => (t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2),\n}\n\n// Expo\nexport const Expo: Power = {\n in: (t) => (t === 0 ? 0 : Math.pow(2, 10 * (t - 1))),\n out: (t) => (t === 1 ? 1 : -Math.pow(2, -10 * t) + 1),\n inOut: (t) => {\n if (t === 0) return 0\n if (t === 1) return 1\n if ((t /= 0.5) < 1) return 0.5 * Math.pow(2, 10 * (t - 1))\n return 0.5 * (-Math.pow(2, -10 * --t) + 2)\n },\n}\n\nexport const Linear: EaseFn = (t) => t\n\n/**\n * Adaptor for gsap ease functions as string\n */\nexport type EaseType = \"power1\" | \"power2\" | \"power3\" | \"power4\" | \"expo\"\nexport type EaseDirection = \"in\" | \"out\" | \"inOut\"\nexport type EaseName = `${EaseType}.${EaseDirection}` | \"linear\" | \"none\"\nexport type EaseFn = (t: number) => number\nexport type Ease = EaseName | EaseFn\nexport type Power = Record<string, EaseFn>\n\nexport const easeAdapter = (ease: EaseName): EaseFn => {\n let [type, direction] = ease.split(\".\") as [EaseType, EaseDirection]\n if (type[0] === type[0].toLowerCase()) {\n type = (type[0].toUpperCase() + type.slice(1)) as EaseType\n }\n const e = { Linear, Power1, Power2, Power3, Power4, Expo }\n return e?.[type]?.[direction] ?? Linear\n}\n","export const isClient = () => typeof window < \"u\"\n","import { isClient } from \"../utils/env\"\n\ntype TickParams = {\n delta: number\n time: number\n elapsed: number\n}\n\ntype Handler = (e: TickParams) => void\n\n/**\n * Ticker\n */\nexport class Ticker {\n #isRunning = false\n #handlers: { handler: Handler; rank: number }[]\n #onUpdateObj: TickParams\n #start: number\n #time: number\n #elapsed: number\n #keepElapsed: number\n #delta: number\n #rafId: number\n #isClient: boolean\n #enable: boolean\n\n constructor() {\n this.#handlers = []\n this.#onUpdateObj = { delta: null, time: null, elapsed: null }\n this.#keepElapsed = 0\n this.#enable = true\n this.#isClient = isClient()\n this.#initEvents()\n // wait a frame in case disableRaf is set to true\n setTimeout(() => this.play(), 0)\n }\n\n public disable(): void {\n this.#enable = false\n }\n\n public add(handler: Handler, rank: number = 0): () => void {\n this.#handlers.push({ handler, rank })\n this.#handlers.sort((a, b) => a.rank - b.rank)\n return () => this.remove(handler)\n }\n\n public remove(handler: Handler): void {\n this.#handlers = this.#handlers.filter((obj) => obj.handler !== handler)\n }\n\n public play(): void {\n this.#isRunning = true\n this.#start = performance.now()\n this.#time = this.#start\n this.#elapsed = this.#keepElapsed + (this.#time - this.#start)\n this.#delta = 16\n if (this.#enable && this.#isClient) {\n this.#rafId = requestAnimationFrame(this.#update)\n }\n }\n\n public pause(): void {\n this.#isRunning = false\n this.#keepElapsed = this.#elapsed\n }\n\n public stop(): void {\n this.#isRunning = false\n this.#keepElapsed = 0\n this.#elapsed = 0\n this.#removeEvents()\n if (this.#enable && this.#isClient && this.#rafId) {\n cancelAnimationFrame(this.#rafId)\n this.#rafId = null\n }\n }\n\n public raf(t: number): void {\n this.#delta = t - (this.#time || t)\n this.#time = t\n this.#elapsed = this.#keepElapsed + (this.#time - this.#start)\n this.#onUpdateObj.delta = this.#delta\n this.#onUpdateObj.time = this.#time\n this.#onUpdateObj.elapsed = this.#elapsed\n for (const { handler } of this.#handlers) handler(this.#onUpdateObj)\n }\n\n #initEvents(): void {\n if (this.#isClient) {\n document.addEventListener(\"visibilitychange\", this.#handleVisibility)\n }\n }\n\n #removeEvents(): void {\n if (this.#isClient) {\n document.removeEventListener(\"visibilitychange\", this.#handleVisibility)\n }\n }\n\n #handleVisibility = (): void => {\n document.hidden ? this.pause() : this.play()\n }\n\n #update = (t = performance.now()): void => {\n if (!this.#isRunning) return\n if (this.#enable && this.#isClient) {\n this.#rafId = requestAnimationFrame(this.#update)\n }\n this.raf(t)\n }\n}\n","import { Ticker } from \"./Ticker\"\nimport { Value } from \"./types\"\nimport { Ease } from \"./ease\"\n\n/**\n * global options in window object\n */\ninterface InterpolOptions {\n ticker: Ticker\n durationFactor: number\n duration: Value\n ease: Ease\n}\n\nexport const InterpolOptions: InterpolOptions = {\n ticker: new Ticker(),\n durationFactor: 1,\n duration: 1000,\n ease: \"linear\",\n}\n","import {\n FormattedProp,\n CallBack,\n InterpolConstruct,\n Props,\n Value,\n CallbackProps,\n InterpolConstructBase,\n} from \"./types\"\nimport { deferredPromise } from \"../utils/deferredPromise\"\nimport { clamp } from \"../utils/clamp\"\nimport { round } from \"../utils/round\"\nimport { compute } from \"../utils/compute\"\nimport { noop } from \"../utils/noop\"\nimport { Ease, easeAdapter, EaseFn, EaseName } from \"./ease\"\nimport { Ticker } from \"./Ticker\"\nimport { InterpolOptions } from \"./options\"\nlet ID = 0\n\nexport class Interpol<K extends string = string> {\n public readonly ID = ++ID\n public ticker: Ticker\n public inTl = false\n public debugEnable: boolean\n\n #_duration: number\n public get duration() {\n return this.#_duration\n }\n #_delay: number\n public get delay() {\n return this.#_delay\n }\n #_ease: EaseFn\n public get ease() {\n return this.#_ease\n }\n #_reverseEase: EaseFn\n public get reverseEase() {\n return this.#_reverseEase\n }\n #time = 0\n public get time() {\n return this.#time\n }\n #lastProgress = 0\n #progress = 0\n #isReversed = false\n public get isReversed() {\n return this.#isReversed\n }\n #isPlaying = false\n public get isPlaying() {\n return this.#isPlaying\n }\n #isPaused = false\n public get isPaused() {\n return this.#isPaused\n }\n #props: Record<K, FormattedProp>\n public get props() {\n return this.#props\n }\n\n meta: Record<string, any>\n #duration: Value\n #delay: Value\n #callbackProps: CallbackProps<K>\n #immediateRender: boolean\n #ease: Value<Ease>\n #reverseEase: Value<Ease>\n #originalProps: Omit<InterpolConstruct<K>, keyof InterpolConstructBase<K>>\n #beforeStart: CallBack<K>\n #onStart: CallBack<K>\n #onUpdate: CallBack<K>\n #onComplete: CallBack<K>\n #timeout: ReturnType<typeof setTimeout>\n #onCompleteDeferred = deferredPromise()\n #hasProgressOnStart = false\n #hasProgressCompleted = false\n\n constructor({\n duration = InterpolOptions.duration,\n ease = InterpolOptions.ease,\n reverseEase = ease,\n paused = false,\n delay = 0,\n immediateRender = false,\n beforeStart = noop,\n onStart = noop,\n onUpdate = noop,\n onComplete = noop,\n debug = false,\n meta = {},\n ...inlineProps\n }: InterpolConstruct<K>) {\n this.ticker = InterpolOptions.ticker\n this.#duration = duration\n this.#isPaused = paused\n this.#delay = delay\n this.#immediateRender = immediateRender\n this.#beforeStart = beforeStart\n this.#onStart = onStart\n this.#onUpdate = onUpdate\n this.#onComplete = onComplete\n this.debugEnable = debug\n this.#ease = ease\n this.#reverseEase = reverseEase\n this.meta = meta\n\n // Prepare & compute props\n this.#originalProps = inlineProps\n // Compute all values (duration, delay, ease, props values)\n this.refresh()\n // Create callback props object\n this.#callbackProps = this.#createPropsParamObjRef<K>(this.#props)\n // Initial callbacks\n this.#beforeStart(this.#callbackProps, this.#time, this.#progress, this)\n if (this.#immediateRender) {\n this.#onUpdate(this.#callbackProps, this.#time, this.#progress, this)\n }\n if (!this.#isPaused) this.play()\n }\n\n // Compute if values were functions\n public refresh(): void {\n // re preprare all props\n this.#props = this.#prepareProps<K>(this.#originalProps)\n\n // compute global options\n this.#_duration = compute(this.#duration) * InterpolOptions.durationFactor\n this.#_delay = compute(this.#delay) * InterpolOptions.durationFactor\n this.#_ease = this.#chooseEase(this.#ease)\n this.#_reverseEase = this.#chooseEase(this.#reverseEase)\n\n // compute each internal prop properties\n for (const key of Object.keys(this.#props)) {\n const prop = this.#props[key]\n prop._from = compute(prop.from)\n prop._to = compute(prop.to)\n prop.ease = prop._computeEaseFn(this.#_ease)\n prop.reverseEase = prop._computeReverseEaseFn(this.#_reverseEase)\n }\n }\n\n /**\n * @deprecated use refresh() instead\n */\n public refreshComputedValues(): void {\n console.warn(`Interpol.refreshComputedValues() is deprecated. Use Interpol.refresh() instead.`)\n this.refresh()\n }\n\n public async play(from: number = 0, allowReplay = true): Promise<any> {\n if (this.#isPlaying && !allowReplay) return\n if (this.#isPlaying && this.#isReversed) {\n this.#isReversed = false\n return\n }\n if (this.#isPlaying) {\n this.stop()\n return await this.play(from)\n }\n\n this.#onEachProps((prop) => (prop.value = prop._to * from))\n this.#time = this.#_duration * from\n this.#progress = from\n this.#isReversed = false\n this.#isPlaying = true\n this.#isPaused = false\n const fromStart = this.#progress === 0\n\n // before onStart, check if we start from 0 or not\n // on the first case, force reset callbackProps\n // else, assign the value to callbackProps\n this.#callbackProps = fromStart\n ? this.#createPropsParamObjRef<K>(this.#props)\n : this.#assignPropsValue<K>(this.#callbackProps, this.#props)\n\n // Delay is set only on first play\n // If this play is trigger before onComplete, we don't wait again\n // start ticker only if is single Interpol, not TL\n this.#timeout = setTimeout(\n () => {\n if (fromStart) this.#onStart(this.#callbackProps, this.#time, this.#progress, this)\n this.ticker.add(this.#handleTick)\n },\n this.#time > 0 ? 0 : this.#_delay,\n )\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n\n public async reverse(from: number = 1, allowReplay = true): Promise<any> {\n if (this.#isPlaying && !allowReplay) return\n // If is playing normal direction, change to reverse and return a new promise\n if (this.#isPlaying && !this.#isReversed) {\n this.#isReversed = true\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n // If is playing reverse, restart reverse\n if (this.#isPlaying && this.#isReversed) {\n this.stop()\n return await this.reverse(from)\n }\n\n this.#onEachProps((p) => (p.value = p._to * from))\n this.#time = this.#_duration * from\n this.#progress = from\n this.#isReversed = true\n this.#isPlaying = true\n this.#isPaused = false\n\n // start ticker only if is single Interpol, not TL\n this.ticker.add(this.#handleTick)\n // create new onComplete deferred Promise and return it\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n\n public pause(): void {\n this.#isPaused = true\n this.#isPlaying = false\n if (!this.inTl) {\n this.ticker.remove(this.#handleTick)\n }\n }\n\n public resume(): void {\n if (!this.#isPaused) return\n this.#isPaused = false\n this.#isPlaying = true\n if (!this.inTl) {\n this.ticker.add(this.#handleTick)\n }\n }\n\n public stop(): void {\n if (!this.inTl || (this.inTl && this.#isReversed)) {\n this.#onEachProps((prop) => (prop.value = prop._from))\n this.#time = 0\n this.#lastProgress = this.#progress\n this.#progress = 0\n }\n\n this.#isPlaying = false\n this.#isPaused = false\n clearTimeout(this.#timeout)\n\n if (!this.inTl) {\n this.#isReversed = false\n this.ticker.remove(this.#handleTick)\n }\n }\n\n /**\n * Set progress to a specific value (between 0 and 1)\n */\n public progress(value?: number, suppressEvents = true): number | void {\n if (value === undefined) {\n return this.#progress\n }\n if (this.#isPlaying) this.pause()\n\n // keep previous progress before update it\n this.#lastProgress = this.#progress\n this.#progress = clamp(0, value, 1)\n\n // if this is the first progress in range (between 0 & 1), refresh computed values\n if (\n (this.#progress !== 0 && this.#lastProgress === 0) ||\n (this.#progress !== 1 && this.#lastProgress === 1)\n ) {\n this.refresh()\n }\n\n // Update time, interpolate and assign props value\n this.#time = clamp(0, this.#_duration * this.#progress, this.#_duration)\n this.#interpolate(this.#progress)\n this.#callbackProps = this.#assignPropsValue<K>(this.#callbackProps, this.#props)\n\n // if last & current progress are differents,\n // Or if progress param is the same this.progress, execute onUpdate\n if (this.#lastProgress !== this.#progress || value === this.#progress) {\n if (this.#lastProgress !== this.#progress) {\n this.#hasProgressOnStart = false\n this.#hasProgressCompleted = false\n }\n this.#onUpdate(this.#callbackProps, this.#time, this.#progress, this)\n this.#log(`progress onUpdate`, {\n props: this.#callbackProps,\n time: this.#time,\n progress: this.#progress,\n })\n }\n\n // onStart\n // - if we go from 0 to 1 and never play\n // - if it hasn't been called before\n // need to reset callbackProps\n if (\n // prettier-ignore\n (this.#lastProgress === 0 && this.#progress > 0) && \n !this.#hasProgressCompleted && \n !suppressEvents\n ) {\n this.#callbackProps = this.#createPropsParamObjRef<K>(this.#props)\n this.#onStart(this.#callbackProps, this.#time, this.#progress, this)\n this.#hasProgressOnStart = true\n this.#log(`progress onStart`, {\n props: this.#callbackProps,\n time: this.#time,\n progress: this.#progress,\n })\n }\n\n // onComplete\n // if progress 1, execute onComplete only if it hasn't been called before\n // Special case for duration 0: execute onComplete every time progress goes from < 1 to 1\n if (this.#progress === 1 && !suppressEvents) {\n const shouldExecute =\n this.#_duration <= 0\n ? // For duration 0, execute when transitioning from < 1 to 1\n this.#lastProgress < 1\n : // For normal duration, execute only once\n !this.#hasProgressCompleted\n\n if (shouldExecute) {\n this.#onComplete(this.#callbackProps, this.#time, this.#progress, this)\n this.#lastProgress = this.#progress\n this.#hasProgressCompleted = true\n this.#log(`progress onComplete`, {\n props: this.#callbackProps,\n time: this.#time,\n progress: this.#progress,\n })\n }\n }\n\n // if progress 0, reset completed flag and allow onComplete to be called again\n if (this.#progress === 0) {\n this.#lastProgress = this.#progress\n this.#hasProgressOnStart = false\n this.#hasProgressCompleted = false\n }\n }\n\n #handleTick = async ({ delta }): Promise<any> => {\n // Specific case if duration is 0, execute onComplete and return\n if (this.#_duration <= 0) {\n this.#onEachProps((p) => (p.value = p._to))\n const obj = {\n props: this.#assignPropsValue<K>(this.#callbackProps, this.#props),\n time: this.#_duration,\n progress: 1,\n }\n this.#onUpdate(obj.props, obj.time, obj.progress, this)\n this.#onComplete(obj.props, obj.time, obj.progress, this)\n this.#onCompleteDeferred.resolve()\n this.stop()\n return\n }\n\n // calc time (time spend from the start)\n // calc progress (between 0 and 1)\n // calc value (between \"from\" and \"to\")\n this.#time = clamp(0, this.#_duration, this.#time + (this.#isReversed ? -delta : delta))\n this.#progress = clamp(0, round(this.#time / this.#_duration), 1)\n this.#interpolate(this.#progress)\n this.#callbackProps = this.#assignPropsValue<K>(this.#callbackProps, this.#props)\n\n // Pass value, time and progress\n this.#onUpdate(this.#callbackProps, this.#time, this.#progress, this)\n this.#log(\"handleTick onUpdate\", {\n props: this.#callbackProps,\n t: this.#time,\n p: this.#progress,\n })\n\n // on play complete\n if (!this.#isReversed && this.#progress === 1) {\n this.#log(`handleTick onComplete!`)\n this.#onComplete(this.#callbackProps, this.#time, this.#progress, this)\n this.#onCompleteDeferred.resolve()\n this.stop()\n }\n // on reverse complete\n if (this.#isReversed && this.#progress === 0) {\n this.#onCompleteDeferred.resolve()\n this.stop()\n }\n }\n\n /**\n * Utility function to execute a callback on each props\n */\n #onEachProps(fn: (prop: FormattedProp) => void): void {\n for (const key of Object.keys(this.#props)) fn(this.#props[key])\n }\n\n /**\n * Mute each props value key\n */\n #interpolate(progress): void {\n // update prop.value\n this.#onEachProps((prop) => {\n const selectedEase = this.#isReversed && prop.reverseEase ? prop.reverseEase : prop.ease\n prop.value = round(prop._from + (prop._to - prop._from) * selectedEase(progress), 1000)\n })\n }\n\n /**\n * Prepare internal props object\n */\n #prepareProps<K extends keyof Props>(props): Record<K, FormattedProp> {\n return Object.keys(props).reduce(\n (acc, key: K) => {\n let p = props[key as K]\n acc[key as K] = {\n from: p?.[0] ?? p?.[\"from\"] ?? 0,\n _from: null,\n to: p?.[1] ?? p?.[\"to\"] ?? p ?? 0,\n _to: null,\n value: null,\n // will be exec by refresh and set _ease\n _computeEaseFn: (globalEase) => {\n const propEase = p?.[\"ease\"]\n return propEase ? this.#chooseEase(propEase) : globalEase\n },\n // will be exec by refresh and set _reverseEase\n _computeReverseEaseFn: (globalEase) => {\n const reverseEase = p?.[\"reverseEase\"]\n const propEase = p?.[\"ease\"]\n return reverseEase\n ? this.#chooseEase(reverseEase)\n : propEase\n ? this.#chooseEase(propEase)\n : globalEase\n },\n ease: null,\n reverseEase: null,\n }\n return acc\n },\n {} as Record<K, FormattedProp>,\n )\n }\n\n /**\n * Create an object with props keys\n * in order to keep the same reference on each frame\n */\n #createPropsParamObjRef<K extends keyof Props>(\n props: Record<K, FormattedProp>,\n ): CallbackProps<K> {\n return Object.keys(props).reduce((acc, key: K) => {\n acc[key as K] = props[key]._from\n return acc\n }, {} as any)\n }\n\n /**\n * Assign props value to propsValue object\n * in order to keep the same reference on each frame\n */\n #assignPropsValue<P extends K>(\n propsValue: CallbackProps<K>,\n props: Record<P, FormattedProp>,\n ): CallbackProps<P> {\n for (const key of Object.keys(propsValue)) {\n propsValue[key as P] = props[key].value\n }\n return propsValue\n }\n\n /**\n * Choose ease function\n * Can be a string or a function or a function that returns one of those\n * @param e ease name or function\n * @returns ease function\n */\n #chooseEase(e: Value<Ease>): EaseFn {\n if (e == null) return (t) => t\n // First, compute the value if it's a function that returns Ease\n const computedEase = compute(e)\n\n // if computed value is a string, return the corresponding ease function\n if (typeof computedEase === \"string\") {\n return easeAdapter(computedEase as EaseName) as EaseFn\n }\n // if initial \"e\" param is a function that returns a number (EaseFn)\n // deduce that it's an EaseFn, ex: ease = (t) => t * t\n else if (typeof (e as (t: number) => number)?.(0) === \"number\") {\n return e as EaseFn\n }\n // else return the computed result ex: () => (t) => t * t transformed as (t) => t * t\n else {\n return computedEase as EaseFn\n }\n }\n\n /**\n * Log util\n */\n #log(...rest: any[]): void {\n this.debugEnable && console.log(`%cinterpol`, `color: rgb(53,158,182)`, this.ID || \"\", ...rest)\n }\n}\n","import { Interpol } from \"./Interpol\"\nimport { InterpolConstruct, Props, TimelineConstruct } from \"./types\"\nimport { Ticker } from \"./Ticker\"\nimport { deferredPromise } from \"../utils/deferredPromise\"\nimport { clamp } from \"../utils/clamp\"\nimport { round } from \"../utils/round\"\nimport { noop } from \"../utils/noop\"\nimport { InterpolOptions } from \"./options\"\n\nexport interface IAdd {\n itp: Interpol\n time: { start: number; end: number; offset: number }\n progress: { start?: number; end?: number; current: number; last: number }\n _isAbsoluteOffset?: boolean\n}\n\nlet TL_ID = 0\n\nexport class Timeline {\n public readonly ID: number\n #progress = 0\n #time = 0\n public get time(): number {\n return this.#time\n }\n #isPlaying = false\n public get isPlaying(): boolean {\n return this.#isPlaying\n }\n #isReversed = false\n public get isReversed(): boolean {\n return this.#isReversed\n }\n #isPaused = false\n public get isPaused(): boolean {\n return this.#isPaused\n }\n #adds: IAdd[] = []\n public get adds(): IAdd[] {\n return this.#adds\n }\n #tlDuration: number = 0\n public get duration(): number {\n return this.#tlDuration\n }\n #ticker: Ticker\n public get ticker(): Ticker {\n return this.#ticker\n }\n\n #playFrom = 0\n #reverseFrom = 1\n #onCompleteDeferred = deferredPromise()\n #debugEnable: boolean\n #onUpdate: (time: number, progress: number) => void\n #onComplete: (time: number, progress: number) => void\n #lastTlProgress = 0\n #reverseLoop = false\n\n constructor({\n onUpdate = noop,\n onComplete = noop,\n debug = false,\n paused = false,\n }: TimelineConstruct = {}) {\n this.#onUpdate = onUpdate\n this.#onComplete = onComplete\n this.#debugEnable = debug\n this.#isPaused = paused\n this.ID = ++TL_ID\n this.#ticker = InterpolOptions.ticker\n // waiting for all adds register before log\n setTimeout(() => this.#log(\"adds\", this.#adds), 1)\n }\n\n /**\n * Add a new interpol obj or instance in Timeline or a callback function\n * @param interpol Interpol | InterpolConstruct<K> | (() => void),\n * @param offset Default \"0\" is relative position in TL\n */\n public add<K extends keyof Props>(\n interpol: Interpol | InterpolConstruct<K> | (() => void),\n offset: number | string = \"0\",\n ): Timeline {\n // Prepare the new Interpol instance\n // If interpol param is a callback function, we transform it to an Interpol instance\n if (typeof interpol === \"function\") {\n interpol = new Interpol({ duration: 0, onComplete: interpol })\n }\n const itp = interpol instanceof Interpol ? interpol : new Interpol<K>(interpol)\n itp.stop()\n itp.refresh()\n itp.ticker = this.#ticker\n itp.inTl = true\n if (this.#debugEnable) itp.debugEnable = this.#debugEnable\n\n let fOffset: number\n let startTime: number\n const factor: number = InterpolOptions.durationFactor\n\n // Relative position in TL\n if (typeof offset === \"string\") {\n fOffset = parseFloat(offset.includes(\"=\") ? offset.split(\"=\").join(\"\") : offset) * factor\n const relativeAdds = this.#adds.filter((add) => !add._isAbsoluteOffset)\n\n const prevAdd =\n relativeAdds?.length > 0\n ? // get previous relative add add with the biggest end time\n relativeAdds.reduce((a, b) => (b.time.end > a.time.end ? b : a))\n : // or get the previous (absolute)\n this.#adds?.[this.#adds.length - 1] || null\n\n this.#tlDuration = Math.max(this.#tlDuration, this.#tlDuration + itp.duration + fOffset)\n startTime = prevAdd ? prevAdd.time.end + fOffset : fOffset\n }\n // Absolute position in TL\n else if (typeof offset === \"number\") {\n fOffset = offset * factor\n this.#tlDuration = Math.max(0, this.#tlDuration, fOffset + itp.duration)\n startTime = fOffset ?? 0\n }\n\n // push new Add instance in local\n this.#adds.push({\n itp,\n time: {\n start: startTime,\n end: startTime + itp.duration,\n offset: fOffset,\n },\n progress: {\n start: null,\n end: null,\n current: 0,\n last: 0,\n },\n _isAbsoluteOffset: typeof offset === \"number\",\n })\n\n // Re Calc all progress start and end after each add register,\n // because we need to know the full TL duration for this calc\n this.#onAllAdds((currAdd, i) => {\n this.#adds[i].progress.start = currAdd.time.start / this.#tlDuration || 0\n this.#adds[i].progress.end = currAdd.time.end / this.#tlDuration || 0\n })\n\n // hack needed because we need to waiting all adds register if this is an autoplay\n if (!this.isPaused) setTimeout(() => this.play(), 0)\n\n // return the Timeline instance to chain methods\n return this\n }\n\n public async play(from: number = 0): Promise<any> {\n this.#playFrom = from\n if (this.#isPlaying && this.#isReversed) {\n this.#isReversed = false\n return this.#onCompleteDeferred.promise\n }\n if (this.#isPlaying) {\n this.#time = this.#tlDuration * from\n this.#progress = from\n this.#isReversed = false\n return this.#onCompleteDeferred.promise\n }\n this.#time = this.#tlDuration * from\n this.#progress = from\n this.#isReversed = false\n this.#isPlaying = true\n this.#isPaused = false\n this.#ticker.add(this.#handleTick)\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n\n public async reverse(from: number = 1): Promise<any> {\n this.#reverseFrom = from\n // If TL is playing in normal direction, change to reverse and return a new promise\n if (this.#isPlaying && !this.#isReversed) {\n this.#isReversed = true\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n // If is playing reverse, restart reverse\n if (this.#isPlaying && this.#isReversed) {\n this.stop()\n return await this.reverse(from)\n }\n\n this.#time = this.#tlDuration * from\n this.#progress = from\n this.#isReversed = true\n this.#isPlaying = true\n this.#isPaused = false\n\n this.#ticker.add(this.#handleTick)\n this.#onCompleteDeferred = deferredPromise()\n return this.#onCompleteDeferred.promise\n }\n\n public pause(): void {\n this.#isPlaying = false\n this.#isPaused = true\n this.#onAllAdds((e) => e.itp.pause())\n this.#ticker.remove(this.#handleTick)\n }\n\n public resume(): void {\n if (!this.#isPaused) return\n this.#isPaused = false\n this.#isPlaying = true\n this.#onAllAdds((e) => e.itp.resume())\n this.#ticker.add(this.#handleTick)\n }\n\n public stop(): void {\n this.#progress = 0\n this.#time = 0\n this.#isPlaying = false\n this.#isPaused = false\n this.#isReversed = false\n this.#onAllAdds((e) => e.itp.stop())\n this.#ticker.remove(this.#handleTick)\n }\n\n public progress(value?: number, suppressEvents = true, suppressTlEvents = true): number | void {\n if (value === undefined) return this.#progress\n if (this.#isPlaying) this.pause()\n this.#progress = clamp(0, value, 1)\n this.#time = clamp(0, this.#tlDuration * this.#progress, this.#tlDuration)\n this.#updateAdds(this.#time, this.#progress, suppressEvents)\n if (value === 1 && !suppressTlEvents) {\n this.#onComplete(this.#time, this.#progress)\n }\n }\n\n public refresh(): void {\n this.#onAllAdds((e) => e.itp.refresh())\n }\n\n /**\n * @deprecated use refresh() instead\n */\n public refreshComputedValues(): void {\n console.warn(`Timeline.refreshComputedValues() is deprecated. Use Timeline.refresh() instead.`)\n this.refresh()\n }\n\n /**\n * Handle Tick\n * On each tick\n * - update time and progress\n * - update all adds\n * - check if is completed\n * @param delta\n * @private\n */\n // prettier-ignore\n #handleTick = async ({ delta }): Promise<any> => {\n this.#time = clamp(0, this.#tlDuration, this.#time + (this.#isReversed ? -delta : delta))\n this.#progress = clamp(0, round(this.#time / this.#tlDuration), 1)\n this.#updateAdds(this.#time, this.#progress, false)\n // on play complete\n if ((!this.#isReversed && this.#progress === 1) || this.#tlDuration === 0) {\n this.#onComplete(this.#time, this.#progress)\n this.#onCompleteDeferred.resolve()\n this.stop()\n }\n // on reverse complete\n if ((this.#isReversed && this.#progress === 0) || this.#tlDuration === 0) {\n this.#onCompleteDeferred.resolve()\n this.stop()\n }\n }\n\n /**\n * Update all adds (itps)\n * Main update function witch progress all adds on there relative time in TL\n * @param tlTime\n * @param tlProgress\n * @param suppressEvents\n */\n #updateAdds(tlTime: number, tlProgress: number, suppressEvents = true): void {\n // Determine if the Adds loop should be reversed\n if (this.#lastTlProgress > tlProgress && !this.#reverseLoop) this.#reverseLoop = true\n if (this.#lastTlProgress < tlProgress && this.#reverseLoop) this.#reverseLoop = false\n this.#lastTlProgress = tlProgress\n // Call constructor onUpdate\n this.#onUpdate(tlTime, tlProgress)\n // Then progress all itps\n this.#onAllAdds((add) => {\n // Register last and current progress in current add\n add.progress.last = add.progress.current\n // For callbacks with duration 0, trigger when tlTime >= start time\n // In other case, calculate the current progress\n // prettier-ignore\n add.progress.current =\n add.itp.duration === 0\n ? tlTime >= add.time.start ? 1 : 0\n : (tlTime - add.time.start) / add.itp.duration\n // progress current itp\n add.itp.progress(add.progress.current, suppressEvents)\n }, this.#reverseLoop)\n }\n\n /**\n * Exe Callback function on all adds\n * Need to call from 0 to x or x to 0, depends on reversed state\n * @param {(add: IAdd, i?: number) => void} cb\n * @param {boolean} reverse Call from X to 0 index\n */\n #onAllAdds(cb: (add: IAdd, i?: number) => void, reverse: boolean = false): void {\n const startIndex = reverse ? this.#adds.length - 1 : 0\n const endIndex = reverse ? -1 : this.#adds.length\n const step = reverse ? -1 : 1\n for (let i = startIndex; i !== endIndex; i += step) cb(this.#adds[i], i)\n }\n\n /**\n * Log util\n * Active @wbe/debug only if debugEnable is true\n * @param rest\n */\n #log(...rest: any[]): void {\n this.#debugEnable && console.log(`%ctimeline`, `color: rgb(217,50,133)`, this.ID || \"\", ...rest)\n }\n}\n","import { El, CallbackProps } from \"./types\"\n\nconst CACHE = new Map<HTMLElement, Record<string, string>>()\nconst COORDS = new Set([\"x\", \"y\", \"z\"])\nconst NO_PX = new Set([\n \"opacity\",\n \"scale\",\n \"scaleX\",\n \"scaleY\",\n \"scaleZ\",\n \"perspective\",\n \"transformOrigin\",\n])\nconst DEG_PROPERTIES = new Set([\n \"rotate\",\n \"rotateX\",\n \"rotateY\",\n \"rotateZ\",\n \"skew\",\n \"skewX\",\n \"skewY\",\n])\n\nfunction formatValue(key: string, val: number | string, format = true): string | number {\n if (!format || typeof val !== \"number\") return val\n if (NO_PX.has(key)) return val\n if (DEG_PROPERTIES.has(key)) return `${val}deg`\n return `${val}px`\n}\n\n/**\n * Styles function\n * @description Set CSS properties on DOM element(s) or object properties\n * @param element HTMLElement or array of HTMLElement or object\n * @param props Object of css properties to set\n * @param autoUnits Auto add \"px\" & \"deg\" units to number values, string values are not affected\n * @returns\n */\nexport const styles = (\n element: El,\n props: CallbackProps<string, number | string>,\n autoUnits = true,\n): void => {\n if (!element) return\n if (!Array.isArray(element)) element = [element as HTMLElement]\n\n // for each element\n for (const el of element) {\n const cache = CACHE.get(el) || {}\n\n // for each key\n for (let key in props) {\n const v = formatValue(key, props[key], autoUnits)\n // Specific case for \"translate3d\"\n // if x, y, z are keys\n if (COORDS.has(key)) {\n const val = (c) => formatValue(c, props?.[c] ?? cache?.[c] ?? \"0px\", autoUnits)\n cache.translate3d = `translate3d(${val(\"x\")}, ${val(\"y\")}, ${val(\"z\")})`\n cache[key] = `${v}`\n }\n // Other transform properties\n else if (key.match(/^(translate|rotate|scale|skew)/)) {\n cache[key] = `${key}(${v})`\n }\n\n // All other properties, applying directly\n else {\n // case this is a style property\n if (el.style) el.style[key] = v && `${v}`\n // case this is a simple object\n else el[key] = v\n }\n }\n\n // Get the string of transform properties without COORDS (x, y and z values)\n // ex: translate3d(0px, 11px, 0px) scale(1) rotate(1deg)\n const transformString = Object.keys(cache)\n .reduce((a, b) => (COORDS.has(b) ? a : a + cache[b] + \" \"), \"\")\n .trim()\n\n // Finally Apply the join transform string properties with values of COORDS\n if (transformString !== \"\") el.style.transform = transformString\n\n // Cache the transform properties object\n CACHE.set(el, cache)\n }\n}\n"],"mappings":"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