@voila.dev/motion 0.0.0-stage → 5.0.113
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 +105 -2
- package/dist/accessibility/reduced-motion.d.ts +13 -0
- package/dist/accessibility/reduced-motion.d.ts.map +1 -0
- package/dist/accessibility/reduced-motion.js +56 -0
- package/dist/accessibility/reduced-motion.js.map +7 -0
- package/dist/animate/animate.d.ts +21 -0
- package/dist/animate/animate.d.ts.map +1 -0
- package/dist/animate/animate.js +76 -0
- package/dist/animate/animate.js.map +7 -0
- package/dist/animate/controls.d.ts +16 -0
- package/dist/animate/controls.d.ts.map +1 -0
- package/dist/animate/controls.js +62 -0
- package/dist/animate/controls.js.map +7 -0
- package/dist/animate/dom.d.ts +11 -0
- package/dist/animate/dom.d.ts.map +1 -0
- package/dist/animate/dom.js +112 -0
- package/dist/animate/dom.js.map +7 -0
- package/dist/animate/js-animation.d.ts +25 -0
- package/dist/animate/js-animation.d.ts.map +1 -0
- package/dist/animate/js-animation.js +117 -0
- package/dist/animate/js-animation.js.map +7 -0
- package/dist/animate/plan.d.ts +17 -0
- package/dist/animate/plan.d.ts.map +1 -0
- package/dist/animate/plan.js +48 -0
- package/dist/animate/plan.js.map +7 -0
- package/dist/animate/style.d.ts +27 -0
- package/dist/animate/style.d.ts.map +1 -0
- package/dist/animate/style.js +96 -0
- package/dist/animate/style.js.map +7 -0
- package/dist/animate/types.d.ts +62 -0
- package/dist/animate/types.d.ts.map +1 -0
- package/dist/animate/types.js +1 -0
- package/dist/animate/types.js.map +7 -0
- package/dist/animate/value.d.ts +13 -0
- package/dist/animate/value.d.ts.map +1 -0
- package/dist/animate/value.js +71 -0
- package/dist/animate/value.js.map +7 -0
- package/dist/animate/waapi.d.ts +20 -0
- package/dist/animate/waapi.d.ts.map +1 -0
- package/dist/animate/waapi.js +152 -0
- package/dist/animate/waapi.js.map +7 -0
- package/dist/dom.d.ts +12 -0
- package/dist/dom.d.ts.map +1 -0
- package/dist/dom.js +17 -0
- package/dist/dom.js.map +7 -0
- package/dist/easing/cubic-bezier.d.ts +4 -0
- package/dist/easing/cubic-bezier.d.ts.map +1 -0
- package/dist/easing/cubic-bezier.js +54 -0
- package/dist/easing/cubic-bezier.js.map +7 -0
- package/dist/easing/linear-css.d.ts +9 -0
- package/dist/easing/linear-css.d.ts.map +1 -0
- package/dist/easing/linear-css.js +30 -0
- package/dist/easing/linear-css.js.map +7 -0
- package/dist/easing/named.d.ts +16 -0
- package/dist/easing/named.d.ts.map +1 -0
- package/dist/easing/named.js +82 -0
- package/dist/easing/named.js.map +7 -0
- package/dist/easing/spring.d.ts +11 -0
- package/dist/easing/spring.d.ts.map +1 -0
- package/dist/easing/spring.js +18 -0
- package/dist/easing/spring.js.map +7 -0
- package/dist/easing/steps.d.ts +4 -0
- package/dist/easing/steps.d.ts.map +1 -0
- package/dist/easing/steps.js +14 -0
- package/dist/easing/steps.js.map +7 -0
- package/dist/easing/types.d.ts +5 -0
- package/dist/easing/types.d.ts.map +1 -0
- package/dist/easing/types.js +1 -0
- package/dist/easing/types.js.map +7 -0
- package/dist/frame/driver.d.ts +13 -0
- package/dist/frame/driver.d.ts.map +1 -0
- package/dist/frame/driver.js +42 -0
- package/dist/frame/driver.js.map +7 -0
- package/dist/frame/frame.d.ts +20 -0
- package/dist/frame/frame.d.ts.map +1 -0
- package/dist/frame/frame.js +77 -0
- package/dist/frame/frame.js.map +7 -0
- package/dist/generators/inertia.d.ts +20 -0
- package/dist/generators/inertia.d.ts.map +1 -0
- package/dist/generators/inertia.js +59 -0
- package/dist/generators/inertia.js.map +7 -0
- package/dist/generators/spring.d.ts +17 -0
- package/dist/generators/spring.d.ts.map +1 -0
- package/dist/generators/spring.js +87 -0
- package/dist/generators/spring.js.map +7 -0
- package/dist/generators/tween.d.ts +15 -0
- package/dist/generators/tween.d.ts.map +1 -0
- package/dist/generators/tween.js +51 -0
- package/dist/generators/tween.js.map +7 -0
- package/dist/generators/types.d.ts +30 -0
- package/dist/generators/types.d.ts.map +1 -0
- package/dist/generators/types.js +1 -0
- package/dist/generators/types.js.map +7 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +7 -0
- package/dist/interpolate/array.d.ts +3 -0
- package/dist/interpolate/array.d.ts.map +1 -0
- package/dist/interpolate/array.js +12 -0
- package/dist/interpolate/array.js.map +7 -0
- package/dist/interpolate/color-parse.d.ts +14 -0
- package/dist/interpolate/color-parse.d.ts.map +1 -0
- package/dist/interpolate/color-parse.js +111 -0
- package/dist/interpolate/color-parse.js.map +7 -0
- package/dist/interpolate/color.d.ts +11 -0
- package/dist/interpolate/color.d.ts.map +1 -0
- package/dist/interpolate/color.js +74 -0
- package/dist/interpolate/color.js.map +7 -0
- package/dist/interpolate/complex.d.ts +7 -0
- package/dist/interpolate/complex.d.ts.map +1 -0
- package/dist/interpolate/complex.js +56 -0
- package/dist/interpolate/complex.js.map +7 -0
- package/dist/interpolate/interpolate.d.ts +16 -0
- package/dist/interpolate/interpolate.d.ts.map +1 -0
- package/dist/interpolate/interpolate.js +39 -0
- package/dist/interpolate/interpolate.js.map +7 -0
- package/dist/interpolate/mix.d.ts +8 -0
- package/dist/interpolate/mix.d.ts.map +1 -0
- package/dist/interpolate/mix.js +48 -0
- package/dist/interpolate/mix.js.map +7 -0
- package/dist/interpolate/number.d.ts +2 -0
- package/dist/interpolate/number.d.ts.map +1 -0
- package/dist/interpolate/number.js +7 -0
- package/dist/interpolate/number.js.map +7 -0
- package/dist/interpolate/object.d.ts +5 -0
- package/dist/interpolate/object.d.ts.map +1 -0
- package/dist/interpolate/object.js +17 -0
- package/dist/interpolate/object.js.map +7 -0
- package/dist/interpolate/path/flatten.d.ts +10 -0
- package/dist/interpolate/path/flatten.d.ts.map +1 -0
- package/dist/interpolate/path/flatten.js +135 -0
- package/dist/interpolate/path/flatten.js.map +7 -0
- package/dist/interpolate/path/morph.d.ts +9 -0
- package/dist/interpolate/path/morph.d.ts.map +1 -0
- package/dist/interpolate/path/morph.js +72 -0
- package/dist/interpolate/path/morph.js.map +7 -0
- package/dist/interpolate/path/parse.d.ts +24 -0
- package/dist/interpolate/path/parse.d.ts.map +1 -0
- package/dist/interpolate/path/parse.js +125 -0
- package/dist/interpolate/path/parse.js.map +7 -0
- package/dist/interpolate/path/rings.d.ts +13 -0
- package/dist/interpolate/path/rings.d.ts.map +1 -0
- package/dist/interpolate/path/rings.js +117 -0
- package/dist/interpolate/path/rings.js.map +7 -0
- package/dist/react/index.d.ts +7 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +19 -0
- package/dist/react/index.js.map +7 -0
- package/dist/react/presence.d.ts +27 -0
- package/dist/react/presence.d.ts.map +1 -0
- package/dist/react/presence.js +135 -0
- package/dist/react/presence.js.map +7 -0
- package/dist/react/use-animate.d.ts +17 -0
- package/dist/react/use-animate.d.ts.map +1 -0
- package/dist/react/use-animate.js +34 -0
- package/dist/react/use-animate.js.map +7 -0
- package/dist/react/use-motion-value.d.ts +4 -0
- package/dist/react/use-motion-value.d.ts.map +1 -0
- package/dist/react/use-motion-value.js +11 -0
- package/dist/react/use-motion-value.js.map +7 -0
- package/dist/react/use-reduced-motion.d.ts +7 -0
- package/dist/react/use-reduced-motion.d.ts.map +1 -0
- package/dist/react/use-reduced-motion.js +19 -0
- package/dist/react/use-reduced-motion.js.map +7 -0
- package/dist/react/use-spring.d.ts +9 -0
- package/dist/react/use-spring.d.ts.map +1 -0
- package/dist/react/use-spring.js +27 -0
- package/dist/react/use-spring.js.map +7 -0
- package/dist/react/use-transform.d.ts +13 -0
- package/dist/react/use-transform.d.ts.map +1 -0
- package/dist/react/use-transform.js +44 -0
- package/dist/react/use-transform.js.map +7 -0
- package/dist/sequence/sequence.d.ts +25 -0
- package/dist/sequence/sequence.d.ts.map +1 -0
- package/dist/sequence/sequence.js +68 -0
- package/dist/sequence/sequence.js.map +7 -0
- package/dist/stagger/stagger.d.ts +12 -0
- package/dist/stagger/stagger.d.ts.map +1 -0
- package/dist/stagger/stagger.js +21 -0
- package/dist/stagger/stagger.js.map +7 -0
- package/dist/testing/manual-frames.d.ts +11 -0
- package/dist/testing/manual-frames.d.ts.map +1 -0
- package/dist/testing/manual-frames.js +40 -0
- package/dist/testing/manual-frames.js.map +7 -0
- package/dist/value/motion-value.d.ts +27 -0
- package/dist/value/motion-value.d.ts.map +1 -0
- package/dist/value/motion-value.js +88 -0
- package/dist/value/motion-value.js.map +7 -0
- package/dist/value/transform.d.ts +16 -0
- package/dist/value/transform.d.ts.map +1 -0
- package/dist/value/transform.js +28 -0
- package/dist/value/transform.js.map +7 -0
- package/dist/view/in-view.d.ts +19 -0
- package/dist/view/in-view.d.ts.map +1 -0
- package/dist/view/in-view.js +46 -0
- package/dist/view/in-view.js.map +7 -0
- package/dist/view/resize.d.ts +13 -0
- package/dist/view/resize.d.ts.map +1 -0
- package/dist/view/resize.js +72 -0
- package/dist/view/resize.js.map +7 -0
- package/dist/view/resolve-elements.d.ts +3 -0
- package/dist/view/resolve-elements.d.ts.map +1 -0
- package/dist/view/resolve-elements.js +10 -0
- package/dist/view/resolve-elements.js.map +7 -0
- package/dist/view/scroll-measure.d.ts +16 -0
- package/dist/view/scroll-measure.d.ts.map +1 -0
- package/dist/view/scroll-measure.js +51 -0
- package/dist/view/scroll-measure.js.map +7 -0
- package/dist/view/scroll-offset.d.ts +28 -0
- package/dist/view/scroll-offset.d.ts.map +1 -0
- package/dist/view/scroll-offset.js +55 -0
- package/dist/view/scroll-offset.js.map +7 -0
- package/dist/view/scroll.d.ts +34 -0
- package/dist/view/scroll.d.ts.map +1 -0
- package/dist/view/scroll.js +83 -0
- package/dist/view/scroll.js.map +7 -0
- package/package.json +57 -5
- package/src/accessibility/reduced-motion.ts +75 -0
- package/src/animate/animate.ts +155 -0
- package/src/animate/controls.ts +76 -0
- package/src/animate/dom.ts +166 -0
- package/src/animate/js-animation.ts +151 -0
- package/src/animate/plan.ts +74 -0
- package/src/animate/style.ts +131 -0
- package/src/animate/types.ts +69 -0
- package/src/animate/value.ts +93 -0
- package/src/animate/waapi.ts +212 -0
- package/src/dom.ts +35 -0
- package/src/easing/cubic-bezier.ts +64 -0
- package/src/easing/linear-css.ts +41 -0
- package/src/easing/named.ts +88 -0
- package/src/easing/spring.ts +25 -0
- package/src/easing/steps.ts +16 -0
- package/src/easing/types.ts +18 -0
- package/src/frame/driver.ts +56 -0
- package/src/frame/frame.ts +102 -0
- package/src/generators/inertia.ts +88 -0
- package/src/generators/spring.ts +117 -0
- package/src/generators/tween.ts +74 -0
- package/src/generators/types.ts +31 -0
- package/src/index.ts +91 -0
- package/src/interpolate/array.ts +13 -0
- package/src/interpolate/color-parse.ts +136 -0
- package/src/interpolate/color.ts +97 -0
- package/src/interpolate/complex.ts +80 -0
- package/src/interpolate/interpolate.ts +60 -0
- package/src/interpolate/mix.ts +74 -0
- package/src/interpolate/number.ts +3 -0
- package/src/interpolate/object.ts +20 -0
- package/src/interpolate/path/flatten.ts +185 -0
- package/src/interpolate/path/morph.ts +100 -0
- package/src/interpolate/path/parse.ts +162 -0
- package/src/interpolate/path/rings.ts +151 -0
- package/src/react/index.ts +11 -0
- package/src/react/presence.tsx +194 -0
- package/src/react/use-animate.ts +46 -0
- package/src/react/use-motion-value.ts +9 -0
- package/src/react/use-reduced-motion.ts +22 -0
- package/src/react/use-spring.ts +35 -0
- package/src/react/use-transform.ts +73 -0
- package/src/sequence/sequence.ts +129 -0
- package/src/stagger/stagger.ts +36 -0
- package/src/testing/browser-commands.d.ts +11 -0
- package/src/testing/manual-frames.ts +49 -0
- package/src/value/motion-value.ts +131 -0
- package/src/value/transform.ts +61 -0
- package/src/view/in-view.ts +74 -0
- package/src/view/resize.ts +101 -0
- package/src/view/resolve-elements.ts +11 -0
- package/src/view/scroll-measure.ts +83 -0
- package/src/view/scroll-offset.ts +100 -0
- package/src/view/scroll.ts +143 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { thenable } from "./controls.js";
|
|
2
|
+
import { iterationTime, planGenerator, totalDuration } from "./plan.js";
|
|
3
|
+
import { cancelFrame, frame, now } from "../frame/frame.js";
|
|
4
|
+
import { mix } from "../interpolate/mix.js";
|
|
5
|
+
function jsAnimation(config) {
|
|
6
|
+
const { keyframes, options, delay, apply } = config;
|
|
7
|
+
const { generator, positional } = planGenerator(
|
|
8
|
+
keyframes,
|
|
9
|
+
options,
|
|
10
|
+
config.velocity
|
|
11
|
+
);
|
|
12
|
+
const segments = positional ? keyframes.slice(1).map((to, index) => mix(keyframes[index], to)) : [];
|
|
13
|
+
const active = totalDuration(generator.duration, options);
|
|
14
|
+
const duration = delay + active;
|
|
15
|
+
const endsReversed = options.repeatType === "reverse" && (options.repeat ?? 0) % 2 === 1;
|
|
16
|
+
const last = keyframes[endsReversed ? 0 : keyframes.length - 1];
|
|
17
|
+
let time = 0;
|
|
18
|
+
let speed = 1;
|
|
19
|
+
let state = "running";
|
|
20
|
+
let previous = now();
|
|
21
|
+
let resolve = () => {
|
|
22
|
+
};
|
|
23
|
+
const finished = new Promise((done) => {
|
|
24
|
+
resolve = done;
|
|
25
|
+
});
|
|
26
|
+
function valueAt(position) {
|
|
27
|
+
if (!positional) return position;
|
|
28
|
+
const index = Math.min(
|
|
29
|
+
Math.max(Math.floor(position), 0),
|
|
30
|
+
segments.length - 1
|
|
31
|
+
);
|
|
32
|
+
return segments[index](position - index);
|
|
33
|
+
}
|
|
34
|
+
function sample() {
|
|
35
|
+
const elapsed = Math.max(0, time - delay);
|
|
36
|
+
return generator.at(iterationTime(elapsed, generator.duration, options));
|
|
37
|
+
}
|
|
38
|
+
function render() {
|
|
39
|
+
if (time < delay) return;
|
|
40
|
+
apply(time >= duration ? last : valueAt(sample().value));
|
|
41
|
+
}
|
|
42
|
+
function settle(next) {
|
|
43
|
+
state = next;
|
|
44
|
+
cancelFrame(tick);
|
|
45
|
+
resolve();
|
|
46
|
+
}
|
|
47
|
+
function tick(data) {
|
|
48
|
+
time = Math.max(0, time + (data.timestamp - previous) / 1e3 * speed);
|
|
49
|
+
previous = data.timestamp;
|
|
50
|
+
if (time < duration) {
|
|
51
|
+
render();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
time = duration;
|
|
55
|
+
render();
|
|
56
|
+
settle("finished");
|
|
57
|
+
config.onComplete?.();
|
|
58
|
+
}
|
|
59
|
+
function play() {
|
|
60
|
+
if (state === "running") return;
|
|
61
|
+
previous = now();
|
|
62
|
+
state = "running";
|
|
63
|
+
frame.update(tick, true);
|
|
64
|
+
}
|
|
65
|
+
frame.update(tick, true);
|
|
66
|
+
render();
|
|
67
|
+
return {
|
|
68
|
+
...thenable(finished),
|
|
69
|
+
get time() {
|
|
70
|
+
return time;
|
|
71
|
+
},
|
|
72
|
+
set time(seconds) {
|
|
73
|
+
time = Math.min(Math.max(seconds, 0), duration);
|
|
74
|
+
render();
|
|
75
|
+
},
|
|
76
|
+
get speed() {
|
|
77
|
+
return speed;
|
|
78
|
+
},
|
|
79
|
+
set speed(rate) {
|
|
80
|
+
speed = rate;
|
|
81
|
+
},
|
|
82
|
+
duration,
|
|
83
|
+
get state() {
|
|
84
|
+
return state;
|
|
85
|
+
},
|
|
86
|
+
play,
|
|
87
|
+
pause() {
|
|
88
|
+
if (state !== "running") return;
|
|
89
|
+
state = "paused";
|
|
90
|
+
cancelFrame(tick);
|
|
91
|
+
},
|
|
92
|
+
stop: () => settle("finished"),
|
|
93
|
+
cancel() {
|
|
94
|
+
apply(keyframes[0]);
|
|
95
|
+
settle("finished");
|
|
96
|
+
},
|
|
97
|
+
complete() {
|
|
98
|
+
if (state === "finished") return;
|
|
99
|
+
time = duration;
|
|
100
|
+
render();
|
|
101
|
+
settle("finished");
|
|
102
|
+
config.onComplete?.();
|
|
103
|
+
},
|
|
104
|
+
attachTimeline: () => false,
|
|
105
|
+
current() {
|
|
106
|
+
const { value, velocity } = sample();
|
|
107
|
+
return {
|
|
108
|
+
value: time < delay ? keyframes[0] : valueAt(value),
|
|
109
|
+
velocity: positional || time < delay ? 0 : velocity
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
jsAnimation
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=js-animation.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/animate/js-animation.ts"],
|
|
4
|
+
"sourcesContent": ["import { thenable } from \"#/animate/controls.ts\";\nimport { iterationTime, planGenerator, totalDuration } from \"#/animate/plan.ts\";\nimport type {\n\tAnimationControls,\n\tAnimationOptions,\n\tAnimationState,\n} from \"#/animate/types.ts\";\nimport { cancelFrame, type FrameData, frame, now } from \"#/frame/frame.ts\";\nimport { mix } from \"#/interpolate/mix.ts\";\n\nexport interface JsAnimationConfig<T> {\n\t/** At least two: the caller resolves a lone target against the current value. */\n\treadonly keyframes: readonly T[];\n\treadonly options: AnimationOptions;\n\t/** Seconds. */\n\treadonly delay: number;\n\t/** The velocity the value has now, carried into a spring. */\n\treadonly velocity: number;\n\tapply(value: T): void;\n\tonComplete?(): void;\n}\n\nexport interface JsAnimation<T> extends AnimationControls {\n\t/** The value and velocity at the current time: where an interruption starts from. */\n\tcurrent(): { readonly value: T; readonly velocity: number };\n}\n\n/**\n * An animation stepped by the frame loop: plain values, objects, SVG\n * attributes and CSS variables \u2014 whatever the Web Animations API can't play.\n */\nexport function jsAnimation<T>(config: JsAnimationConfig<T>): JsAnimation<T> {\n\tconst { keyframes, options, delay, apply } = config;\n\tconst { generator, positional } = planGenerator(\n\t\tkeyframes,\n\t\toptions,\n\t\tconfig.velocity,\n\t);\n\tconst segments = positional\n\t\t? keyframes.slice(1).map((to, index) => mix(keyframes[index] as T, to as T))\n\t\t: [];\n\tconst active = totalDuration(generator.duration, options);\n\tconst duration = delay + active;\n\tconst endsReversed =\n\t\toptions.repeatType === \"reverse\" && (options.repeat ?? 0) % 2 === 1;\n\tconst last = keyframes[endsReversed ? 0 : keyframes.length - 1] as T;\n\n\tlet time = 0;\n\tlet speed = 1;\n\tlet state: AnimationState = \"running\";\n\tlet previous = now();\n\tlet resolve: () => void = () => {};\n\tconst finished = new Promise<void>((done) => {\n\t\tresolve = done;\n\t});\n\n\tfunction valueAt(position: number): T {\n\t\tif (!positional) return position as T;\n\t\tconst index = Math.min(\n\t\t\tMath.max(Math.floor(position), 0),\n\t\t\tsegments.length - 1,\n\t\t);\n\t\treturn (segments[index] as (progress: number) => T)(position - index);\n\t}\n\n\tfunction sample() {\n\t\tconst elapsed = Math.max(0, time - delay);\n\t\treturn generator.at(iterationTime(elapsed, generator.duration, options));\n\t}\n\n\tfunction render() {\n\t\tif (time < delay) return;\n\t\tapply(time >= duration ? last : valueAt(sample().value));\n\t}\n\n\tfunction settle(next: AnimationState) {\n\t\tstate = next;\n\t\tcancelFrame(tick);\n\t\tresolve();\n\t}\n\n\tfunction tick(data: FrameData) {\n\t\ttime = Math.max(0, time + ((data.timestamp - previous) / 1000) * speed);\n\t\tprevious = data.timestamp;\n\t\tif (time < duration) {\n\t\t\trender();\n\t\t\treturn;\n\t\t}\n\t\ttime = duration;\n\t\trender();\n\t\tsettle(\"finished\");\n\t\tconfig.onComplete?.();\n\t}\n\n\tfunction play() {\n\t\tif (state === \"running\") return;\n\t\tprevious = now();\n\t\tstate = \"running\";\n\t\tframe.update(tick, true);\n\t}\n\n\tframe.update(tick, true);\n\trender();\n\n\treturn {\n\t\t...thenable(finished),\n\t\tget time() {\n\t\t\treturn time;\n\t\t},\n\t\tset time(seconds) {\n\t\t\ttime = Math.min(Math.max(seconds, 0), duration);\n\t\t\trender();\n\t\t},\n\t\tget speed() {\n\t\t\treturn speed;\n\t\t},\n\t\tset speed(rate) {\n\t\t\tspeed = rate;\n\t\t},\n\t\tduration,\n\t\tget state() {\n\t\t\treturn state;\n\t\t},\n\t\tplay,\n\t\tpause() {\n\t\t\tif (state !== \"running\") return;\n\t\t\tstate = \"paused\";\n\t\t\tcancelFrame(tick);\n\t\t},\n\t\tstop: () => settle(\"finished\"),\n\t\tcancel() {\n\t\t\tapply(keyframes[0] as T);\n\t\t\tsettle(\"finished\");\n\t\t},\n\t\tcomplete() {\n\t\t\tif (state === \"finished\") return;\n\t\t\ttime = duration;\n\t\t\trender();\n\t\t\tsettle(\"finished\");\n\t\t\tconfig.onComplete?.();\n\t\t},\n\t\tattachTimeline: () => false,\n\t\tcurrent() {\n\t\t\tconst { value, velocity } = sample();\n\t\t\treturn {\n\t\t\t\tvalue: time < delay ? (keyframes[0] as T) : valueAt(value),\n\t\t\t\tvelocity: positional || time < delay ? 0 : velocity,\n\t\t\t};\n\t\t},\n\t};\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { AnimationOptions } from "./types.js";
|
|
2
|
+
import type { Generator } from "../generators/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* The motion of one channel, as a generator. Two numbers spring in their own
|
|
5
|
+
* units, so the velocity a value already has carries into the new motion.
|
|
6
|
+
* Anything else (colours, paths, several keyframes) moves a position along
|
|
7
|
+
* the keyframe list — 0 at the first, 1 at the second… — and the caller mixes
|
|
8
|
+
* the keyframes at that position.
|
|
9
|
+
*/
|
|
10
|
+
export declare function planGenerator(keyframes: readonly unknown[], options: AnimationOptions, velocity?: number): {
|
|
11
|
+
readonly generator: Generator;
|
|
12
|
+
readonly positional: boolean;
|
|
13
|
+
};
|
|
14
|
+
/** The elapsed time within the current repetition, playing backwards on odd ones when they reverse. */
|
|
15
|
+
export declare function iterationTime(elapsed: number, duration: number, options: AnimationOptions): number;
|
|
16
|
+
export declare function totalDuration(duration: number, options: AnimationOptions): number;
|
|
17
|
+
//# sourceMappingURL=plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/animate/plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC5B,SAAS,EAAE,SAAS,OAAO,EAAE,EAC7B,OAAO,EAAE,gBAAgB,EACzB,QAAQ,SAAI,GACV;IAAE,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CA+BjE;AAED,uGAAuG;AACvG,wBAAgB,aAAa,CAC5B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACvB,MAAM,CAUR;AAED,wBAAgB,aAAa,CAC5B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACvB,MAAM,CAER"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { spring } from "../generators/spring.js";
|
|
2
|
+
import { tween } from "../generators/tween.js";
|
|
3
|
+
const DEFAULT_TWEEN_DURATION = 0.3;
|
|
4
|
+
function planGenerator(keyframes, options, velocity = 0) {
|
|
5
|
+
const numeric = keyframes.every((frame) => typeof frame === "number");
|
|
6
|
+
const springs = options.type !== "tween" && keyframes.length === 2 && !options.ease;
|
|
7
|
+
if (numeric) {
|
|
8
|
+
const values = keyframes;
|
|
9
|
+
const generator2 = springs ? spring({
|
|
10
|
+
...options,
|
|
11
|
+
from: values[0] ?? 0,
|
|
12
|
+
to: values[1] ?? 0,
|
|
13
|
+
velocity: options.velocity ?? velocity
|
|
14
|
+
}) : tween({
|
|
15
|
+
keyframes: values,
|
|
16
|
+
duration: options.duration ?? DEFAULT_TWEEN_DURATION,
|
|
17
|
+
ease: options.ease,
|
|
18
|
+
times: options.times
|
|
19
|
+
});
|
|
20
|
+
return { generator: generator2, positional: false };
|
|
21
|
+
}
|
|
22
|
+
const positions = keyframes.map((_frame, index) => index);
|
|
23
|
+
const generator = springs ? spring({ ...options, from: 0, to: 1 }) : tween({
|
|
24
|
+
keyframes: positions,
|
|
25
|
+
duration: options.duration ?? DEFAULT_TWEEN_DURATION,
|
|
26
|
+
ease: options.ease,
|
|
27
|
+
times: options.times
|
|
28
|
+
});
|
|
29
|
+
return { generator, positional: true };
|
|
30
|
+
}
|
|
31
|
+
function iterationTime(elapsed, duration, options) {
|
|
32
|
+
const repeat = options.repeat ?? 0;
|
|
33
|
+
if (repeat === 0 || duration === 0) return Math.min(elapsed, duration);
|
|
34
|
+
const total = duration * (repeat + 1);
|
|
35
|
+
const clamped = Math.min(elapsed, total);
|
|
36
|
+
const iteration = Math.min(Math.floor(clamped / duration), repeat);
|
|
37
|
+
const within = clamped - iteration * duration;
|
|
38
|
+
return options.repeatType === "reverse" && iteration % 2 === 1 ? duration - within : within;
|
|
39
|
+
}
|
|
40
|
+
function totalDuration(duration, options) {
|
|
41
|
+
return duration * ((options.repeat ?? 0) + 1);
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
iterationTime,
|
|
45
|
+
planGenerator,
|
|
46
|
+
totalDuration
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/animate/plan.ts"],
|
|
4
|
+
"sourcesContent": ["import type { AnimationOptions } from \"#/animate/types.ts\";\nimport { spring } from \"#/generators/spring.ts\";\nimport { tween } from \"#/generators/tween.ts\";\nimport type { Generator } from \"#/generators/types.ts\";\n\nconst DEFAULT_TWEEN_DURATION = 0.3;\n\n/**\n * The motion of one channel, as a generator. Two numbers spring in their own\n * units, so the velocity a value already has carries into the new motion.\n * Anything else (colours, paths, several keyframes) moves a position along\n * the keyframe list \u2014 0 at the first, 1 at the second\u2026 \u2014 and the caller mixes\n * the keyframes at that position.\n */\nexport function planGenerator(\n\tkeyframes: readonly unknown[],\n\toptions: AnimationOptions,\n\tvelocity = 0,\n): { readonly generator: Generator; readonly positional: boolean } {\n\tconst numeric = keyframes.every((frame) => typeof frame === \"number\");\n\tconst springs =\n\t\toptions.type !== \"tween\" && keyframes.length === 2 && !options.ease;\n\tif (numeric) {\n\t\tconst values = keyframes as readonly number[];\n\t\tconst generator = springs\n\t\t\t? spring({\n\t\t\t\t\t...options,\n\t\t\t\t\tfrom: values[0] ?? 0,\n\t\t\t\t\tto: values[1] ?? 0,\n\t\t\t\t\tvelocity: options.velocity ?? velocity,\n\t\t\t\t})\n\t\t\t: tween({\n\t\t\t\t\tkeyframes: values,\n\t\t\t\t\tduration: options.duration ?? DEFAULT_TWEEN_DURATION,\n\t\t\t\t\tease: options.ease,\n\t\t\t\t\ttimes: options.times,\n\t\t\t\t});\n\t\treturn { generator, positional: false };\n\t}\n\tconst positions = keyframes.map((_frame, index) => index);\n\tconst generator = springs\n\t\t? spring({ ...options, from: 0, to: 1 })\n\t\t: tween({\n\t\t\t\tkeyframes: positions,\n\t\t\t\tduration: options.duration ?? DEFAULT_TWEEN_DURATION,\n\t\t\t\tease: options.ease,\n\t\t\t\ttimes: options.times,\n\t\t\t});\n\treturn { generator, positional: true };\n}\n\n/** The elapsed time within the current repetition, playing backwards on odd ones when they reverse. */\nexport function iterationTime(\n\telapsed: number,\n\tduration: number,\n\toptions: AnimationOptions,\n): number {\n\tconst repeat = options.repeat ?? 0;\n\tif (repeat === 0 || duration === 0) return Math.min(elapsed, duration);\n\tconst total = duration * (repeat + 1);\n\tconst clamped = Math.min(elapsed, total);\n\tconst iteration = Math.min(Math.floor(clamped / duration), repeat);\n\tconst within = clamped - iteration * duration;\n\treturn options.repeatType === \"reverse\" && iteration % 2 === 1\n\t\t? duration - within\n\t\t: within;\n}\n\nexport function totalDuration(\n\tduration: number,\n\toptions: AnimationOptions,\n): number {\n\treturn duration * ((options.repeat ?? 0) + 1);\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,cAAc;AACvB,SAAS,aAAa;AAGtB,MAAM,yBAAyB;AASxB,SAAS,cACf,WACA,SACA,WAAW,GACuD;AAClE,QAAM,UAAU,UAAU,MAAM,CAAC,UAAU,OAAO,UAAU,QAAQ;AACpE,QAAM,UACL,QAAQ,SAAS,WAAW,UAAU,WAAW,KAAK,CAAC,QAAQ;AAChE,MAAI,SAAS;AACZ,UAAM,SAAS;AACf,UAAMA,aAAY,UACf,OAAO;AAAA,MACP,GAAG;AAAA,MACH,MAAM,OAAO,CAAC,KAAK;AAAA,MACnB,IAAI,OAAO,CAAC,KAAK;AAAA,MACjB,UAAU,QAAQ,YAAY;AAAA,IAC/B,CAAC,IACA,MAAM;AAAA,MACN,WAAW;AAAA,MACX,UAAU,QAAQ,YAAY;AAAA,MAC9B,MAAM,QAAQ;AAAA,MACd,OAAO,QAAQ;AAAA,IAChB,CAAC;AACH,WAAO,EAAE,WAAAA,YAAW,YAAY,MAAM;AAAA,EACvC;AACA,QAAM,YAAY,UAAU,IAAI,CAAC,QAAQ,UAAU,KAAK;AACxD,QAAM,YAAY,UACf,OAAO,EAAE,GAAG,SAAS,MAAM,GAAG,IAAI,EAAE,CAAC,IACrC,MAAM;AAAA,IACN,WAAW;AAAA,IACX,UAAU,QAAQ,YAAY;AAAA,IAC9B,MAAM,QAAQ;AAAA,IACd,OAAO,QAAQ;AAAA,EAChB,CAAC;AACH,SAAO,EAAE,WAAW,YAAY,KAAK;AACtC;AAGO,SAAS,cACf,SACA,UACA,SACS;AACT,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,WAAW,KAAK,aAAa,EAAG,QAAO,KAAK,IAAI,SAAS,QAAQ;AACrE,QAAM,QAAQ,YAAY,SAAS;AACnC,QAAM,UAAU,KAAK,IAAI,SAAS,KAAK;AACvC,QAAM,YAAY,KAAK,IAAI,KAAK,MAAM,UAAU,QAAQ,GAAG,MAAM;AACjE,QAAM,SAAS,UAAU,YAAY;AACrC,SAAO,QAAQ,eAAe,aAAa,YAAY,MAAM,IAC1D,WAAW,SACX;AACJ;AAEO,SAAS,cACf,UACA,SACS;AACT,SAAO,aAAa,QAAQ,UAAU,KAAK;AAC5C;",
|
|
6
|
+
"names": ["generator"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { KeyframeValue } from "./types.js";
|
|
2
|
+
type TransformProperty = "translate" | "scale" | "rotate";
|
|
3
|
+
interface TransformChannel {
|
|
4
|
+
readonly property: TransformProperty;
|
|
5
|
+
readonly unit: string;
|
|
6
|
+
readonly identity: number;
|
|
7
|
+
/** The channel alone as a value of its property, the other axes at identity. */
|
|
8
|
+
readonly alone: (value: string) => string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The independent transforms. Each animates its CSS property alone with
|
|
12
|
+
* `composite: "add"`, so `x` and `y` run as two compositor animations that
|
|
13
|
+
* sum, and one can be interrupted without touching the other.
|
|
14
|
+
*/
|
|
15
|
+
export declare const TRANSFORMS: Readonly<Record<string, TransformChannel>>;
|
|
16
|
+
/** A keyframe as CSS: numbers take the property's unit. */
|
|
17
|
+
export declare function withUnit(key: string, value: KeyframeValue): string;
|
|
18
|
+
export declare function committedTransform(element: Element, key: string): number;
|
|
19
|
+
/** Writes the committed transforms inline, with every animating channel at its identity. */
|
|
20
|
+
export declare function writeTransforms(element: Element): void;
|
|
21
|
+
export declare function beginTransform(element: Element, key: string): void;
|
|
22
|
+
export declare function commitTransform(element: Element, key: string, value: KeyframeValue): void;
|
|
23
|
+
export declare function cssName(key: string): string;
|
|
24
|
+
/** Moves things on screen, as opposed to fading or tinting them: what reduced motion turns off. */
|
|
25
|
+
export declare function isMovement(key: string): boolean;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=style.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/animate/style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,KAAK,iBAAiB,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1D,UAAU,gBAAgB;IACzB,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAuBjE,CAAC;AAiBF,2DAA2D;AAC3D,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,CAMlE;AAkBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAKxE;AASD,4FAA4F;AAC5F,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,QAO/C;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,QAG3D;AAED,wBAAgB,eAAe,CAC9B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,aAAa,QAKpB;AAED,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI3C;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE/C"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
const TRANSFORMS = {
|
|
2
|
+
x: { property: "translate", unit: "px", identity: 0, alone: (v) => `${v}` },
|
|
3
|
+
y: {
|
|
4
|
+
property: "translate",
|
|
5
|
+
unit: "px",
|
|
6
|
+
identity: 0,
|
|
7
|
+
alone: (v) => `0px ${v}`
|
|
8
|
+
},
|
|
9
|
+
z: {
|
|
10
|
+
property: "translate",
|
|
11
|
+
unit: "px",
|
|
12
|
+
identity: 0,
|
|
13
|
+
alone: (v) => `0px 0px ${v}`
|
|
14
|
+
},
|
|
15
|
+
scale: { property: "scale", unit: "", identity: 1, alone: (v) => `${v}` },
|
|
16
|
+
scaleX: { property: "scale", unit: "", identity: 1, alone: (v) => `${v} 1` },
|
|
17
|
+
scaleY: { property: "scale", unit: "", identity: 1, alone: (v) => `1 ${v}` },
|
|
18
|
+
rotate: {
|
|
19
|
+
property: "rotate",
|
|
20
|
+
unit: "deg",
|
|
21
|
+
identity: 0,
|
|
22
|
+
alone: (v) => `${v}`
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const UNITLESS = /* @__PURE__ */ new Set([
|
|
26
|
+
"opacity",
|
|
27
|
+
"zIndex",
|
|
28
|
+
"fontWeight",
|
|
29
|
+
"lineHeight",
|
|
30
|
+
"flexGrow",
|
|
31
|
+
"flexShrink",
|
|
32
|
+
"order",
|
|
33
|
+
"fillOpacity",
|
|
34
|
+
"strokeOpacity",
|
|
35
|
+
"strokeMiterlimit",
|
|
36
|
+
"aspectRatio",
|
|
37
|
+
"pathLength"
|
|
38
|
+
]);
|
|
39
|
+
function withUnit(key, value) {
|
|
40
|
+
if (typeof value === "string") return value;
|
|
41
|
+
const unit = TRANSFORMS[key]?.unit ?? (UNITLESS.has(key) || key.startsWith("--") ? "" : "px");
|
|
42
|
+
return `${value}${unit}`;
|
|
43
|
+
}
|
|
44
|
+
const committed = /* @__PURE__ */ new WeakMap();
|
|
45
|
+
const animating = /* @__PURE__ */ new WeakMap();
|
|
46
|
+
function entries(map, element, fresh) {
|
|
47
|
+
const existing = map.get(element);
|
|
48
|
+
if (existing) return existing;
|
|
49
|
+
const created = fresh();
|
|
50
|
+
map.set(element, created);
|
|
51
|
+
return created;
|
|
52
|
+
}
|
|
53
|
+
function committedTransform(element, key) {
|
|
54
|
+
const value = committed.get(element)?.get(key);
|
|
55
|
+
return typeof value === "number" ? value : Number.parseFloat(value ?? "") || (TRANSFORMS[key]?.identity ?? 0);
|
|
56
|
+
}
|
|
57
|
+
function channel(element, key) {
|
|
58
|
+
const channelDef = TRANSFORMS[key];
|
|
59
|
+
if (animating.get(element)?.has(key))
|
|
60
|
+
return `${channelDef.identity}${channelDef.unit}`;
|
|
61
|
+
return withUnit(key, committed.get(element)?.get(key) ?? channelDef.identity);
|
|
62
|
+
}
|
|
63
|
+
function writeTransforms(element) {
|
|
64
|
+
const style = element.style;
|
|
65
|
+
const at = (key) => channel(element, key);
|
|
66
|
+
style.translate = `${at("x")} ${at("y")} ${at("z")}`;
|
|
67
|
+
const uniform = Number.parseFloat(at("scale"));
|
|
68
|
+
style.scale = `${uniform * Number.parseFloat(at("scaleX"))} ${uniform * Number.parseFloat(at("scaleY"))}`;
|
|
69
|
+
style.rotate = at("rotate");
|
|
70
|
+
}
|
|
71
|
+
function beginTransform(element, key) {
|
|
72
|
+
entries(animating, element, () => /* @__PURE__ */ new Set()).add(key);
|
|
73
|
+
writeTransforms(element);
|
|
74
|
+
}
|
|
75
|
+
function commitTransform(element, key, value) {
|
|
76
|
+
entries(committed, element, () => /* @__PURE__ */ new Map()).set(key, value);
|
|
77
|
+
animating.get(element)?.delete(key);
|
|
78
|
+
writeTransforms(element);
|
|
79
|
+
}
|
|
80
|
+
function cssName(key) {
|
|
81
|
+
return key.startsWith("--") ? key : key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);
|
|
82
|
+
}
|
|
83
|
+
function isMovement(key) {
|
|
84
|
+
return !/opacity|color|fill|stroke$|filter/i.test(key);
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
TRANSFORMS,
|
|
88
|
+
beginTransform,
|
|
89
|
+
commitTransform,
|
|
90
|
+
committedTransform,
|
|
91
|
+
cssName,
|
|
92
|
+
isMovement,
|
|
93
|
+
withUnit,
|
|
94
|
+
writeTransforms
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=style.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/animate/style.ts"],
|
|
4
|
+
"sourcesContent": ["import type { KeyframeValue } from \"#/animate/types.ts\";\n\ntype TransformProperty = \"translate\" | \"scale\" | \"rotate\";\n\ninterface TransformChannel {\n\treadonly property: TransformProperty;\n\treadonly unit: string;\n\treadonly identity: number;\n\t/** The channel alone as a value of its property, the other axes at identity. */\n\treadonly alone: (value: string) => string;\n}\n\n/**\n * The independent transforms. Each animates its CSS property alone with\n * `composite: \"add\"`, so `x` and `y` run as two compositor animations that\n * sum, and one can be interrupted without touching the other.\n */\nexport const TRANSFORMS: Readonly<Record<string, TransformChannel>> = {\n\tx: { property: \"translate\", unit: \"px\", identity: 0, alone: (v) => `${v}` },\n\ty: {\n\t\tproperty: \"translate\",\n\t\tunit: \"px\",\n\t\tidentity: 0,\n\t\talone: (v) => `0px ${v}`,\n\t},\n\tz: {\n\t\tproperty: \"translate\",\n\t\tunit: \"px\",\n\t\tidentity: 0,\n\t\talone: (v) => `0px 0px ${v}`,\n\t},\n\tscale: { property: \"scale\", unit: \"\", identity: 1, alone: (v) => `${v}` },\n\tscaleX: { property: \"scale\", unit: \"\", identity: 1, alone: (v) => `${v} 1` },\n\tscaleY: { property: \"scale\", unit: \"\", identity: 1, alone: (v) => `1 ${v}` },\n\trotate: {\n\t\tproperty: \"rotate\",\n\t\tunit: \"deg\",\n\t\tidentity: 0,\n\t\talone: (v) => `${v}`,\n\t},\n};\n\nconst UNITLESS = new Set([\n\t\"opacity\",\n\t\"zIndex\",\n\t\"fontWeight\",\n\t\"lineHeight\",\n\t\"flexGrow\",\n\t\"flexShrink\",\n\t\"order\",\n\t\"fillOpacity\",\n\t\"strokeOpacity\",\n\t\"strokeMiterlimit\",\n\t\"aspectRatio\",\n\t\"pathLength\",\n]);\n\n/** A keyframe as CSS: numbers take the property's unit. */\nexport function withUnit(key: string, value: KeyframeValue): string {\n\tif (typeof value === \"string\") return value;\n\tconst unit =\n\t\tTRANSFORMS[key]?.unit ??\n\t\t(UNITLESS.has(key) || key.startsWith(\"--\") ? \"\" : \"px\");\n\treturn `${value}${unit}`;\n}\n\n/** Committed transform values per element, the ones no animation is driving. */\nconst committed = new WeakMap<Element, Map<string, KeyframeValue>>();\nconst animating = new WeakMap<Element, Set<string>>();\n\nfunction entries<T>(\n\tmap: WeakMap<Element, T>,\n\telement: Element,\n\tfresh: () => T,\n) {\n\tconst existing = map.get(element);\n\tif (existing) return existing;\n\tconst created = fresh();\n\tmap.set(element, created);\n\treturn created;\n}\n\nexport function committedTransform(element: Element, key: string): number {\n\tconst value = committed.get(element)?.get(key);\n\treturn typeof value === \"number\"\n\t\t? value\n\t\t: Number.parseFloat(value ?? \"\") || (TRANSFORMS[key]?.identity ?? 0);\n}\n\nfunction channel(element: Element, key: string): string {\n\tconst channelDef = TRANSFORMS[key] as TransformChannel;\n\tif (animating.get(element)?.has(key))\n\t\treturn `${channelDef.identity}${channelDef.unit}`;\n\treturn withUnit(key, committed.get(element)?.get(key) ?? channelDef.identity);\n}\n\n/** Writes the committed transforms inline, with every animating channel at its identity. */\nexport function writeTransforms(element: Element) {\n\tconst style = (element as HTMLElement).style;\n\tconst at = (key: string) => channel(element, key);\n\tstyle.translate = `${at(\"x\")} ${at(\"y\")} ${at(\"z\")}`;\n\tconst uniform = Number.parseFloat(at(\"scale\"));\n\tstyle.scale = `${uniform * Number.parseFloat(at(\"scaleX\"))} ${uniform * Number.parseFloat(at(\"scaleY\"))}`;\n\tstyle.rotate = at(\"rotate\");\n}\n\nexport function beginTransform(element: Element, key: string) {\n\tentries(animating, element, () => new Set()).add(key);\n\twriteTransforms(element);\n}\n\nexport function commitTransform(\n\telement: Element,\n\tkey: string,\n\tvalue: KeyframeValue,\n) {\n\tentries(committed, element, () => new Map()).set(key, value);\n\tanimating.get(element)?.delete(key);\n\twriteTransforms(element);\n}\n\nexport function cssName(key: string): string {\n\treturn key.startsWith(\"--\")\n\t\t? key\n\t\t: key.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n\n/** Moves things on screen, as opposed to fading or tinting them: what reduced motion turns off. */\nexport function isMovement(key: string): boolean {\n\treturn !/opacity|color|fill|stroke$|filter/i.test(key);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ReducedMotionPolicy } from "../accessibility/reduced-motion.js";
|
|
2
|
+
import type { EasingDefinition } from "../easing/types.js";
|
|
3
|
+
import type { SpringOptions } from "../generators/types.js";
|
|
4
|
+
export type Delay = number | ((index: number, total: number) => number);
|
|
5
|
+
export interface AnimationOptions extends SpringOptions {
|
|
6
|
+
/**
|
|
7
|
+
* "spring" by default for two numeric keyframes, "tween" otherwise. A tween
|
|
8
|
+
* lasts `duration` seconds (0.3 by default); a spring's `duration` is its
|
|
9
|
+
* perceived duration.
|
|
10
|
+
*/
|
|
11
|
+
readonly type?: "spring" | "tween";
|
|
12
|
+
readonly delay?: Delay;
|
|
13
|
+
readonly ease?: EasingDefinition | readonly EasingDefinition[];
|
|
14
|
+
/** Where each keyframe sits, 0 to 1, for a tween over several keyframes. */
|
|
15
|
+
readonly times?: readonly number[];
|
|
16
|
+
readonly repeat?: number;
|
|
17
|
+
readonly repeatType?: "loop" | "reverse";
|
|
18
|
+
/** Units per second, for a spring. Defaults to the velocity the value already has. */
|
|
19
|
+
readonly velocity?: number;
|
|
20
|
+
/** Overrides the global policy for this animation. */
|
|
21
|
+
readonly reducedMotion?: ReducedMotionPolicy;
|
|
22
|
+
}
|
|
23
|
+
export interface ValueAnimationOptions<T> extends AnimationOptions {
|
|
24
|
+
readonly onUpdate?: (value: T) => void;
|
|
25
|
+
readonly onComplete?: () => void;
|
|
26
|
+
}
|
|
27
|
+
export type AnimationState = "running" | "paused" | "finished";
|
|
28
|
+
/**
|
|
29
|
+
* What every `animate` call returns, whatever drives it. Awaitable: it
|
|
30
|
+
* resolves when the animation finishes, is stopped or is cancelled.
|
|
31
|
+
*/
|
|
32
|
+
export interface AnimationControls extends PromiseLike<void> {
|
|
33
|
+
readonly finished: Promise<void>;
|
|
34
|
+
/** Seconds since the start, delay included. Settable to scrub. */
|
|
35
|
+
time: number;
|
|
36
|
+
speed: number;
|
|
37
|
+
/** Seconds from the start to the end, delay included. */
|
|
38
|
+
readonly duration: number;
|
|
39
|
+
readonly state: AnimationState;
|
|
40
|
+
play(): void;
|
|
41
|
+
pause(): void;
|
|
42
|
+
/** Stops where it is: the value stays as painted. */
|
|
43
|
+
stop(): void;
|
|
44
|
+
/** Stops and goes back to where it started. */
|
|
45
|
+
cancel(): void;
|
|
46
|
+
/** Jumps to the end. */
|
|
47
|
+
complete(): void;
|
|
48
|
+
/** Lets a native scroll or view timeline drive it; false when part of it runs in JavaScript. */
|
|
49
|
+
attachTimeline(timeline: AnimationTimeline): boolean;
|
|
50
|
+
}
|
|
51
|
+
export type KeyframeValue = number | string;
|
|
52
|
+
export type Keyframes<T = KeyframeValue> = T | readonly T[];
|
|
53
|
+
/**
|
|
54
|
+
* DOM keyframes: any CSS property (camelCase), a CSS variable (`--name`),
|
|
55
|
+
* the independent transforms (`x`, `y`, `z`, `scale`, `scaleX`, `scaleY`,
|
|
56
|
+
* `rotate`), or an SVG attribute. A single value animates from the current
|
|
57
|
+
* one; an array lists every keyframe. Numbers take the property's unit (px,
|
|
58
|
+
* deg) when it has one.
|
|
59
|
+
*/
|
|
60
|
+
export type DOMKeyframes = Readonly<Record<string, Keyframes>>;
|
|
61
|
+
export type ElementTarget = Element | string | ArrayLike<Element>;
|
|
62
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/animate/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAC7E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,MAAM,MAAM,KAAK,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACtD;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,gBAAgB,GAAG,SAAS,gBAAgB,EAAE,CAAC;IAC/D,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,sFAAsF;IACtF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,aAAa,CAAC,EAAE,mBAAmB,CAAC;CAC7C;AAED,MAAM,WAAW,qBAAqB,CAAC,CAAC,CAAE,SAAQ,gBAAgB;IACjE,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;CACjC;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,iBAAkB,SAAQ,WAAW,CAAC,IAAI,CAAC;IAC3D,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;IACd,qDAAqD;IACrD,IAAI,IAAI,IAAI,CAAC;IACb,+CAA+C;IAC/C,MAAM,IAAI,IAAI,CAAC;IACf,wBAAwB;IACxB,QAAQ,IAAI,IAAI,CAAC;IACjB,gGAAgG;IAChG,cAAc,CAAC,QAAQ,EAAE,iBAAiB,GAAG,OAAO,CAAC;CACrD;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAC5C,MAAM,MAAM,SAAS,CAAC,CAAC,GAAG,aAAa,IAAI,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAE/D,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnimationControls, Keyframes, ValueAnimationOptions } from "./types.js";
|
|
2
|
+
import type { MotionValue } from "../value/motion-value.js";
|
|
3
|
+
/**
|
|
4
|
+
* A motion value towards a target on the frame loop. Whatever the value is
|
|
5
|
+
* doing now — mid-spring, dragged — is where the new animation starts, at
|
|
6
|
+
* the same speed.
|
|
7
|
+
*/
|
|
8
|
+
export declare function animateMotionValue<T>(value: MotionValue<T>, target: Keyframes<T>, options?: ValueAnimationOptions<T>): AnimationControls;
|
|
9
|
+
/** Each numeric or mixable key of a plain object, written back into the object. */
|
|
10
|
+
export declare function animateObject<T extends object>(object: T, keyframes: {
|
|
11
|
+
readonly [K in keyof T]?: Keyframes<T[K]>;
|
|
12
|
+
}, options?: ValueAnimationOptions<T>): AnimationControls;
|
|
13
|
+
//# sourceMappingURL=value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../../src/animate/value.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACX,iBAAiB,EAEjB,SAAS,EACT,qBAAqB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAQ3D;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EACnC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EACrB,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,qBAAqB,CAAC,CAAC,CAAM,GACpC,iBAAiB,CAwBnB;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAC7C,MAAM,EAAE,CAAC,EACT,SAAS,EAAE;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAAE,EACxD,OAAO,GAAE,qBAAqB,CAAC,CAAC,CAAM,GACpC,iBAAiB,CAkCnB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { shouldReduceMotion } from "../accessibility/reduced-motion.js";
|
|
2
|
+
import { finishedControls, groupControls } from "./controls.js";
|
|
3
|
+
import { jsAnimation } from "./js-animation.js";
|
|
4
|
+
import { cancelFrame, frame } from "../frame/frame.js";
|
|
5
|
+
function startDelay(options) {
|
|
6
|
+
return typeof options.delay === "function" ? options.delay(0, 1) : options.delay ?? 0;
|
|
7
|
+
}
|
|
8
|
+
function animateMotionValue(value, target, options = {}) {
|
|
9
|
+
const list = Array.isArray(target) ? target : [target];
|
|
10
|
+
const keyframes = list.length > 1 ? list : [value.get(), list[0]];
|
|
11
|
+
const velocity = value.getVelocity();
|
|
12
|
+
value.stop();
|
|
13
|
+
if (shouldReduceMotion(options.reducedMotion)) {
|
|
14
|
+
value.jump(keyframes.at(-1));
|
|
15
|
+
options.onUpdate?.(value.get());
|
|
16
|
+
options.onComplete?.();
|
|
17
|
+
return finishedControls();
|
|
18
|
+
}
|
|
19
|
+
const animation = jsAnimation({
|
|
20
|
+
keyframes,
|
|
21
|
+
options,
|
|
22
|
+
delay: startDelay(options),
|
|
23
|
+
velocity: list.length > 1 ? 0 : velocity,
|
|
24
|
+
apply(next) {
|
|
25
|
+
value.set(next);
|
|
26
|
+
options.onUpdate?.(next);
|
|
27
|
+
},
|
|
28
|
+
onComplete: options.onComplete
|
|
29
|
+
});
|
|
30
|
+
value.start(animation);
|
|
31
|
+
return animation;
|
|
32
|
+
}
|
|
33
|
+
function animateObject(object, keyframes, options = {}) {
|
|
34
|
+
const record = object;
|
|
35
|
+
const reduce = shouldReduceMotion(options.reducedMotion);
|
|
36
|
+
const controls = Object.entries(keyframes).map(([key, target]) => {
|
|
37
|
+
const list = Array.isArray(target) ? target : [target];
|
|
38
|
+
const frames = list.length > 1 ? list : [record[key], list[0]];
|
|
39
|
+
if (reduce) {
|
|
40
|
+
record[key] = frames.at(-1);
|
|
41
|
+
return finishedControls();
|
|
42
|
+
}
|
|
43
|
+
return jsAnimation({
|
|
44
|
+
keyframes: frames,
|
|
45
|
+
options,
|
|
46
|
+
delay: startDelay(options),
|
|
47
|
+
velocity: 0,
|
|
48
|
+
apply(next) {
|
|
49
|
+
record[key] = next;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
if (reduce) options.onUpdate?.(object);
|
|
54
|
+
const group = groupControls(controls);
|
|
55
|
+
const notify = options.onUpdate;
|
|
56
|
+
if (notify && !reduce) {
|
|
57
|
+
const each = () => notify(object);
|
|
58
|
+
frame.render(each, true);
|
|
59
|
+
group.finished.then(() => {
|
|
60
|
+
cancelFrame(each);
|
|
61
|
+
notify(object);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
group.finished.then(() => options.onComplete?.());
|
|
65
|
+
return group;
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
animateMotionValue,
|
|
69
|
+
animateObject
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=value.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/animate/value.ts"],
|
|
4
|
+
"sourcesContent": ["import { shouldReduceMotion } from \"#/accessibility/reduced-motion.ts\";\nimport { finishedControls, groupControls } from \"#/animate/controls.ts\";\nimport { jsAnimation } from \"#/animate/js-animation.ts\";\nimport type {\n\tAnimationControls,\n\tAnimationOptions,\n\tKeyframes,\n\tValueAnimationOptions,\n} from \"#/animate/types.ts\";\nimport { cancelFrame, frame } from \"#/frame/frame.ts\";\nimport type { MotionValue } from \"#/value/motion-value.ts\";\n\nfunction startDelay(options: AnimationOptions): number {\n\treturn typeof options.delay === \"function\"\n\t\t? options.delay(0, 1)\n\t\t: (options.delay ?? 0);\n}\n\n/**\n * A motion value towards a target on the frame loop. Whatever the value is\n * doing now \u2014 mid-spring, dragged \u2014 is where the new animation starts, at\n * the same speed.\n */\nexport function animateMotionValue<T>(\n\tvalue: MotionValue<T>,\n\ttarget: Keyframes<T>,\n\toptions: ValueAnimationOptions<T> = {},\n): AnimationControls {\n\tconst list: readonly T[] = Array.isArray(target) ? target : [target as T];\n\tconst keyframes = list.length > 1 ? list : [value.get(), list[0] as T];\n\tconst velocity = value.getVelocity();\n\tvalue.stop();\n\tif (shouldReduceMotion(options.reducedMotion)) {\n\t\tvalue.jump(keyframes.at(-1) as T);\n\t\toptions.onUpdate?.(value.get());\n\t\toptions.onComplete?.();\n\t\treturn finishedControls();\n\t}\n\tconst animation = jsAnimation({\n\t\tkeyframes,\n\t\toptions,\n\t\tdelay: startDelay(options),\n\t\tvelocity: list.length > 1 ? 0 : velocity,\n\t\tapply(next: T) {\n\t\t\tvalue.set(next);\n\t\t\toptions.onUpdate?.(next);\n\t\t},\n\t\tonComplete: options.onComplete,\n\t});\n\tvalue.start(animation);\n\treturn animation;\n}\n\n/** Each numeric or mixable key of a plain object, written back into the object. */\nexport function animateObject<T extends object>(\n\tobject: T,\n\tkeyframes: { readonly [K in keyof T]?: Keyframes<T[K]> },\n\toptions: ValueAnimationOptions<T> = {},\n): AnimationControls {\n\tconst record = object as Record<string, unknown>;\n\tconst reduce = shouldReduceMotion(options.reducedMotion);\n\tconst controls = Object.entries(keyframes).map(([key, target]) => {\n\t\tconst list: readonly unknown[] = Array.isArray(target) ? target : [target];\n\t\tconst frames = list.length > 1 ? list : [record[key], list[0]];\n\t\tif (reduce) {\n\t\t\trecord[key] = frames.at(-1);\n\t\t\treturn finishedControls();\n\t\t}\n\t\treturn jsAnimation({\n\t\t\tkeyframes: frames,\n\t\t\toptions,\n\t\t\tdelay: startDelay(options),\n\t\t\tvelocity: 0,\n\t\t\tapply(next) {\n\t\t\t\trecord[key] = next;\n\t\t\t},\n\t\t});\n\t});\n\tif (reduce) options.onUpdate?.(object);\n\t// One update per frame for the whole object, after every key has moved.\n\tconst group = groupControls(controls);\n\tconst notify = options.onUpdate;\n\tif (notify && !reduce) {\n\t\tconst each = () => notify(object);\n\t\tframe.render(each, true);\n\t\tgroup.finished.then(() => {\n\t\t\tcancelFrame(each);\n\t\t\tnotify(object);\n\t\t});\n\t}\n\tgroup.finished.then(() => options.onComplete?.());\n\treturn group;\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,0BAA0B;AACnC,SAAS,kBAAkB,qBAAqB;AAChD,SAAS,mBAAmB;AAO5B,SAAS,aAAa,aAAa;AAGnC,SAAS,WAAW,SAAmC;AACtD,SAAO,OAAO,QAAQ,UAAU,aAC7B,QAAQ,MAAM,GAAG,CAAC,IACjB,QAAQ,SAAS;AACtB;AAOO,SAAS,mBACf,OACA,QACA,UAAoC,CAAC,GACjB;AACpB,QAAM,OAAqB,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAW;AACxE,QAAM,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAM;AACrE,QAAM,WAAW,MAAM,YAAY;AACnC,QAAM,KAAK;AACX,MAAI,mBAAmB,QAAQ,aAAa,GAAG;AAC9C,UAAM,KAAK,UAAU,GAAG,EAAE,CAAM;AAChC,YAAQ,WAAW,MAAM,IAAI,CAAC;AAC9B,YAAQ,aAAa;AACrB,WAAO,iBAAiB;AAAA,EACzB;AACA,QAAM,YAAY,YAAY;AAAA,IAC7B;AAAA,IACA;AAAA,IACA,OAAO,WAAW,OAAO;AAAA,IACzB,UAAU,KAAK,SAAS,IAAI,IAAI;AAAA,IAChC,MAAM,MAAS;AACd,YAAM,IAAI,IAAI;AACd,cAAQ,WAAW,IAAI;AAAA,IACxB;AAAA,IACA,YAAY,QAAQ;AAAA,EACrB,CAAC;AACD,QAAM,MAAM,SAAS;AACrB,SAAO;AACR;AAGO,SAAS,cACf,QACA,WACA,UAAoC,CAAC,GACjB;AACpB,QAAM,SAAS;AACf,QAAM,SAAS,mBAAmB,QAAQ,aAAa;AACvD,QAAM,WAAW,OAAO,QAAQ,SAAS,EAAE,IAAI,CAAC,CAAC,KAAK,MAAM,MAAM;AACjE,UAAM,OAA2B,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM;AACzE,UAAM,SAAS,KAAK,SAAS,IAAI,OAAO,CAAC,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC;AAC7D,QAAI,QAAQ;AACX,aAAO,GAAG,IAAI,OAAO,GAAG,EAAE;AAC1B,aAAO,iBAAiB;AAAA,IACzB;AACA,WAAO,YAAY;AAAA,MAClB,WAAW;AAAA,MACX;AAAA,MACA,OAAO,WAAW,OAAO;AAAA,MACzB,UAAU;AAAA,MACV,MAAM,MAAM;AACX,eAAO,GAAG,IAAI;AAAA,MACf;AAAA,IACD,CAAC;AAAA,EACF,CAAC;AACD,MAAI,OAAQ,SAAQ,WAAW,MAAM;AAErC,QAAM,QAAQ,cAAc,QAAQ;AACpC,QAAM,SAAS,QAAQ;AACvB,MAAI,UAAU,CAAC,QAAQ;AACtB,UAAM,OAAO,MAAM,OAAO,MAAM;AAChC,UAAM,OAAO,MAAM,IAAI;AACvB,UAAM,SAAS,KAAK,MAAM;AACzB,kBAAY,IAAI;AAChB,aAAO,MAAM;AAAA,IACd,CAAC;AAAA,EACF;AACA,QAAM,SAAS,KAAK,MAAM,QAAQ,aAAa,CAAC;AAChD,SAAO;AACR;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { JsAnimation } from "./js-animation.js";
|
|
2
|
+
import type { AnimationOptions, KeyframeValue } from "./types.js";
|
|
3
|
+
export interface WaapiConfig {
|
|
4
|
+
readonly element: Element;
|
|
5
|
+
/** The CSS property the browser animates. */
|
|
6
|
+
readonly property: string;
|
|
7
|
+
readonly keyframes: readonly KeyframeValue[];
|
|
8
|
+
/** A keyframe as the property's CSS value. */
|
|
9
|
+
format(value: KeyframeValue): string;
|
|
10
|
+
readonly options: AnimationOptions;
|
|
11
|
+
readonly delay: number;
|
|
12
|
+
readonly velocity: number;
|
|
13
|
+
readonly composite: CompositeOperation;
|
|
14
|
+
/** Writes the value that stays once the animation is gone. */
|
|
15
|
+
commit(value: KeyframeValue): void;
|
|
16
|
+
onComplete?(): void;
|
|
17
|
+
}
|
|
18
|
+
/** One CSS property of one element, played by the Web Animations API. */
|
|
19
|
+
export declare function waapiAnimation(config: WaapiConfig): JsAnimation<KeyframeValue>;
|
|
20
|
+
//# sourceMappingURL=waapi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waapi.d.ts","sourceRoot":"","sources":["../../src/animate/waapi.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAG7D,OAAO,KAAK,EACX,gBAAgB,EAEhB,aAAa,EACb,MAAM,oBAAoB,CAAC;AAM5B,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,aAAa,EAAE,CAAC;IAC7C,8CAA8C;IAC9C,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,kBAAkB,CAAC;IACvC,8DAA8D;IAC9D,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACnC,UAAU,CAAC,IAAI,IAAI,CAAC;CACpB;AA0ED,yEAAyE;AACzE,wBAAgB,cAAc,CAC7B,MAAM,EAAE,WAAW,GACjB,WAAW,CAAC,aAAa,CAAC,CA0G5B"}
|