{"version":3,"file":"AnimationBase.min.mjs","names":[],"sources":["../../../../src/util/animation/AnimationBase.ts"],"sourcesContent":["import { noop } from '../../constants';\nimport { getFabricWindow } from '../../env';\nimport { requestAnimFrame } from './AnimationFrameProvider';\nimport { runningAnimations } from './AnimationRegistry';\nimport { defaultEasing } from './easing';\nimport type {\n  AnimationState,\n  TAbortCallback,\n  TBaseAnimationOptions,\n  TEasingFunction,\n  TOnAnimationChangeCallback,\n} from './types';\n\nconst defaultAbort = () => false;\n\nexport abstract class AnimationBase<\n  T extends number | number[] = number | number[],\n> {\n  declare readonly startValue: T;\n  declare readonly endValue: T;\n  declare readonly duration: number;\n  declare readonly delay: number;\n\n  declare protected readonly byValue: T;\n  declare protected readonly easing: TEasingFunction<T>;\n\n  declare private readonly _onStart: VoidFunction;\n  declare private readonly _onChange: TOnAnimationChangeCallback<T>;\n  declare private readonly _onComplete: TOnAnimationChangeCallback<T>;\n  declare private readonly _abort: TAbortCallback<T>;\n\n  /**\n   * Used to register the animation to a target object\n   * so that it can be cancelled within the object context\n   */\n  declare readonly target?: unknown;\n\n  private _state: AnimationState = 'pending';\n  /**\n   * Time %, or the ratio of `timeElapsed / duration`\n   * @see tick\n   */\n  durationProgress = 0;\n  /**\n   * Value %, or the ratio of `(currentValue - startValue) / (endValue - startValue)`\n   */\n  valueProgress = 0;\n  /**\n   * Current value\n   */\n  declare value: T;\n  /**\n   * Animation start time ms\n   */\n  declare private startTime: number;\n\n  declare private timeout: number | null;\n\n  constructor({\n    startValue,\n    byValue,\n    duration = 500,\n    delay = 0,\n    easing = defaultEasing,\n    onStart = noop,\n    onChange = noop,\n    onComplete = noop,\n    abort = defaultAbort,\n    target,\n  }: TBaseAnimationOptions<T>) {\n    this.tick = this.tick.bind(this);\n\n    this.duration = duration;\n    this.delay = delay;\n    this.easing = easing;\n    this._onStart = onStart;\n    this._onChange = onChange;\n    this._onComplete = onComplete;\n    this._abort = abort;\n    this.target = target;\n\n    this.startValue = startValue;\n    this.byValue = byValue;\n    this.value = this.startValue;\n    this.endValue = Object.freeze(this.calculate(this.duration).value);\n  }\n\n  get state() {\n    return this._state;\n  }\n\n  isDone() {\n    return this._state === 'aborted' || this._state === 'completed';\n  }\n\n  /**\n   * Calculate the current value based on the easing parameters\n   * @param timeElapsed in ms\n   * @protected\n   */\n  protected abstract calculate(timeElapsed: number): {\n    value: T;\n    valueProgress: number;\n  };\n\n  start() {\n    const firstTick: FrameRequestCallback = (timestamp) => {\n      if (this._state !== 'pending') return;\n      this.startTime = timestamp || +new Date();\n      this._state = 'running';\n      this._onStart();\n      this.tick(this.startTime);\n    };\n\n    this.register();\n\n    // setTimeout(cb, 0) will run cb on the next frame, causing a delay\n    // we don't want that\n    if (this.delay > 0) {\n      this.timeout = getFabricWindow().setTimeout(\n        () => requestAnimFrame(firstTick),\n        this.delay,\n      );\n    } else {\n      requestAnimFrame(firstTick);\n    }\n  }\n\n  private tick(t: number) {\n    const durationMs = (t || +new Date()) - this.startTime;\n    const boundDurationMs = Math.min(durationMs, this.duration);\n    this.durationProgress = boundDurationMs / this.duration;\n    const { value, valueProgress } = this.calculate(boundDurationMs);\n    this.value = Object.freeze(value);\n    this.valueProgress = valueProgress;\n\n    if (this._state === 'aborted') {\n      return;\n    } else if (\n      this._abort(this.value, this.valueProgress, this.durationProgress)\n    ) {\n      this._state = 'aborted';\n      this.unregister();\n    } else if (durationMs >= this.duration) {\n      this.durationProgress = this.valueProgress = 1;\n      this._onChange(this.endValue, this.valueProgress, this.durationProgress);\n      this._state = 'completed';\n      this._onComplete(\n        this.endValue,\n        this.valueProgress,\n        this.durationProgress,\n      );\n      this.unregister();\n      this.timeout = null;\n    } else {\n      this._onChange(this.value, this.valueProgress, this.durationProgress);\n      requestAnimFrame(this.tick);\n    }\n  }\n\n  private register() {\n    runningAnimations.push(this as unknown as AnimationBase);\n  }\n\n  private unregister() {\n    runningAnimations.remove(this as unknown as AnimationBase);\n  }\n\n  abort() {\n    this._state = 'aborted';\n    this.unregister();\n\n    this.timeout && getFabricWindow().clearTimeout(this.timeout);\n  }\n}\n"],"mappings":"+YAaA,MAAM,MAAA,CAAqB,EAE3B,IAAsB,EAAtB,KAAA,CA2CE,YAAA,CAAY,WACV,EAAA,QACA,EAAA,SACA,EAAW,IAAA,MACX,EAAQ,EAAA,OACR,EAAS,EAAA,QACT,EAAU,EAAA,SACV,EAAW,EAAA,WACX,EAAa,EAAA,MACb,EAAQ,EAAA,OACR,GAAA,CAAA,EAAA,KA/BM,SAAyB,UAAA,CAAA,EAAA,KAKjC,mBAAmB,EAAA,CAAA,EAAA,KAInB,gBAAgB,EAAA,CAwBd,KAAK,KAAO,KAAK,KAAK,KAAK,KAAA,CAE3B,KAAK,SAAW,EAChB,KAAK,MAAQ,EACb,KAAK,OAAS,EACd,KAAK,SAAW,EAChB,KAAK,UAAY,EACjB,KAAK,YAAc,EACnB,KAAK,OAAS,EACd,KAAK,OAAS,EAEd,KAAK,WAAa,EAClB,KAAK,QAAU,EACf,KAAK,MAAQ,KAAK,WAClB,KAAK,SAAW,OAAO,OAAO,KAAK,UAAU,KAAK,SAAA,CAAU,MAAA,CAG9D,IAAA,OAAI,CACF,OAAO,KAAK,OAGd,QAAA,CACE,OAAO,KAAK,SAAW,WAAa,KAAK,SAAW,YAatD,OAAA,CACE,IAAM,EAAmC,GAAA,CACnC,KAAK,SAAW,YACpB,KAAK,UAAY,GAAA,CAAc,IAAI,KACnC,KAAK,OAAS,UACd,KAAK,UAAA,CACL,KAAK,KAAK,KAAK,UAAA,GAGjB,KAAK,UAAA,CAID,KAAK,MAAQ,EACf,KAAK,QAAU,GAAA,CAAkB,eACzB,EAAiB,EAAA,CACvB,KAAK,MAAA,CAGP,EAAiB,EAAA,CAIrB,KAAa,EAAA,CACX,IAAM,GAAc,GAAA,CAAM,IAAI,MAAU,KAAK,UACvC,EAAkB,KAAK,IAAI,EAAY,KAAK,SAAA,CAClD,KAAK,iBAAmB,EAAkB,KAAK,SAC/C,GAAA,CAAM,MAAE,EAAA,cAAO,GAAkB,KAAK,UAAU,EAAA,CAChD,KAAK,MAAQ,OAAO,OAAO,EAAA,CAC3B,KAAK,cAAgB,EAEjB,KAAK,SAAW,YAGlB,KAAK,OAAO,KAAK,MAAO,KAAK,cAAe,KAAK,iBAAA,EAEjD,KAAK,OAAS,UACd,KAAK,YAAA,EACI,GAAc,KAAK,UAC5B,KAAK,iBAAmB,KAAK,cAAgB,EAC7C,KAAK,UAAU,KAAK,SAAU,KAAK,cAAe,KAAK,iBAAA,CACvD,KAAK,OAAS,YACd,KAAK,YACH,KAAK,SACL,KAAK,cACL,KAAK,iBAAA,CAEP,KAAK,YAAA,CACL,KAAK,QAAU,OAEf,KAAK,UAAU,KAAK,MAAO,KAAK,cAAe,KAAK,iBAAA,CACpD,EAAiB,KAAK,KAAA,GAI1B,UAAA,CACE,EAAkB,KAAK,KAAA,CAGzB,YAAA,CACE,EAAkB,OAAO,KAAA,CAG3B,OAAA,CACE,KAAK,OAAS,UACd,KAAK,YAAA,CAEL,KAAK,SAAW,GAAA,CAAkB,aAAa,KAAK,QAAA,GAAA,OAAA,KAAA"}