anim-engine 0.3.2 → 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.
- package/README.md +283 -499
- package/dist/animation/create-animation.d.ts +12 -0
- package/dist/animation/create-animation.js +19 -23
- package/dist/animation/create-single-tween.d.ts +1 -2
- package/dist/animation/index.d.ts +1 -0
- package/dist/animation/runner.d.ts +1 -1
- package/dist/animation/runner.js +22 -22
- package/dist/animation/update.d.ts +1 -1
- package/dist/animation/update.js +4 -4
- package/dist/domain/animation.d.ts +118 -3
- package/dist/domain/color.d.ts +14 -0
- package/dist/domain/easing.d.ts +12 -0
- package/dist/domain/easing.js +9 -35
- package/dist/domain/index.d.ts +4 -4
- package/dist/domain/interpolation.d.ts +153 -5
- package/dist/domain/resolve-value.d.ts +13 -0
- package/dist/domain/resolve-value.js +8 -0
- package/dist/domain/ticker.d.ts +26 -14
- package/dist/domain/timeline.d.ts +47 -2
- package/dist/index.d.ts +10 -13
- package/dist/index.js +8 -7
- package/dist/lerp/create-lerp.d.ts +14 -9
- package/dist/lerp/create-lerp.js +21 -18
- package/dist/lerp/index.d.ts +1 -0
- package/dist/lerp-rgba/hex-to-rgba.d.ts +13 -0
- package/dist/lerp-rgba/hex-to-rgba.js +48 -0
- package/dist/lerp-rgba/index.d.ts +2 -0
- package/dist/lerp-rgba/lerp-rgba.d.ts +13 -0
- package/dist/{color/lerp-oklab.js → lerp-rgba/lerp-rgba.js} +3 -48
- package/dist/smooth-clamp/{smooth-clamp.js → create-smooth-clamp.js} +1 -1
- package/dist/smooth-clamp/index.d.ts +1 -0
- package/dist/smooth-damp/create-smooth-damp.d.ts +16 -10
- package/dist/smooth-damp/create-smooth-damp.js +34 -29
- package/dist/smooth-damp/index.d.ts +1 -0
- package/dist/spring/create-spring.d.ts +13 -11
- package/dist/spring/create-spring.js +17 -19
- package/dist/spring/index.d.ts +1 -0
- package/dist/ticker/get-ticker.d.ts +25 -0
- package/dist/{domain/ticker.js → ticker/get-ticker.js} +10 -2
- package/dist/ticker/index.d.ts +1 -0
- package/dist/timeline/create-timeline.d.ts +16 -6
- package/dist/timeline/create-timeline.js +41 -13
- package/dist/timeline/index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/color/lerp-oklab.d.ts +0 -26
- /package/dist/smooth-clamp/{smooth-clamp.d.ts → create-smooth-clamp.d.ts} +0 -0
|
@@ -1,20 +1,43 @@
|
|
|
1
|
-
import { getTicker } from "../domain/ticker.js";
|
|
2
1
|
import { resolveValue } from "../domain/resolve-value.js";
|
|
2
|
+
import { getTicker } from "../ticker/get-ticker.js";
|
|
3
3
|
import { smoothDampStep } from "./step.js";
|
|
4
4
|
//#region src/smooth-damp/create-smooth-damp.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Creates a smooth damped interpolation that progressively moves a value
|
|
7
|
+
* toward a target with velocity that decreases as it approaches, producing
|
|
8
|
+
* a natural deceleration effect.
|
|
9
|
+
*
|
|
10
|
+
* Unlike a simple lerp, smooth damp respects an optional max speed and
|
|
11
|
+
* maintains velocity continuity, making it suitable for camera-relative
|
|
12
|
+
* movement, UI animations, and game object tracking.
|
|
13
|
+
*
|
|
14
|
+
* The target is re-evaluated every frame, allowing it to change dynamically.
|
|
15
|
+
*
|
|
16
|
+
* @param options - Configuration options for the smooth damp interpolation.
|
|
17
|
+
* @returns An {@link Interpolation} instance for controlling the smooth damp.
|
|
18
|
+
*/
|
|
19
|
+
var createSmoothDamp = ({ to, smoothTimeMs: rawSmoothTimeMs, maxSpeed: rawMaxSpeed, precision = .01, onUpdate, onEnded, ticker = getTicker() }) => {
|
|
9
20
|
const state = {
|
|
10
21
|
current: 0,
|
|
11
22
|
velocity: 0
|
|
12
23
|
};
|
|
13
24
|
let active = true;
|
|
14
|
-
|
|
15
|
-
|
|
25
|
+
state.current = to();
|
|
26
|
+
const update = (deltaMs) => {
|
|
27
|
+
if (!active) return;
|
|
28
|
+
const target = to();
|
|
29
|
+
const smoothTimeMs = resolveValue(rawSmoothTimeMs);
|
|
30
|
+
const maxSpeed = rawMaxSpeed !== void 0 ? resolveValue(rawMaxSpeed) : Infinity;
|
|
31
|
+
smoothDampStep(state, target, smoothTimeMs, maxSpeed, deltaMs);
|
|
32
|
+
onUpdate?.(state.current, state.velocity);
|
|
33
|
+
if (onEnded && Math.abs(state.current - target) < precision && Math.abs(state.velocity) < precision) {
|
|
34
|
+
state.current = target;
|
|
35
|
+
state.velocity = 0;
|
|
36
|
+
onEnded();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
16
39
|
ticker.add(update);
|
|
17
|
-
const
|
|
40
|
+
const resume = () => {
|
|
18
41
|
if (active) return;
|
|
19
42
|
active = true;
|
|
20
43
|
ticker.add(update);
|
|
@@ -23,32 +46,14 @@ var createSmoothDamp = (options) => {
|
|
|
23
46
|
active = false;
|
|
24
47
|
ticker.remove(update);
|
|
25
48
|
};
|
|
26
|
-
const kill = () => {
|
|
27
|
-
active = false;
|
|
28
|
-
ticker.remove(update);
|
|
29
|
-
};
|
|
30
|
-
function update(deltaMs) {
|
|
31
|
-
if (!active) return;
|
|
32
|
-
const target = options.to();
|
|
33
|
-
const smoothTimeMs = resolveValue(options.smoothTimeMs);
|
|
34
|
-
const maxSpeed = options.maxSpeed !== void 0 ? resolveValue(options.maxSpeed) : Infinity;
|
|
35
|
-
smoothDampStep(state, target, smoothTimeMs, maxSpeed, deltaMs);
|
|
36
|
-
onUpdate?.(state.current, state.velocity);
|
|
37
|
-
if (onEnded && Math.abs(state.current - target) < precision && Math.abs(state.velocity) < precision) {
|
|
38
|
-
state.current = target;
|
|
39
|
-
state.velocity = 0;
|
|
40
|
-
onEnded();
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
49
|
return {
|
|
44
|
-
|
|
50
|
+
resume,
|
|
45
51
|
stop,
|
|
46
|
-
|
|
47
|
-
setCurrentValue: (value) => {
|
|
52
|
+
setValue: (value) => {
|
|
48
53
|
state.current = value;
|
|
49
54
|
state.velocity = 0;
|
|
50
55
|
},
|
|
51
|
-
get
|
|
56
|
+
get value() {
|
|
52
57
|
return state.current;
|
|
53
58
|
},
|
|
54
59
|
get velocity() {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSmoothDamp } from './create-smooth-damp';
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { Interpolation,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { Interpolation, SpringOptions } from '../domain';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a spring-based interpolation that simulates mass-spring-damper
|
|
4
|
+
* physics, producing bouncy or elastic movement toward the target value.
|
|
5
|
+
*
|
|
6
|
+
* Uses Verlet integration for stable, energy-conserving simulation.
|
|
7
|
+
* Higher stiffness produces faster, snappier motion; higher damping
|
|
8
|
+
* reduces oscillation. The target is re-evaluated every frame.
|
|
9
|
+
*
|
|
10
|
+
* @param options - Configuration options for the spring interpolation.
|
|
11
|
+
* @returns An {@link Interpolation} instance for controlling the spring.
|
|
12
|
+
*/
|
|
13
|
+
export declare const createSpring: ({ precision, onUpdate, onEnded, to: rawTo, stiffness: rawStiffness, damping: rawDamping, mass: rawMass, ticker, }: SpringOptions) => Interpolation;
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { getTicker } from "../domain/ticker.js";
|
|
2
1
|
import { resolveValue } from "../domain/resolve-value.js";
|
|
2
|
+
import { getTicker } from "../ticker/get-ticker.js";
|
|
3
3
|
import { verletStep } from "./verlet.js";
|
|
4
4
|
//#region src/spring/create-spring.ts
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Creates a spring-based interpolation that simulates mass-spring-damper
|
|
7
|
+
* physics, producing bouncy or elastic movement toward the target value.
|
|
8
|
+
*
|
|
9
|
+
* Uses Verlet integration for stable, energy-conserving simulation.
|
|
10
|
+
* Higher stiffness produces faster, snappier motion; higher damping
|
|
11
|
+
* reduces oscillation. The target is re-evaluated every frame.
|
|
12
|
+
*
|
|
13
|
+
* @param options - Configuration options for the spring interpolation.
|
|
14
|
+
* @returns An {@link Interpolation} instance for controlling the spring.
|
|
15
|
+
*/
|
|
16
|
+
var createSpring = ({ precision = .01, onUpdate, onEnded, to: rawTo, stiffness: rawStiffness = 180, damping: rawDamping = 12, mass: rawMass = 1, ticker = getTicker() }) => {
|
|
13
17
|
const state = {
|
|
14
18
|
current: rawTo(),
|
|
15
19
|
velocity: 0
|
|
16
20
|
};
|
|
17
21
|
let active = true;
|
|
18
|
-
const ticker = getTicker();
|
|
19
22
|
ticker.add(update);
|
|
20
|
-
const
|
|
23
|
+
const resume = () => {
|
|
21
24
|
if (active) return;
|
|
22
25
|
active = true;
|
|
23
26
|
ticker.add(update);
|
|
@@ -26,10 +29,6 @@ var createSpring = (options) => {
|
|
|
26
29
|
active = false;
|
|
27
30
|
ticker.remove(update);
|
|
28
31
|
};
|
|
29
|
-
const kill = () => {
|
|
30
|
-
active = false;
|
|
31
|
-
ticker.remove(update);
|
|
32
|
-
};
|
|
33
32
|
function update(deltaMs) {
|
|
34
33
|
if (!active) return;
|
|
35
34
|
const target = rawTo();
|
|
@@ -45,14 +44,13 @@ var createSpring = (options) => {
|
|
|
45
44
|
}
|
|
46
45
|
}
|
|
47
46
|
return {
|
|
48
|
-
|
|
47
|
+
resume,
|
|
49
48
|
stop,
|
|
50
|
-
|
|
51
|
-
setCurrentValue: (value) => {
|
|
49
|
+
setValue: (value) => {
|
|
52
50
|
state.current = value;
|
|
53
51
|
state.velocity = 0;
|
|
54
52
|
},
|
|
55
|
-
get
|
|
53
|
+
get value() {
|
|
56
54
|
return state.current;
|
|
57
55
|
},
|
|
58
56
|
get velocity() {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createSpring } from './create-spring';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Ticker } from '../domain';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the application-wide default ticker singleton.
|
|
4
|
+
*
|
|
5
|
+
* The ticker is created lazily on first access and reused for all
|
|
6
|
+
* subsequent calls. It drives all animations and interpolations that
|
|
7
|
+
* don't specify an external ticker.
|
|
8
|
+
*
|
|
9
|
+
* @returns The default {@link Ticker} instance.
|
|
10
|
+
*/
|
|
11
|
+
export declare const getTicker: () => Ticker;
|
|
12
|
+
/**
|
|
13
|
+
* Create a ticker that drives active animations.
|
|
14
|
+
*
|
|
15
|
+
* Does NOT auto-start. The user must explicitly call either:
|
|
16
|
+
* - `start()` — begins a `requestAnimationFrame` loop
|
|
17
|
+
* - `update(deltaMs)` — drive manually from a game loop
|
|
18
|
+
*
|
|
19
|
+
* `add()` and `remove()` register/unregister animations without
|
|
20
|
+
* side effects on the rAF loop.
|
|
21
|
+
*
|
|
22
|
+
* Uses a flat array with undefined-tombstone removal for safe concurrent
|
|
23
|
+
* modification during iteration. Compacted after each frame.
|
|
24
|
+
*/
|
|
25
|
+
export declare const createTicker: () => Ticker;
|
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
//#region src/
|
|
1
|
+
//#region src/ticker/get-ticker.ts
|
|
2
2
|
var singleton;
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Returns the application-wide default ticker singleton.
|
|
5
|
+
*
|
|
6
|
+
* The ticker is created lazily on first access and reused for all
|
|
7
|
+
* subsequent calls. It drives all animations and interpolations that
|
|
8
|
+
* don't specify an external ticker.
|
|
9
|
+
*
|
|
10
|
+
* @returns The default {@link Ticker} instance.
|
|
11
|
+
*/
|
|
4
12
|
var getTicker = () => {
|
|
5
13
|
if (!singleton) singleton = createTicker();
|
|
6
14
|
return singleton;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getTicker } from './get-ticker';
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
import { TimelineLayer, Timeline } from '../domain';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { TimelineLayer, Timeline, TimelineCallbacks, ExternalTicker } from '../domain';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a timeline animation that sequences multiple keyframe animation
|
|
4
|
+
* layers, each starting at a specified time or gap after the previous layer.
|
|
5
|
+
*
|
|
6
|
+
* The timeline aggregates all layers into a single controllable animation
|
|
7
|
+
* with its own play/pause/resume/stop semantics and returns the combined
|
|
8
|
+
* values and velocities of all layers on each update.
|
|
9
|
+
*
|
|
10
|
+
* @param layers - An array of {@link TimelineLayer} configs describing each
|
|
11
|
+
* animation in the sequence and when it should play.
|
|
12
|
+
* @param callbacks - Optional callback hooks and configuration.
|
|
13
|
+
* @param ticker - An optional external ticker. Defaults to the global ticker.
|
|
14
|
+
* @returns A {@link Timeline} instance for controlling the sequenced animation.
|
|
15
|
+
*/
|
|
16
|
+
export declare const createTimeline: (layers: TimelineLayer[], { onStarted, onUpdate, onEnded, onProgress }?: TimelineCallbacks, ticker?: ExternalTicker) => Timeline;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { resolveEasing } from "../domain/easing.js";
|
|
2
|
-
import { getTicker } from "../domain/ticker.js";
|
|
3
2
|
import { resolveValue } from "../domain/resolve-value.js";
|
|
3
|
+
import { getTicker } from "../ticker/get-ticker.js";
|
|
4
4
|
import { createKeyframeRunner } from "../animation/runner.js";
|
|
5
5
|
//#region src/timeline/create-timeline.ts
|
|
6
|
-
var
|
|
6
|
+
var noOp = () => {};
|
|
7
7
|
var buildFromConfigs = (rawLayers) => {
|
|
8
8
|
const activeLayers = [];
|
|
9
9
|
let previousEndAt = 0;
|
|
@@ -38,18 +38,40 @@ var buildFromConfigs = (rawLayers) => {
|
|
|
38
38
|
totalDurationMs: Math.max(0, ...activeLayers.map((l) => l.endAt))
|
|
39
39
|
};
|
|
40
40
|
};
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Creates a timeline animation that sequences multiple keyframe animation
|
|
43
|
+
* layers, each starting at a specified time or gap after the previous layer.
|
|
44
|
+
*
|
|
45
|
+
* The timeline aggregates all layers into a single controllable animation
|
|
46
|
+
* with its own play/pause/resume/stop semantics and returns the combined
|
|
47
|
+
* values and velocities of all layers on each update.
|
|
48
|
+
*
|
|
49
|
+
* @param layers - An array of {@link TimelineLayer} configs describing each
|
|
50
|
+
* animation in the sequence and when it should play.
|
|
51
|
+
* @param callbacks - Optional callback hooks and configuration.
|
|
52
|
+
* @param ticker - An optional external ticker. Defaults to the global ticker.
|
|
53
|
+
* @returns A {@link Timeline} instance for controlling the sequenced animation.
|
|
54
|
+
*/
|
|
55
|
+
var createTimeline = (layers, { onStarted, onUpdate, onEnded, onProgress = noOp } = {}, ticker = getTicker()) => {
|
|
44
56
|
const rawLayers = layers;
|
|
45
57
|
let state = buildFromConfigs(rawLayers);
|
|
46
58
|
let activeLayers = state.activeLayers;
|
|
47
59
|
let totalDurationMs = state.totalDurationMs;
|
|
60
|
+
let valuesCache = [];
|
|
61
|
+
let velocitiesCache = [];
|
|
62
|
+
const syncValues = () => {
|
|
63
|
+
valuesCache.length = activeLayers.length;
|
|
64
|
+
velocitiesCache.length = activeLayers.length;
|
|
65
|
+
for (let i = 0; i < activeLayers.length; i++) {
|
|
66
|
+
valuesCache[i] = activeLayers[i].runner.velocity;
|
|
67
|
+
velocitiesCache[i] = activeLayers[i].runner.velocity;
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
syncValues();
|
|
48
71
|
let timelineStatus = "stopped";
|
|
49
72
|
let elapsedMs = 0;
|
|
50
73
|
let resolvePromise;
|
|
51
74
|
let remainingLayers = activeLayers.length;
|
|
52
|
-
const ticker = getTicker();
|
|
53
75
|
const finish = () => {
|
|
54
76
|
timelineStatus = "stopped";
|
|
55
77
|
ticker.remove(update);
|
|
@@ -72,15 +94,19 @@ var createTimeline = (layers, options) => {
|
|
|
72
94
|
}
|
|
73
95
|
}
|
|
74
96
|
}
|
|
97
|
+
syncValues();
|
|
98
|
+
onUpdate?.(valuesCache, velocitiesCache);
|
|
75
99
|
onProgress(totalDurationMs > 0 ? Math.min(elapsedMs / totalDurationMs, 1) : 1);
|
|
76
100
|
if (remainingLayers <= 0) finish();
|
|
77
101
|
};
|
|
78
102
|
const play = () => {
|
|
79
|
-
if (timelineStatus === "dead") throw new Error("Cannot play a dead timeline");
|
|
80
103
|
state = buildFromConfigs(rawLayers);
|
|
81
104
|
activeLayers = state.activeLayers;
|
|
82
105
|
totalDurationMs = state.totalDurationMs;
|
|
83
106
|
remainingLayers = activeLayers.length;
|
|
107
|
+
valuesCache = [];
|
|
108
|
+
velocitiesCache = [];
|
|
109
|
+
syncValues();
|
|
84
110
|
elapsedMs = 0;
|
|
85
111
|
const promise = new Promise((resolve) => {
|
|
86
112
|
resolvePromise = resolve;
|
|
@@ -112,17 +138,13 @@ var createTimeline = (layers, options) => {
|
|
|
112
138
|
layer.runner.evaluate(1);
|
|
113
139
|
layer.runner.onEnded?.();
|
|
114
140
|
}
|
|
141
|
+
syncValues();
|
|
115
142
|
timelineStatus = "stopped";
|
|
116
143
|
ticker.remove(update);
|
|
117
144
|
onEnded?.();
|
|
118
145
|
resolvePromise?.();
|
|
119
146
|
resolvePromise = void 0;
|
|
120
147
|
};
|
|
121
|
-
const kill = () => {
|
|
122
|
-
timelineStatus = "dead";
|
|
123
|
-
ticker.remove(update);
|
|
124
|
-
resolvePromise = void 0;
|
|
125
|
-
};
|
|
126
148
|
const setProgress = (value) => {
|
|
127
149
|
if (timelineStatus === "playing") pause();
|
|
128
150
|
elapsedMs = Math.max(0, Math.min(1, value)) * totalDurationMs;
|
|
@@ -137,6 +159,7 @@ var createTimeline = (layers, options) => {
|
|
|
137
159
|
layer.runner.evaluate(localProgress);
|
|
138
160
|
layer.ended = localProgress >= 1;
|
|
139
161
|
}
|
|
162
|
+
syncValues();
|
|
140
163
|
remainingLayers = activeLayers.filter((l) => !l.ended).length;
|
|
141
164
|
};
|
|
142
165
|
return {
|
|
@@ -145,11 +168,16 @@ var createTimeline = (layers, options) => {
|
|
|
145
168
|
resume,
|
|
146
169
|
stop,
|
|
147
170
|
skipToEnd,
|
|
148
|
-
kill,
|
|
149
171
|
setProgress,
|
|
150
172
|
get progress() {
|
|
151
173
|
return totalDurationMs > 0 ? Math.min(elapsedMs / totalDurationMs, 1) : 1;
|
|
152
174
|
},
|
|
175
|
+
get values() {
|
|
176
|
+
return valuesCache;
|
|
177
|
+
},
|
|
178
|
+
get velocities() {
|
|
179
|
+
return velocitiesCache;
|
|
180
|
+
},
|
|
153
181
|
get status() {
|
|
154
182
|
return timelineStatus;
|
|
155
183
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { createTimeline } from './create-timeline';
|
package/package.json
CHANGED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export type RgbaTuple = readonly [number, number, number, number];
|
|
2
|
-
/**
|
|
3
|
-
* Interpolate between two RGBA colors in Oklab space.
|
|
4
|
-
*
|
|
5
|
-
* The RGB channels are converted to Oklab, lerped perceptually uniformly,
|
|
6
|
-
* and converted back. The alpha channel is lerped linearly.
|
|
7
|
-
*
|
|
8
|
-
* @param from - Starting RGBA tuple [R, G, B, A], each 0–1.
|
|
9
|
-
* @param to - Ending RGBA tuple [R, G, B, A], each 0–1.
|
|
10
|
-
* @param progress - Interpolation factor (0 = from, 1 = to).
|
|
11
|
-
* @returns A new RGBA tuple [R, G, B, A], each 0–1.
|
|
12
|
-
*/
|
|
13
|
-
export declare const lerpOklab: (from: RgbaTuple, to: RgbaTuple, progress: number) => [number, number, number, number];
|
|
14
|
-
/**
|
|
15
|
-
* Parse a hex color string into an RGBA tuple.
|
|
16
|
-
*
|
|
17
|
-
* Accepts formats:
|
|
18
|
-
* - `#RGB`
|
|
19
|
-
* - `#RGBA`
|
|
20
|
-
* - `#RRGGBB`
|
|
21
|
-
* - `#RRGGBBAA`
|
|
22
|
-
*
|
|
23
|
-
* @param hex - Hex color string with optional leading `#`.
|
|
24
|
-
* @returns An RGBA tuple [R, G, B, A], each 0–1.
|
|
25
|
-
*/
|
|
26
|
-
export declare const hexToRgba: (hex: string) => [number, number, number, number];
|
|
File without changes
|