anim-engine 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,14 @@
1
1
  import { AnimationOptions, Animation } from '../domain';
2
+ /**
3
+ * Creates an animation instance that can be played, paused, stopped,
4
+ * and queried for its current state.
5
+ *
6
+ * Accepts either a single tween configuration (from → to over a duration)
7
+ * or a keyframe animation with multiple keyframes, each with optional
8
+ * easing and gaps.
9
+ *
10
+ * @param options - The animation configuration, either {@link SingleTweenOptions}
11
+ * or {@link KeyframeAnimationOptions}.
12
+ * @returns An {@link Animation} instance for controlling the animation.
13
+ */
2
14
  export declare const createAnimation: (options: AnimationOptions) => Animation;
@@ -6,16 +6,27 @@ import { createKeyframeRunner, createTweenRunner } from "./runner.js";
6
6
  var isKeyframeMode = (options) => {
7
7
  return "keyframes" in options && Array.isArray(options.keyframes);
8
8
  };
9
+ /**
10
+ * Creates an animation instance that can be played, paused, stopped,
11
+ * and queried for its current state.
12
+ *
13
+ * Accepts either a single tween configuration (from → to over a duration)
14
+ * or a keyframe animation with multiple keyframes, each with optional
15
+ * easing and gaps.
16
+ *
17
+ * @param options - The animation configuration, either {@link SingleTweenOptions}
18
+ * or {@link KeyframeAnimationOptions}.
19
+ * @returns An {@link Animation} instance for controlling the animation.
20
+ */
9
21
  var createAnimation = (options) => {
10
22
  if (isKeyframeMode(options)) return createKeyframeAnimation(options);
11
23
  return createSingleTween(options);
12
24
  };
13
- var createSingleTween = ({ onStarted, onUpdate, onProgress, onEnded, from: rawFrom, to: rawTo, durationMs: rawDurationMs, ease: easeName = "inOutSine" }) => {
25
+ var createSingleTween = ({ from: rawFrom, to: rawTo, durationMs: rawDurationMs, ease: easeName = "inOutSine", onStarted, onUpdate, onProgress, onEnded, ticker = getTicker() }) => {
14
26
  let cachedDurationMs = resolveValue(rawDurationMs);
15
27
  let status = "stopped";
16
28
  const hasDynamicProperty = typeof rawFrom === "function" || typeof rawTo === "function" || typeof rawDurationMs === "function";
17
29
  let resolvePromise;
18
- const ticker = getTicker();
19
30
  const handleEnded = () => {
20
31
  status = "stopped";
21
32
  ticker.remove(runner);
@@ -41,7 +52,6 @@ var createSingleTween = ({ onStarted, onUpdate, onProgress, onEnded, from: rawFr
41
52
  };
42
53
  runner = buildRunner();
43
54
  const play = () => {
44
- if (status === "dead") throw new Error("Cannot play a dead animation");
45
55
  if (hasDynamicProperty) runner = buildRunner();
46
56
  else runner.reset();
47
57
  const promise = new Promise((resolve) => {
@@ -76,11 +86,6 @@ var createSingleTween = ({ onStarted, onUpdate, onProgress, onEnded, from: rawFr
76
86
  resolvePromise?.();
77
87
  resolvePromise = void 0;
78
88
  };
79
- const kill = () => {
80
- status = "dead";
81
- ticker.remove(runner);
82
- resolvePromise = void 0;
83
- };
84
89
  const setProgress = (value) => {
85
90
  if (status === "playing") pause();
86
91
  runner.evaluate(Math.max(0, Math.min(1, value)));
@@ -91,9 +96,8 @@ var createSingleTween = ({ onStarted, onUpdate, onProgress, onEnded, from: rawFr
91
96
  resume,
92
97
  stop,
93
98
  skipToEnd,
94
- kill,
95
- get currentValue() {
96
- return runner.currentValue;
99
+ get value() {
100
+ return runner.value;
97
101
  },
98
102
  get velocity() {
99
103
  return runner.velocity;
@@ -110,7 +114,7 @@ var createSingleTween = ({ onStarted, onUpdate, onProgress, onEnded, from: rawFr
110
114
  }
111
115
  };
112
116
  };
113
- var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, onProgress, onEnded }) => {
117
+ var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, onProgress, onEnded, ticker = getTicker() }) => {
114
118
  const resolveKeyframeGaps = () => {
115
119
  let total = 0;
116
120
  for (let i = 1; i < rawKeyframes.length; i++) total += resolveValue(rawKeyframes[i].gap ?? 0);
@@ -120,7 +124,6 @@ var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, o
120
124
  let status = "stopped";
121
125
  let resolvePromise;
122
126
  const hasDynamicProperty = rawKeyframes.some((kf) => typeof kf.value === "function" || typeof kf.gap === "function");
123
- const ticker = getTicker();
124
127
  const handleEnded = () => {
125
128
  status = "stopped";
126
129
  ticker.remove(runner);
@@ -144,7 +147,6 @@ var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, o
144
147
  };
145
148
  runner = buildRunner();
146
149
  const play = () => {
147
- if (status === "dead") throw new Error("Cannot play a dead animation");
148
150
  if (hasDynamicProperty) {
149
151
  runner = buildRunner();
150
152
  cachedDurationMs = resolveKeyframeGaps();
@@ -181,11 +183,6 @@ var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, o
181
183
  resolvePromise?.();
182
184
  resolvePromise = void 0;
183
185
  };
184
- const kill = () => {
185
- status = "dead";
186
- ticker.remove(runner);
187
- resolvePromise = void 0;
188
- };
189
186
  const setProgress = (value) => {
190
187
  if (status === "playing") pause();
191
188
  runner.evaluate(Math.max(0, Math.min(1, value)));
@@ -196,9 +193,8 @@ var createKeyframeAnimation = ({ keyframes: rawKeyframes, onStarted, onUpdate, o
196
193
  resume,
197
194
  stop,
198
195
  skipToEnd,
199
- kill,
200
- get currentValue() {
201
- return runner.currentValue;
196
+ get value() {
197
+ return runner.value;
202
198
  },
203
199
  get velocity() {
204
200
  return runner.velocity;
@@ -28,8 +28,7 @@ export type Animation = {
28
28
  resume: () => void;
29
29
  stop: () => void;
30
30
  skipToEnd: () => void;
31
- kill: () => void;
32
- currentValue: number;
31
+ value: number;
33
32
  velocity: number;
34
33
  progress: number;
35
34
  setProgress: (value: number) => void;
@@ -3,7 +3,7 @@ export type Runner = {
3
3
  (deltaMs: number): boolean;
4
4
  evaluate: (progress: number) => number;
5
5
  reset: () => void;
6
- currentValue: number;
6
+ value: number;
7
7
  velocity: number;
8
8
  progress: number;
9
9
  onStarted: (() => void) | undefined;
@@ -4,13 +4,13 @@ var noOp = () => {};
4
4
  var createTweenRunner = ({ from, to, durationMs, easeFn, onStarted, onUpdate = noOp, onProgress = noOp, onEnded }) => {
5
5
  const state = {
6
6
  progress: 0,
7
- currentValue: from,
7
+ value: from,
8
8
  velocity: 0
9
9
  };
10
10
  let runner;
11
11
  const step = (deltaMs) => {
12
12
  const completed = updateTween(state, deltaMs, durationMs, easeFn, from, to);
13
- onUpdate(state.currentValue, state.velocity);
13
+ onUpdate(state.value, state.velocity);
14
14
  onProgress(state.progress);
15
15
  if (completed) onEnded();
16
16
  return completed;
@@ -19,26 +19,26 @@ var createTweenRunner = ({ from, to, durationMs, easeFn, onStarted, onUpdate = n
19
19
  const clamped = Math.max(0, Math.min(1, progress));
20
20
  state.progress = clamped;
21
21
  if (clamped >= 1) {
22
- state.currentValue = to;
22
+ state.value = to;
23
23
  state.velocity = 0;
24
24
  } else {
25
25
  const range = to - from;
26
- state.currentValue = from + range * easeFn(clamped);
26
+ state.value = from + range * easeFn(clamped);
27
27
  state.velocity = 0;
28
28
  }
29
- onUpdate(state.currentValue, state.velocity);
30
- return state.currentValue;
29
+ onUpdate(state.value, state.velocity);
30
+ return state.value;
31
31
  };
32
32
  const reset = () => {
33
33
  state.progress = 0;
34
- state.currentValue = from;
34
+ state.value = from;
35
35
  state.velocity = 0;
36
36
  };
37
37
  runner = step;
38
38
  runner.evaluate = evaluate;
39
39
  runner.reset = reset;
40
- Object.defineProperty(runner, "currentValue", {
41
- get: () => state.currentValue,
40
+ Object.defineProperty(runner, "value", {
41
+ get: () => state.value,
42
42
  configurable: true
43
43
  });
44
44
  Object.defineProperty(runner, "velocity", {
@@ -71,7 +71,7 @@ var createKeyframeRunner = ({ keyframes, onStarted, onUpdate = noOp, onProgress
71
71
  for (let i = 0; i < segments.length; i++) prefixSum.push(prefixSum[i] + segments[i].durationMs);
72
72
  const totalDurationMs = prefixSum[prefixSum.length - 1];
73
73
  const invTotalDuration = totalDurationMs > 0 ? 1 / totalDurationMs : 1;
74
- let currentValue = keyframes[0].value;
74
+ let value = keyframes[0].value;
75
75
  let velocity = 0;
76
76
  let globalProgress = 0;
77
77
  let currentSegmentIndex = 0;
@@ -83,22 +83,22 @@ var createKeyframeRunner = ({ keyframes, onStarted, onUpdate = noOp, onProgress
83
83
  segmentElapsed += deltaMs;
84
84
  segmentProgress += deltaMs / segment.durationMs;
85
85
  if (segmentProgress >= 1) segmentProgress = 1;
86
- const previousValue = currentValue;
86
+ const previousValue = value;
87
87
  const eased = segment.easeFn(segmentProgress);
88
- currentValue = segment.from + segment.range * eased;
88
+ value = segment.from + segment.range * eased;
89
89
  if (segmentProgress >= 1) {
90
- currentValue = segment.to;
90
+ value = segment.to;
91
91
  velocity = 0;
92
- } else velocity = (currentValue - previousValue) / (deltaMs / 1e3);
92
+ } else velocity = (value - previousValue) / (deltaMs / 1e3);
93
93
  const elapsedTotal = prefixSum[currentSegmentIndex] + segmentElapsed;
94
94
  globalProgress = Math.min(elapsedTotal * invTotalDuration, 1);
95
95
  onProgress(globalProgress);
96
- onUpdate(currentValue, velocity);
96
+ onUpdate(value, velocity);
97
97
  if (segmentProgress >= 1) if (currentSegmentIndex < segments.length - 1) {
98
98
  currentSegmentIndex++;
99
99
  segmentElapsed = 0;
100
100
  segmentProgress = 0;
101
- currentValue = segments[currentSegmentIndex].from;
101
+ value = segments[currentSegmentIndex].from;
102
102
  velocity = 0;
103
103
  globalProgress = Math.min(prefixSum[currentSegmentIndex] * invTotalDuration, 1);
104
104
  onProgress(globalProgress);
@@ -125,18 +125,18 @@ var createKeyframeRunner = ({ keyframes, onStarted, onUpdate = noOp, onProgress
125
125
  const segProgress = segDuration > 0 ? (elapsed - segStart) / segDuration : 1;
126
126
  const clampedSegProgress = Math.max(0, Math.min(1, segProgress));
127
127
  const eased = segment.easeFn(clampedSegProgress);
128
- currentValue = segment.from + segment.range * eased;
128
+ value = segment.from + segment.range * eased;
129
129
  velocity = 0;
130
130
  globalProgress = clamped;
131
131
  currentSegmentIndex = segIdx;
132
132
  segmentElapsed = elapsed - segStart;
133
133
  segmentProgress = clampedSegProgress;
134
- onUpdate(currentValue, velocity);
134
+ onUpdate(value, velocity);
135
135
  onProgress(clamped);
136
- return currentValue;
136
+ return value;
137
137
  };
138
138
  const reset = () => {
139
- currentValue = keyframes[0].value;
139
+ value = keyframes[0].value;
140
140
  velocity = 0;
141
141
  globalProgress = 0;
142
142
  currentSegmentIndex = 0;
@@ -146,8 +146,8 @@ var createKeyframeRunner = ({ keyframes, onStarted, onUpdate = noOp, onProgress
146
146
  runner = update;
147
147
  runner.evaluate = evaluate;
148
148
  runner.reset = reset;
149
- Object.defineProperty(runner, "currentValue", {
150
- get: () => currentValue,
149
+ Object.defineProperty(runner, "value", {
150
+ get: () => value,
151
151
  configurable: true
152
152
  });
153
153
  Object.defineProperty(runner, "velocity", {
@@ -1,7 +1,7 @@
1
1
  import { EaseFunction } from '../domain';
2
2
  export type TweenState = {
3
3
  progress: number;
4
- currentValue: number;
4
+ value: number;
5
5
  velocity: number;
6
6
  };
7
7
  /**
@@ -7,15 +7,15 @@
7
7
  var updateTween = (state, deltaMs, durationMs, easeFn, from, to) => {
8
8
  const thisFrameProgress = deltaMs / durationMs;
9
9
  state.progress = Math.min(state.progress + thisFrameProgress, 1);
10
- const previousValue = state.currentValue;
10
+ const previousValue = state.value;
11
11
  if (state.progress >= 1) {
12
- state.currentValue = to;
12
+ state.value = to;
13
13
  state.velocity = 0;
14
14
  return true;
15
15
  }
16
16
  const eased = easeFn(state.progress);
17
- state.currentValue = from + (to - from) * eased;
18
- state.velocity = (state.currentValue - previousValue) / (deltaMs / 1e3);
17
+ state.value = from + (to - from) * eased;
18
+ state.velocity = (state.value - previousValue) / (deltaMs / 1e3);
19
19
  return false;
20
20
  };
21
21
  //#endregion
@@ -1,40 +1,155 @@
1
1
  import { EaseFunction, EaseName } from './easing';
2
2
  import { DynamicValue } from './resolve-value';
3
- export type AnimationStatus = "playing" | "paused" | "stopped" | "dead";
3
+ import { ExternalTicker } from './ticker';
4
+ /**
5
+ * The status of an animation, which can be "playing", "paused", or "stopped".
6
+ * - "playing": The animation is currently running.
7
+ * - "paused": The animation is temporarily halted but can be resumed.
8
+ * - "stopped": The animation has finished or has been stopped and is available for garbage collection if no external references remain.
9
+ */
10
+ export type AnimationStatus = "playing" | "paused" | "stopped";
11
+ /**
12
+ * Options for creating a single tween animation, which interpolates between a starting and ending value over a specified duration with optional easing.
13
+ */
4
14
  export type SingleTweenOptions = {
15
+ /**
16
+ * The starting value of the animation. Can be a number or a function that returns a number.
17
+ */
5
18
  from: DynamicValue;
19
+ /**
20
+ * The ending value of the animation. Can be a number or a function that returns a number.
21
+ */
6
22
  to: DynamicValue;
23
+ /**
24
+ * The duration of the animation in milliseconds. Can be a number or a function that returns a number.
25
+ */
7
26
  durationMs: DynamicValue;
27
+ /**
28
+ * The easing function or name to use for the animation.
29
+ */
8
30
  ease?: EaseName | EaseFunction;
31
+ /**
32
+ * Callback fired when the animation starts.
33
+ */
9
34
  onStarted?: () => void;
35
+ /**
36
+ * Callback fired on each animation update with the current value and velocity.
37
+ */
10
38
  onUpdate?: (value: number, velocity: number) => void;
39
+ /**
40
+ * Callback fired on each animation update with the current progress (0 to 1).
41
+ */
11
42
  onProgress?: (progress: number) => void;
43
+ /**
44
+ * Callback fired when the animation ends.
45
+ */
12
46
  onEnded?: () => void;
47
+ /**
48
+ * Optional external ticker to drive the animation.
49
+ */
50
+ ticker?: ExternalTicker;
13
51
  };
52
+ /**
53
+ * Object for describing a single keyframe.
54
+ */
14
55
  export type Keyframe = {
56
+ /**
57
+ * The value of the keyframe. Can be a number or a function that returns a number.
58
+ */
15
59
  value: DynamicValue;
60
+ /**
61
+ * The easing function or name to use for the keyframe.
62
+ */
16
63
  ease?: EaseName | EaseFunction;
64
+ /**
65
+ * The gap before the keyframe in milliseconds. Can be a number or a function that returns a number.
66
+ */
17
67
  gap?: DynamicValue;
18
68
  };
69
+ /**
70
+ * Options for creating a keyframe animation, which consists of multiple keyframes each with their own value, easing, and optional gap.
71
+ */
19
72
  export type KeyframeAnimationOptions = {
73
+ /**
74
+ * The keyframes for the animation. Each keyframe defines a value, optional easing, and optional gap in milliseconds.
75
+ */
20
76
  keyframes: Keyframe[];
77
+ /**
78
+ * Callback fired when the animation starts.
79
+ */
21
80
  onStarted?: () => void;
81
+ /**
82
+ * Callback fired on each animation update with the current value and velocity.
83
+ */
22
84
  onUpdate?: (value: number, velocity: number) => void;
85
+ /**
86
+ * Callback fired on each animation update with the current progress (0 to 1).
87
+ */
23
88
  onProgress?: (progress: number) => void;
89
+ /**
90
+ * Callback fired when the animation ends.
91
+ */
24
92
  onEnded?: () => void;
93
+ /**
94
+ * Optional external ticker to drive the animation.
95
+ */
96
+ ticker?: ExternalTicker;
25
97
  };
98
+ /**
99
+ * Options for creating an animation, which can be either a single tween or a keyframe animation type.
100
+ */
26
101
  export type AnimationOptions = SingleTweenOptions | KeyframeAnimationOptions;
102
+ /**
103
+ * Represents an animation instance that can be controlled and queried for its state.
104
+ */
27
105
  export type Animation = {
106
+ /**
107
+ * Plays the animation from the current state and returns a promise that resolves when the animation ends.
108
+ */
28
109
  play: () => Promise<void>;
110
+ /**
111
+ * Pauses the animation if it is currently playing.
112
+ */
29
113
  pause: () => void;
114
+ /**
115
+ * Resumes the animation if it is currently paused.
116
+ */
30
117
  resume: () => void;
118
+ /**
119
+ * Stops the animation and resets its state.
120
+ */
31
121
  stop: () => void;
122
+ /**
123
+ * Skips the animation to its end state immediately.
124
+ */
32
125
  skipToEnd: () => void;
33
- kill: () => void;
34
- currentValue: number;
126
+ /**
127
+ * The current value of the animation.
128
+ */
129
+ value: number;
130
+ /**
131
+ * The current velocity of the animation.
132
+ */
35
133
  velocity: number;
134
+ /**
135
+ * The current progress of the animation, represented as a number between 0 and 1.
136
+ */
36
137
  progress: number;
138
+ /**
139
+ * Sets the progress of the animation to a specific value between 0 and 1. If the animation is playing, it will be paused.
140
+ */
37
141
  setProgress: (value: number) => void;
142
+ /**
143
+ * The current status of the animation, which can be "playing", "paused", or "stopped".
144
+ * - "playing": The animation is currently running.
145
+ * - "paused": The animation is temporarily halted but can be resumed.
146
+ * - "stopped": The animation has finished or has been stopped and is available for garbage collection if no external references remain.
147
+ */
38
148
  status: AnimationStatus;
149
+ /**
150
+ * The total duration of the animation in milliseconds. This value is determined by the animation's configuration and keyframes.
151
+ * For single tween animations, this is the specified duration. For keyframe animations, this is the sum of all keyframe gaps and durations.
152
+ * Note that if the animation has dynamic values for duration or gaps, this value may change when the animation is played and the dynamic values are read.
153
+ */
39
154
  durationMs: number;
40
155
  };
@@ -1,2 +1,14 @@
1
+ /**
2
+ * A tuple representing an RGBA color with each channel as a float in the range [0, 1].
3
+ * Ordered as [red, green, blue, alpha].
4
+ */
1
5
  export type RgbaTuple = readonly [number, number, number, number];
6
+ /**
7
+ * A function that linearly interpolates between two RGBA colors in Oklab color space.
8
+ *
9
+ * @param from - The starting color as an RgbaTuple.
10
+ * @param to - The ending color as an RgbaTuple.
11
+ * @param progress - A number between 0 and 1 representing the interpolation progress.
12
+ * @returns The interpolated color as an RgbaTuple.
13
+ */
2
14
  export type LerpRgba = (from: RgbaTuple, to: RgbaTuple, progress: number) => RgbaTuple;
@@ -1,4 +1,16 @@
1
+ /**
2
+ * A function that maps a progress value `t` in [0, 1] to an eased output value.
3
+ * Values outside [0, 1] may be returned for overshooting easings like elastic or back.
4
+ */
1
5
  export type EaseFunction = (t: number) => number;
6
+ /**
7
+ * Resolves an easing identifier or function into a concrete {@link EaseFunction}.
8
+ * If a function is passed, it is returned as-is. If a name is passed, the
9
+ * corresponding built-in easing function is looked up.
10
+ *
11
+ * @param ease - An easing name or a custom easing function.
12
+ * @returns The resolved easing function.
13
+ */
2
14
  export declare const resolveEasing: (ease: EaseName | EaseFunction) => EaseFunction;
3
15
  /** All 31 named easing identifiers, ordered by type. */
4
16
  export declare const EASE_NAMES: readonly ["linear", "inQuad", "outQuad", "inOutQuad", "inCubic", "outCubic", "inOutCubic", "inQuart", "outQuart", "inOutQuart", "inQuint", "outQuint", "inOutQuint", "inSine", "outSine", "inOutSine", "inExpo", "outExpo", "inOutExpo", "inCirc", "outCirc", "inOutCirc", "inBack", "outBack", "inOutBack", "inElastic", "outElastic", "inOutElastic", "inBounce", "outBounce", "inOutBounce"];
@@ -1,4 +1,12 @@
1
1
  //#region src/domain/easing.ts
2
+ /**
3
+ * Resolves an easing identifier or function into a concrete {@link EaseFunction}.
4
+ * If a function is passed, it is returned as-is. If a name is passed, the
5
+ * corresponding built-in easing function is looked up.
6
+ *
7
+ * @param ease - An easing name or a custom easing function.
8
+ * @returns The resolved easing function.
9
+ */
2
10
  var resolveEasing = (ease) => typeof ease === "function" ? ease : EASING_FUNCTIONS[ease];
3
11
  var pow = Math.pow;
4
12
  var sqrt = Math.sqrt;
@@ -2,9 +2,9 @@ export type { AnimationStatus } from './animation';
2
2
  export type { InterpolationStatus, Interpolation, LerpOptions, SmoothDampOptions, SpringOptions, } from './interpolation';
3
3
  export type { EaseName, EaseFunction } from './easing';
4
4
  export { EASE_NAMES, cubicBezier, EASING_FUNCTIONS, resolveEasing } from './easing';
5
- export type { Ticker, TickHandler } from './ticker';
5
+ export type { Ticker, TickHandler, ExternalTicker } from './ticker';
6
6
  export { resolveValue } from './resolve-value';
7
7
  export type { DynamicValue } from './resolve-value';
8
8
  export type { Animation, AnimationOptions, SingleTweenOptions, KeyframeAnimationOptions, Keyframe, } from './animation';
9
- export type { TimelineLayer, Timeline } from './timeline';
9
+ export type { TimelineLayer, Timeline, TimelineCallbacks } from './timeline';
10
10
  export type { RgbaTuple, LerpRgba } from './color';
@@ -1,35 +1,158 @@
1
1
  import { DynamicValue } from './resolve-value';
2
- export type InterpolationStatus = "active" | "inactive" | "dead";
2
+ import { ExternalTicker } from './ticker';
3
+ /**
4
+ * Represents the status of an interpolation, which can be either "active" or "inactive".
5
+ */
6
+ export type InterpolationStatus = "active" | "inactive";
7
+ /**
8
+ * Represents an interpolation process that can be controlled and monitored.
9
+ *
10
+ * The interpolation can be resumed or stopped, and its current value, velocity, and status can be accessed.
11
+ */
3
12
  export type Interpolation = {
4
- start: () => void;
13
+ /**
14
+ * Resumes the interpolation if it is currently inactive.
15
+ */
16
+ resume: () => void;
17
+ /**
18
+ * Stops the interpolation if it is currently active.
19
+ */
5
20
  stop: () => void;
6
- kill: () => void;
7
- setCurrentValue: (value: number) => void;
8
- currentValue: number;
21
+ /**
22
+ * Sets the current value of the interpolation instantly and resets its velocity to zero.
23
+ */
24
+ setValue: (value: number) => void;
25
+ /**
26
+ * The current value of the interpolation.
27
+ */
28
+ value: number;
29
+ /**
30
+ * The current velocity of the interpolation.
31
+ */
9
32
  velocity: number;
33
+ /**
34
+ * The current status of the interpolation, which can be "active" or "inactive".
35
+ */
10
36
  status: InterpolationStatus;
11
37
  };
38
+ /**
39
+ * Options for configuring a linear interpolation (lerp) function.
40
+ */
12
41
  export type LerpOptions = {
42
+ /**
43
+ * A function that returns the starting value for the interpolation. This is evaluated every frame.
44
+ */
13
45
  to: () => number;
46
+ /**
47
+ * A function that returns the ending value for the interpolation. This is evaluated every frame if a function is provided.
48
+ */
14
49
  smoothTimeMs: DynamicValue;
50
+ /**
51
+ * The precision threshold for determining when the interpolation has effectively reached its target. Defaults to 0.01.
52
+ */
15
53
  precision?: number;
54
+ /**
55
+ * A callback function that is called on every update of the interpolation, receiving the current value and velocity as arguments.
56
+ */
16
57
  onUpdate?: (value: number, velocity: number) => void;
58
+ /**
59
+ * A callback function that is called when the interpolation has effectively reached its target and is considered complete.
60
+ */
17
61
  onEnded?: () => void;
62
+ /**
63
+ * An optional external ticker that can be provided to control the timing of the interpolation updates. If not provided, a default ticker will be used.
64
+ */
65
+ ticker?: ExternalTicker;
18
66
  };
67
+ /**
68
+ * Options for configuring a smooth damped interpolation.
69
+ *
70
+ * Smooth damp progressively moves toward a target value with velocity that
71
+ * decreases as it approaches, producing a natural deceleration effect.
72
+ */
19
73
  export type SmoothDampOptions = {
74
+ /**
75
+ * A function that returns the target value to smoothly move toward.
76
+ * This is evaluated every frame, allowing the target to change dynamically.
77
+ */
20
78
  to: () => number;
79
+ /**
80
+ * The approximate time (in milliseconds) it takes for the value to settle
81
+ * at the target. Larger values produce slower, more gradual movement.
82
+ */
21
83
  smoothTimeMs: DynamicValue;
84
+ /**
85
+ * An optional maximum speed cap (in units/second). Prevents excessively
86
+ * fast movement when the gap between current and target is large.
87
+ */
22
88
  maxSpeed?: DynamicValue;
89
+ /**
90
+ * The precision threshold for determining when the interpolation has
91
+ * effectively reached its target. Defaults to 0.01.
92
+ */
23
93
  precision?: number;
94
+ /**
95
+ * A callback function that is called on every update of the interpolation,
96
+ * receiving the current value and velocity as arguments.
97
+ */
24
98
  onUpdate?: (value: number, velocity: number) => void;
99
+ /**
100
+ * A callback function that is called when the interpolation has effectively
101
+ * reached its target and is considered complete.
102
+ */
25
103
  onEnded?: () => void;
104
+ /**
105
+ * An optional external ticker that can be provided to control the timing of
106
+ * the interpolation updates. If not provided, a default ticker will be used.
107
+ */
108
+ ticker?: ExternalTicker;
26
109
  };
110
+ /**
111
+ * Options for configuring a spring-based interpolation.
112
+ *
113
+ * Spring physics simulate mass-spring-damper motion, producing bouncy or
114
+ * elastic movement toward the target value.
115
+ */
27
116
  export type SpringOptions = {
117
+ /**
118
+ * A function that returns the target value toward which the spring pulls.
119
+ * This is evaluated every frame, allowing the target to change dynamically.
120
+ */
28
121
  to: () => number;
122
+ /**
123
+ * The stiffness of the spring. Higher values produce faster, snappier motion.
124
+ * Defaults to 180.
125
+ */
29
126
  stiffness?: DynamicValue;
127
+ /**
128
+ * The damping coefficient. Higher values reduce oscillation and settling time.
129
+ * Defaults to 12.
130
+ */
30
131
  damping?: DynamicValue;
132
+ /**
133
+ * The mass of the simulated object. Higher values produce slower, heavier
134
+ * motion. Defaults to 1.
135
+ */
31
136
  mass?: DynamicValue;
137
+ /**
138
+ * The precision threshold for determining when the spring has effectively
139
+ * settled at its target (both position and velocity within tolerance).
140
+ * Defaults to 0.01.
141
+ */
32
142
  precision?: number;
143
+ /**
144
+ * A callback function that is called on every update of the spring,
145
+ * receiving the current value and velocity as arguments.
146
+ */
33
147
  onUpdate?: (value: number, velocity: number) => void;
148
+ /**
149
+ * A callback function that is called when the spring has effectively
150
+ * settled at its target and is considered complete.
151
+ */
34
152
  onEnded?: () => void;
153
+ /**
154
+ * An optional external ticker that can be provided to control the timing of
155
+ * the spring updates. If not provided, a default ticker will be used.
156
+ */
157
+ ticker?: ExternalTicker;
35
158
  };