UNPKG

@wbe/interpol

Version:

Interpolates values with a GSAP-like API ~ 3kB

1 lines 51.8 kB
{"version":3,"sources":["../src/index.ts","../src/core/env.ts","../src/core/Ticker.ts","../src/options.ts","../src/core/deferredPromise.ts","../src/core/clamp.ts","../src/core/round.ts","../src/core/compute.ts","../src/core/noop.ts","../src/core/ease.ts","../src/Interpol.ts","../src/Timeline.ts","../src/core/styles.ts"],"sourcesContent":["export type { InterpolConstruct, Props, TimelineConstruct, Value } from \"./core/types\"\nexport type { Ease, EaseFn, EaseName, EaseType, EaseDirection, Power } from \"./core/ease\"\nexport type { IAdd } from \"./Timeline\"\nexport { InterpolOptions } from \"./options\"\nexport { Interpol } from \"./Interpol\"\nexport { Timeline } from \"./Timeline\"\nexport { Ticker } from \"./core/Ticker\"\nexport { Power1, Power2, Power3, Power4, Expo, easeAdapter } from \"./core/ease\"\nexport { styles } from \"./core/styles\"\n","export const isClient = () => typeof window < \"u\"\n","import { isClient } from \"./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 \"./core/Ticker\"\nimport { Value } from \"./core/types\"\nimport { Ease } from \"./core/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","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 */\n// prettier-ignore\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 first letter is lowercase, capitalize it\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","import {\n FormattedProp,\n CallBack,\n InterpolConstruct,\n Props,\n Value,\n CallbackProps,\n InterpolConstructBase,\n} from \"./core/types\"\nimport { deferredPromise } from \"./core/deferredPromise\"\nimport { clamp } from \"./core/clamp\"\nimport { round } from \"./core/round\"\nimport { compute } from \"./core/compute\"\nimport { noop } from \"./core/noop\"\nimport { Ease, easeAdapter, EaseFn, EaseName } from \"./core/ease\"\nimport { InterpolOptions } from \"./options\"\nimport { Ticker } from \"./core/Ticker\"\n\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 #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 #duration: Value\n #callbackProps: CallbackProps<K>\n #immediateRender: boolean\n #delay: number\n #ease: Ease\n #reverseEase: Ease\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 ...inlineProps\n }: InterpolConstruct<K>) {\n this.ticker = InterpolOptions.ticker\n this.#duration = duration\n this.#isPaused = paused\n this.#delay = delay * InterpolOptions.durationFactor\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\n // Prepare & compute props\n this.#props = this.#prepareProps<K>(\n inlineProps as Omit<InterpolConstruct<K>, keyof InterpolConstructBase<K>>,\n )\n this.refreshComputedValues()\n this.#callbackProps = this.#createPropsParamObjRef<K>(this.#props)\n\n this.#beforeStart(this.#callbackProps, this.#time, this.#progress, this)\n\n if (this.#immediateRender) {\n this.#onUpdate(this.#callbackProps, this.#time, this.#progress, this)\n }\n\n if (!this.#isPaused) this.play()\n }\n\n // Compute if values were functions\n public refreshComputedValues(): void {\n this.#_duration = compute(this.#duration) * InterpolOptions.durationFactor\n this.#onEachProps((prop) => {\n prop._from = compute(prop.from)\n prop._to = compute(prop.to)\n })\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.refreshComputedValues()\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 // select ease\n const selectEase = (prop) =>\n this.#isReversed && prop.reverseEase ? prop.reverseEase : prop.ease\n // update prop.value\n this.#onEachProps(\n (prop) =>\n (prop.value = round(\n prop._from + (prop._to - prop._from) * selectEase(prop)(progress),\n 1000,\n )),\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 ease: this.#chooseEase(p?.[\"ease\"] || this.#ease),\n reverseEase: this.#chooseEase(p?.[\"reverseEase\"] || p?.[\"ease\"] || this.#reverseEase),\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\n * @param e ease name or function\n * @returns ease function\n */\n #chooseEase(e: Ease): EaseFn {\n return e != null ? (typeof e === \"string\" ? easeAdapter(e as EaseName) : (e as EaseFn)) : null\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 \"./core/types\"\nimport { Ticker } from \"./core/Ticker\"\nimport { deferredPromise } from \"./core/deferredPromise\"\nimport { clamp } from \"./core/clamp\"\nimport { round } from \"./core/round\"\nimport { noop } from \"./core/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.refreshComputedValues()\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\n }\n if (this.#isPlaying) {\n this.stop()\n return await this.play(from)\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 refreshComputedValues(): void {\n this.#onAllAdds((e) => e.itp.refreshComputedValues())\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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