@voila.dev/chart 5.0.114 → 5.0.118
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/dist/canvas/paint-scene.d.ts.map +1 -1
- package/dist/canvas/paint-scene.js +3 -1
- package/dist/canvas/paint-scene.js.map +2 -2
- package/dist/contour/density.d.ts.map +1 -1
- package/dist/contour/density.js +2 -0
- package/dist/contour/density.js.map +2 -2
- package/dist/core/marks/area.d.ts.map +1 -1
- package/dist/core/marks/area.js +27 -11
- package/dist/core/marks/area.js.map +2 -2
- package/dist/core/marks/bar.d.ts.map +1 -1
- package/dist/core/marks/bar.js +2 -0
- package/dist/core/marks/bar.js.map +2 -2
- package/dist/core/marks/line.d.ts.map +1 -1
- package/dist/core/marks/line.js +13 -4
- package/dist/core/marks/line.js.map +2 -2
- package/dist/core/marks/polar.d.ts.map +1 -1
- package/dist/core/marks/polar.js +22 -5
- package/dist/core/marks/polar.js.map +2 -2
- package/dist/core/marks/shared.d.ts +8 -1
- package/dist/core/marks/shared.d.ts.map +1 -1
- package/dist/core/marks/shared.js.map +2 -2
- package/dist/core/marks/stats/difference.d.ts.map +1 -1
- package/dist/core/marks/stats/difference.js +20 -7
- package/dist/core/marks/stats/difference.js.map +2 -2
- package/dist/core/motion/arc-motion.d.ts +9 -0
- package/dist/core/motion/arc-motion.d.ts.map +1 -0
- package/dist/core/motion/arc-motion.js +67 -0
- package/dist/core/motion/arc-motion.js.map +7 -0
- package/dist/core/motion/enter-exit.d.ts +6 -0
- package/dist/core/motion/enter-exit.d.ts.map +1 -0
- package/dist/core/motion/enter-exit.js +20 -0
- package/dist/core/motion/enter-exit.js.map +7 -0
- package/dist/core/motion/leaving.d.ts +12 -0
- package/dist/core/motion/leaving.d.ts.map +1 -0
- package/dist/core/motion/leaving.js +33 -0
- package/dist/core/motion/leaving.js.map +7 -0
- package/dist/core/motion/motion-store.d.ts +4 -1
- package/dist/core/motion/motion-store.d.ts.map +1 -1
- package/dist/core/motion/motion-store.js +251 -100
- package/dist/core/motion/motion-store.js.map +3 -3
- package/dist/core/motion/points-motion.d.ts +6 -0
- package/dist/core/motion/points-motion.d.ts.map +1 -0
- package/dist/core/motion/points-motion.js +140 -0
- package/dist/core/motion/points-motion.js.map +7 -0
- package/dist/core/motion/strings.d.ts +18 -0
- package/dist/core/motion/strings.d.ts.map +1 -0
- package/dist/core/motion/strings.js +34 -0
- package/dist/core/motion/strings.js.map +7 -0
- package/dist/core/types.d.ts +85 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/geo/geo.d.ts.map +1 -1
- package/dist/geo/geo.js +2 -0
- package/dist/geo/geo.js.map +2 -2
- package/dist/react/chart.d.ts.map +1 -1
- package/dist/react/chart.js +6 -2
- package/dist/react/chart.js.map +2 -2
- package/dist/react/svg-scene.d.ts.map +1 -1
- package/dist/react/svg-scene.js +3 -1
- package/dist/react/svg-scene.js.map +2 -2
- package/dist/react/use-animated-scene.d.ts.map +1 -1
- package/dist/react/use-animated-scene.js +14 -2
- package/dist/react/use-animated-scene.js.map +2 -2
- package/dist/voronoi/voronoi.d.ts.map +1 -1
- package/dist/voronoi/voronoi.js +2 -0
- package/dist/voronoi/voronoi.js.map +2 -2
- package/package.json +2 -2
- package/src/canvas/paint-scene.ts +5 -1
- package/src/contour/density.ts +2 -0
- package/src/core/marks/area.ts +28 -13
- package/src/core/marks/bar.ts +2 -0
- package/src/core/marks/line.ts +15 -8
- package/src/core/marks/polar.ts +22 -5
- package/src/core/marks/shared.ts +8 -0
- package/src/core/marks/stats/difference.ts +28 -8
- package/src/core/motion/arc-motion.ts +113 -0
- package/src/core/motion/enter-exit.ts +44 -0
- package/src/core/motion/leaving.ts +55 -0
- package/src/core/motion/motion-store.ts +332 -109
- package/src/core/motion/points-motion.ts +190 -0
- package/src/core/motion/strings.ts +68 -0
- package/src/core/types.ts +98 -0
- package/src/geo/geo.ts +2 -0
- package/src/react/chart.tsx +8 -2
- package/src/react/svg-scene.tsx +5 -1
- package/src/react/use-animated-scene.ts +18 -2
- package/src/voronoi/voronoi.ts +2 -0
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
import { spring, tween } from "@voila.dev/motion";
|
|
2
|
+
import { enterFrom, exitTo } from "./enter-exit.js";
|
|
3
|
+
import {
|
|
4
|
+
leavingGuides,
|
|
5
|
+
withLeaving
|
|
6
|
+
} from "./leaving.js";
|
|
7
|
+
import {
|
|
8
|
+
STRING_CHANNELS,
|
|
9
|
+
stringMixer,
|
|
10
|
+
stringOf,
|
|
11
|
+
withStrings
|
|
12
|
+
} from "./strings.js";
|
|
2
13
|
import { staggerDelay } from "./timing.js";
|
|
3
|
-
|
|
4
|
-
const CHANNELS = {
|
|
14
|
+
const FIELDS = {
|
|
5
15
|
rect: ["x", "y", "width", "height"],
|
|
6
16
|
circle: ["cx", "cy", "r"],
|
|
7
17
|
line: ["x1", "y1", "x2", "y2"],
|
|
@@ -10,15 +20,25 @@ const CHANNELS = {
|
|
|
10
20
|
group: []
|
|
11
21
|
};
|
|
12
22
|
const OPACITY = "opacity";
|
|
13
|
-
|
|
23
|
+
const DRAWN = "drawn";
|
|
24
|
+
const SEPARATOR = "\0";
|
|
25
|
+
function walk(nodes, visit) {
|
|
14
26
|
for (const node of nodes) {
|
|
15
|
-
|
|
16
|
-
if (node.kind === "group")
|
|
27
|
+
visit(node, nodes);
|
|
28
|
+
if (node.kind === "group") walk(node.children, visit);
|
|
17
29
|
}
|
|
18
|
-
|
|
30
|
+
}
|
|
31
|
+
function index(nodes) {
|
|
32
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
33
|
+
const siblings = /* @__PURE__ */ new Map();
|
|
34
|
+
walk(nodes, (node, list) => {
|
|
35
|
+
byKey.set(node.key, node);
|
|
36
|
+
siblings.set(node.key, list);
|
|
37
|
+
});
|
|
38
|
+
return { byKey, siblings };
|
|
19
39
|
}
|
|
20
40
|
function channelKey(node, channel) {
|
|
21
|
-
return `${node}
|
|
41
|
+
return `${node}${SEPARATOR}${channel}`;
|
|
22
42
|
}
|
|
23
43
|
function elapsed(motion, now) {
|
|
24
44
|
return Math.max(0, (now - motion.start) / 1e3);
|
|
@@ -26,10 +46,16 @@ function elapsed(motion, now) {
|
|
|
26
46
|
function done(motion, now) {
|
|
27
47
|
return elapsed(motion, now) >= motion.generator.duration;
|
|
28
48
|
}
|
|
49
|
+
function clamp(value) {
|
|
50
|
+
return Math.min(1, Math.max(0, value));
|
|
51
|
+
}
|
|
29
52
|
function createMotionStore(initial, timing) {
|
|
30
53
|
let target = initial;
|
|
31
54
|
const numbers = /* @__PURE__ */ new Map();
|
|
32
|
-
const
|
|
55
|
+
const strings = /* @__PURE__ */ new Map();
|
|
56
|
+
const guides = /* @__PURE__ */ new Map();
|
|
57
|
+
const shapes = /* @__PURE__ */ new Map();
|
|
58
|
+
const leaving = /* @__PURE__ */ new Map();
|
|
33
59
|
function generator(from, to, velocity) {
|
|
34
60
|
return timing.type === "spring" ? spring({
|
|
35
61
|
from,
|
|
@@ -43,128 +69,253 @@ function createMotionStore(initial, timing) {
|
|
|
43
69
|
ease: timing.easing
|
|
44
70
|
});
|
|
45
71
|
}
|
|
46
|
-
function
|
|
47
|
-
const motion =
|
|
48
|
-
|
|
49
|
-
return tweenPath(
|
|
50
|
-
motion.from,
|
|
51
|
-
motion.to,
|
|
52
|
-
motion.generator.at(elapsed(motion, now)).value
|
|
53
|
-
);
|
|
72
|
+
function value(node, channel, fallback, now) {
|
|
73
|
+
const motion = numbers.get(channelKey(node, channel));
|
|
74
|
+
return motion ? motion.generator.at(elapsed(motion, now)).value : fallback;
|
|
54
75
|
}
|
|
55
|
-
function
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
function spring1(node, channel, from, to, start, now) {
|
|
77
|
+
const key = channelKey(node, channel);
|
|
78
|
+
const running = numbers.get(key);
|
|
79
|
+
const velocity = running ? running.generator.at(elapsed(running, now)).velocity : 0;
|
|
80
|
+
numbers.delete(key);
|
|
81
|
+
if (from === to && velocity === 0) return;
|
|
82
|
+
numbers.set(key, { generator: generator(from, to, velocity), start });
|
|
83
|
+
}
|
|
84
|
+
function mixString(from, to, channel, start) {
|
|
85
|
+
const key = channelKey(to.key, channel);
|
|
86
|
+
strings.delete(key);
|
|
87
|
+
const was = stringOf(from, channel);
|
|
88
|
+
const goal = stringOf(to, channel);
|
|
89
|
+
if (was === void 0 || goal === void 0 || was === goal) return;
|
|
90
|
+
strings.set(key, {
|
|
91
|
+
generator: generator(0, 1, 0),
|
|
92
|
+
start,
|
|
93
|
+
mix: stringMixer(to, channel, was, goal)
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function drop(node) {
|
|
97
|
+
for (const motions of [numbers, strings]) {
|
|
98
|
+
for (const key of motions.keys()) {
|
|
99
|
+
if (key.startsWith(node + SEPARATOR)) motions.delete(key);
|
|
100
|
+
}
|
|
68
101
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
102
|
+
shapes.delete(node);
|
|
103
|
+
leaving.delete(node);
|
|
104
|
+
}
|
|
105
|
+
function move(from, to, start, now) {
|
|
106
|
+
const key = to.key;
|
|
107
|
+
for (const field of FIELDS[to.kind]) {
|
|
108
|
+
const was = from[field];
|
|
109
|
+
spring1(
|
|
110
|
+
key,
|
|
111
|
+
field,
|
|
112
|
+
was,
|
|
113
|
+
to[field],
|
|
114
|
+
start,
|
|
73
115
|
now
|
|
74
116
|
);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
117
|
+
}
|
|
118
|
+
mixString(from, to, "fill", start);
|
|
119
|
+
mixString(from, to, "stroke", start);
|
|
120
|
+
if (to.kind !== "path" || from.kind !== "path") return;
|
|
121
|
+
const previous = shapes.get(key);
|
|
122
|
+
shapes.delete(key);
|
|
123
|
+
strings.delete(channelKey(key, "d"));
|
|
124
|
+
const motion = to.motion;
|
|
125
|
+
const plan = motion && from.geometry && to.geometry ? motion.plan(from.geometry, to.geometry) : void 0;
|
|
126
|
+
if (!plan) {
|
|
127
|
+
mixString(from, to, "d", start);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
for (const channel of previous?.plan.targets.keys() ?? []) {
|
|
131
|
+
if (!plan.targets.has(channel)) {
|
|
132
|
+
numbers.delete(channelKey(key, `g${channel}`));
|
|
83
133
|
}
|
|
84
134
|
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const from = fade ? fade.generator.at(elapsed(fade, now)).value : 0;
|
|
89
|
-
numbers.set(fading, { generator: generator(from, 1, 0), start });
|
|
135
|
+
for (const [channel, goal] of plan.targets) {
|
|
136
|
+
const was = plan.starts.get(channel) ?? goal;
|
|
137
|
+
spring1(key, `g${channel}`, was, goal, start, now);
|
|
90
138
|
}
|
|
139
|
+
shapes.set(key, { plan, motion });
|
|
91
140
|
}
|
|
92
|
-
function
|
|
141
|
+
function paintNode(node, now) {
|
|
93
142
|
if (node.kind === "group") {
|
|
94
|
-
return {
|
|
95
|
-
...node,
|
|
96
|
-
children: node.children.map((child) => paint(child, now))
|
|
97
|
-
};
|
|
143
|
+
return { ...node, children: paintList(node.children, node.key, now) };
|
|
98
144
|
}
|
|
145
|
+
const key = node.key;
|
|
99
146
|
const moved = {};
|
|
100
|
-
for (const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
147
|
+
for (const field of FIELDS[node.kind]) {
|
|
148
|
+
moved[field] = value(
|
|
149
|
+
key,
|
|
150
|
+
field,
|
|
151
|
+
node[field],
|
|
152
|
+
now
|
|
153
|
+
);
|
|
104
154
|
}
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const
|
|
114
|
-
const
|
|
155
|
+
let next = { ...node, ...moved };
|
|
156
|
+
const shape = shapes.get(key);
|
|
157
|
+
if (next.kind === "path" && shape) {
|
|
158
|
+
const geometry2 = shape.plan.build(
|
|
159
|
+
(channel) => value(key, `g${channel}`, shape.plan.targets.get(channel) ?? 0, now)
|
|
160
|
+
);
|
|
161
|
+
next = { ...next, geometry: geometry2, d: shape.motion.draw(geometry2) };
|
|
162
|
+
}
|
|
163
|
+
const mixed = {};
|
|
164
|
+
for (const channel of STRING_CHANNELS) {
|
|
165
|
+
const motion = strings.get(channelKey(key, channel));
|
|
166
|
+
if (motion) {
|
|
167
|
+
mixed[channel] = motion.mix(
|
|
168
|
+
motion.generator.at(elapsed(motion, now)).value
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
next = withStrings(next, mixed);
|
|
173
|
+
const opacity = value(key, OPACITY, 1, now);
|
|
174
|
+
const drawn = value(key, DRAWN, 1, now);
|
|
175
|
+
if (opacity === 1 && drawn === 1) return next;
|
|
176
|
+
const geometry = next.kind === "path" ? next.geometry : void 0;
|
|
177
|
+
const length = geometry && next.kind === "path" ? next.motion?.length?.(geometry) : 0;
|
|
115
178
|
return {
|
|
116
|
-
...
|
|
179
|
+
...next,
|
|
117
180
|
paint: {
|
|
118
|
-
...
|
|
119
|
-
opacity: (
|
|
181
|
+
...next.paint,
|
|
182
|
+
opacity: (next.paint.opacity ?? 1) * clamp(opacity),
|
|
183
|
+
...drawn < 1 && geometry ? {
|
|
184
|
+
drawn: {
|
|
185
|
+
fraction: clamp(drawn),
|
|
186
|
+
length: length ?? 0
|
|
187
|
+
}
|
|
188
|
+
} : {}
|
|
120
189
|
}
|
|
121
190
|
};
|
|
122
191
|
}
|
|
192
|
+
function paintList(list, parent, now) {
|
|
193
|
+
const out = [];
|
|
194
|
+
function place(after) {
|
|
195
|
+
for (const [key, exit] of leaving) {
|
|
196
|
+
if (exit.after !== after) continue;
|
|
197
|
+
out.push(paintNode(exit.node, now));
|
|
198
|
+
place(key);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
if (parent === null) place(void 0);
|
|
202
|
+
for (const node of list) {
|
|
203
|
+
out.push(paintNode(node, now));
|
|
204
|
+
place(node.key);
|
|
205
|
+
}
|
|
206
|
+
if (guides.size === 0) return out;
|
|
207
|
+
const fading = [...guides.values()].map(
|
|
208
|
+
(motion) => [
|
|
209
|
+
motion.guide,
|
|
210
|
+
Math.max(0, motion.generator.at(elapsed(motion, now)).value)
|
|
211
|
+
]
|
|
212
|
+
);
|
|
213
|
+
return withLeaving(out, parent, fading);
|
|
214
|
+
}
|
|
215
|
+
function prune(now) {
|
|
216
|
+
for (const motions of [numbers, strings, guides]) {
|
|
217
|
+
for (const [key, motion] of motions) {
|
|
218
|
+
if (done(motion, now)) motions.delete(key);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const moving = new Set(
|
|
222
|
+
[...numbers.keys(), ...strings.keys()].map(
|
|
223
|
+
(key) => key.split(SEPARATOR)[0]
|
|
224
|
+
)
|
|
225
|
+
);
|
|
226
|
+
for (const key of shapes.keys()) {
|
|
227
|
+
if (!moving.has(key)) shapes.delete(key);
|
|
228
|
+
}
|
|
229
|
+
for (const key of leaving.keys()) {
|
|
230
|
+
if (!moving.has(key)) leaving.delete(key);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
123
233
|
return {
|
|
124
234
|
retarget(scene, now) {
|
|
125
|
-
const before =
|
|
126
|
-
const after =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
235
|
+
const before = index(target.nodes);
|
|
236
|
+
const after = index(scene.nodes);
|
|
237
|
+
function painted(key) {
|
|
238
|
+
const node = before.byKey.get(key) ?? leaving.get(key)?.node ?? guides.get(key)?.guide.node;
|
|
239
|
+
return node && paintNode(node, now);
|
|
240
|
+
}
|
|
241
|
+
for (const guide of leavingGuides(
|
|
242
|
+
target.nodes,
|
|
243
|
+
(key) => after.byKey.has(key)
|
|
244
|
+
)) {
|
|
245
|
+
guides.set(guide.node.key, {
|
|
246
|
+
generator: generator(value(guide.node.key, OPACITY, 1, now), 0, 0),
|
|
247
|
+
start: now,
|
|
248
|
+
guide
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
for (const key of /* @__PURE__ */ new Set([...before.byKey.keys(), ...leaving.keys()])) {
|
|
252
|
+
if (after.byKey.has(key)) continue;
|
|
253
|
+
const base = before.byKey.get(key) ?? leaving.get(key)?.node;
|
|
254
|
+
const siblings = before.siblings.get(key) ?? leaving.get(key)?.siblings ?? [];
|
|
255
|
+
const goal = exitTo(base, siblings, after.byKey);
|
|
256
|
+
const from = painted(key);
|
|
257
|
+
if (!goal || !from) {
|
|
258
|
+
drop(key);
|
|
259
|
+
continue;
|
|
137
260
|
}
|
|
261
|
+
move(from, goal, now, now);
|
|
262
|
+
const at = siblings.findIndex((node) => node.key === key);
|
|
263
|
+
leaving.set(key, {
|
|
264
|
+
node: goal,
|
|
265
|
+
after: siblings[at - 1]?.key,
|
|
266
|
+
siblings
|
|
267
|
+
});
|
|
138
268
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
);
|
|
145
|
-
|
|
269
|
+
const marks = [...after.byKey.values()].filter(
|
|
270
|
+
(node) => node.role === "mark"
|
|
271
|
+
);
|
|
272
|
+
const order = new Map(marks.map((node, at) => [node.key, at]));
|
|
273
|
+
for (const node of after.byKey.values()) {
|
|
274
|
+
if (node.kind === "group") continue;
|
|
275
|
+
const start = now + staggerDelay(timing, order.get(node.key) ?? 0, marks.length) * 1e3;
|
|
276
|
+
const old = painted(node.key);
|
|
277
|
+
leaving.delete(node.key);
|
|
278
|
+
const from = old ?? enterFrom(node, after.siblings.get(node.key) ?? [], before.byKey);
|
|
279
|
+
if (from) move(from, node, start, now);
|
|
280
|
+
const fading = numbers.get(channelKey(node.key, OPACITY));
|
|
281
|
+
const returning = guides.get(node.key);
|
|
282
|
+
if (!from && node.enter !== "none" || fading || returning) {
|
|
283
|
+
const shown = returning ? Math.max(0, returning.generator.at(elapsed(returning, now)).value) : fading ? value(node.key, OPACITY, 1, now) : 0;
|
|
284
|
+
spring1(node.key, OPACITY, shown, 1, start, now);
|
|
285
|
+
}
|
|
146
286
|
}
|
|
287
|
+
for (const key of after.byKey.keys()) guides.delete(key);
|
|
147
288
|
target = scene;
|
|
148
289
|
},
|
|
290
|
+
introduce(now) {
|
|
291
|
+
let any = false;
|
|
292
|
+
walk(target.nodes, (node) => {
|
|
293
|
+
if (node.kind !== "path" || node.enter !== "draw") return;
|
|
294
|
+
if (node.geometry?.kind !== "points" || node.paint.strokeDasharray) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
spring1(node.key, DRAWN, 0, 1, now, now);
|
|
298
|
+
any = true;
|
|
299
|
+
});
|
|
300
|
+
return any;
|
|
301
|
+
},
|
|
149
302
|
snap(scene) {
|
|
150
|
-
numbers
|
|
151
|
-
|
|
303
|
+
for (const motions of [numbers, strings, guides, shapes, leaving]) {
|
|
304
|
+
motions.clear();
|
|
305
|
+
}
|
|
152
306
|
target = scene;
|
|
153
307
|
},
|
|
154
308
|
frame(now) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
for (const [key, motion] of paths) {
|
|
159
|
-
if (done(motion, now)) paths.delete(key);
|
|
160
|
-
}
|
|
161
|
-
if (numbers.size === 0 && paths.size === 0) return target;
|
|
162
|
-
return { ...target, nodes: target.nodes.map((node) => paint(node, now)) };
|
|
309
|
+
prune(now);
|
|
310
|
+
if (numbers.size + strings.size + guides.size === 0) return target;
|
|
311
|
+
return { ...target, nodes: paintList(target.nodes, null, now) };
|
|
163
312
|
},
|
|
164
313
|
settled(now) {
|
|
165
|
-
return [
|
|
166
|
-
(
|
|
167
|
-
|
|
314
|
+
return [
|
|
315
|
+
...numbers.values(),
|
|
316
|
+
...strings.values(),
|
|
317
|
+
...guides.values()
|
|
318
|
+
].every((motion) => done(motion, now));
|
|
168
319
|
}
|
|
169
320
|
};
|
|
170
321
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/core/motion/motion-store.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Generator, spring, tween } from \"@voila.dev/motion\";\nimport { type ChartTiming, staggerDelay } from \"#/core/motion/timing.ts\";\nimport { tweenPath } from \"#/core/motion/tween.ts\";\nimport type { ChartScene, SceneNode } from \"#/core/types.ts\";\n\n/**\n * Every moving number of a chart, as springs keyed by node and channel. A\n * new scene retargets them: each channel starts from where it is painted, at\n * the speed it has, so an update landing mid-flight bends the motion instead\n * of kinking it. Pure and clocked from outside (milliseconds), so the SVG and\n * Canvas renderers move identically and tests step it by hand. Hit-testing\n * and focus never read it: they read the scene it moves towards.\n */\nexport interface MotionStore {\n\tretarget(scene: ChartScene, now: number): void;\n\t/** Jumps to `scene`: a resize, or reduced motion. */\n\tsnap(scene: ChartScene): void;\n\tframe(now: number): ChartScene;\n\tsettled(now: number): boolean;\n}\n\ninterface Motion {\n\treadonly generator: Generator;\n\t/** Milliseconds, the delay included. */\n\treadonly start: number;\n}\n\ninterface PathMotion extends Motion {\n\treadonly from: string;\n\treadonly to: string;\n}\n\ntype Numeric = Record<string, number>;\n\nconst CHANNELS: Record<SceneNode[\"kind\"], readonly string[]> = {\n\trect: [\"x\", \"y\", \"width\", \"height\"],\n\tcircle: [\"cx\", \"cy\", \"r\"],\n\tline: [\"x1\", \"y1\", \"x2\", \"y2\"],\n\ttext: [\"x\", \"y\"],\n\tpath: [],\n\tgroup: [],\n};\n\nconst OPACITY = \"opacity\";\n\nfunction flatten(\n\tnodes: readonly SceneNode[],\n\tinto = new Map<string, SceneNode>(),\n) {\n\tfor (const node of nodes) {\n\t\tinto.set(node.key, node);\n\t\tif (node.kind === \"group\") flatten(node.children, into);\n\t}\n\treturn into;\n}\n\nfunction channelKey(node: string, channel: string): string {\n\treturn `${node}\\u0000${channel}`;\n}\n\nfunction elapsed(motion: Motion, now: number): number {\n\treturn Math.max(0, (now - motion.start) / 1000);\n}\n\nfunction done(motion: Motion, now: number): boolean {\n\treturn elapsed(motion, now) >= motion.generator.duration;\n}\n\nexport function createMotionStore(\n\tinitial: ChartScene,\n\ttiming: ChartTiming,\n): MotionStore {\n\tlet target = initial;\n\tconst numbers = new Map<string, Motion>();\n\tconst paths = new Map<string, PathMotion>();\n\n\tfunction generator(from: number, to: number, velocity: number): Generator {\n\t\treturn timing.type === \"spring\"\n\t\t\t? spring({\n\t\t\t\t\tfrom,\n\t\t\t\t\tto,\n\t\t\t\t\tvelocity,\n\t\t\t\t\tduration: timing.duration,\n\t\t\t\t\tbounce: timing.bounce,\n\t\t\t\t})\n\t\t\t: tween({\n\t\t\t\t\tkeyframes: [from, to],\n\t\t\t\t\tduration: timing.duration,\n\t\t\t\t\tease: timing.easing,\n\t\t\t\t});\n\t}\n\n\tfunction pathNow(key: string, fallback: string | undefined, now: number) {\n\t\tconst motion = paths.get(key);\n\t\tif (!motion) return fallback;\n\t\treturn tweenPath(\n\t\t\tmotion.from,\n\t\t\tmotion.to,\n\t\t\tmotion.generator.at(elapsed(motion, now)).value,\n\t\t);\n\t}\n\n\tfunction moveNode(\n\t\tnode: SceneNode,\n\t\tbefore: SceneNode | undefined,\n\t\tstart: number,\n\t\tnow: number,\n\t) {\n\t\tfor (const channel of CHANNELS[node.kind]) {\n\t\t\tconst key = channelKey(node.key, channel);\n\t\t\tconst running = numbers.get(key);\n\t\t\tconst state = running?.generator.at(elapsed(running, now));\n\t\t\tconst from =\n\t\t\t\tstate?.value ?? (before as unknown as Numeric | undefined)?.[channel];\n\t\t\tconst to = (node as unknown as Numeric)[channel] as number;\n\t\t\tnumbers.delete(key);\n\t\t\tif (from === undefined || (from === to && !state?.velocity)) continue;\n\t\t\tnumbers.set(key, {\n\t\t\t\tgenerator: generator(from, to, state?.velocity ?? 0),\n\t\t\t\tstart,\n\t\t\t});\n\t\t}\n\t\tif (node.kind === \"path\") {\n\t\t\tconst from = pathNow(\n\t\t\t\tnode.key,\n\t\t\t\tbefore?.kind === \"path\" ? before.d : undefined,\n\t\t\t\tnow,\n\t\t\t);\n\t\t\tpaths.delete(node.key);\n\t\t\tif (from !== undefined && from !== node.d) {\n\t\t\t\tpaths.set(node.key, {\n\t\t\t\t\tgenerator: generator(0, 1, 0),\n\t\t\t\t\tstart,\n\t\t\t\t\tfrom,\n\t\t\t\t\tto: node.d,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tconst fading = channelKey(node.key, OPACITY);\n\t\tconst fade = numbers.get(fading);\n\t\tif (before === undefined || fade) {\n\t\t\tconst from = fade ? fade.generator.at(elapsed(fade, now)).value : 0;\n\t\t\tnumbers.set(fading, { generator: generator(from, 1, 0), start });\n\t\t}\n\t}\n\n\tfunction paint(node: SceneNode, now: number): SceneNode {\n\t\tif (node.kind === \"group\") {\n\t\t\treturn {\n\t\t\t\t...node,\n\t\t\t\tchildren: node.children.map((child) => paint(child, now)),\n\t\t\t};\n\t\t}\n\t\tconst moved: Numeric = {};\n\t\tfor (const channel of [...CHANNELS[node.kind], OPACITY]) {\n\t\t\tconst motion = numbers.get(channelKey(node.key, channel));\n\t\t\tif (!motion) continue;\n\t\t\tmoved[channel] = motion.generator.at(elapsed(motion, now)).value;\n\t\t}\n\t\tconst d = node.kind === \"path\" ? pathNow(node.key, node.d, now) : undefined;\n\t\tconst { [OPACITY]: opacity, ...geometry } = moved;\n\t\tconst next = {\n\t\t\t...node,\n\t\t\t...geometry,\n\t\t\t...(d === undefined ? {} : { d }),\n\t\t} as SceneNode;\n\t\tif (opacity === undefined) return next;\n\t\tconst shown = Math.min(1, Math.max(0, opacity));\n\t\tconst painted = next as Exclude<SceneNode, { kind: \"group\" }>;\n\t\treturn {\n\t\t\t...painted,\n\t\t\tpaint: {\n\t\t\t\t...painted.paint,\n\t\t\t\topacity: (painted.paint.opacity ?? 1) * shown,\n\t\t\t},\n\t\t} as SceneNode;\n\t}\n\n\treturn {\n\t\tretarget(scene, now) {\n\t\t\tconst before = flatten(target.nodes);\n\t\t\tconst after = flatten(scene.nodes);\n\t\t\tconst marks = [...after.values()].filter((node) => node.role === \"mark\");\n\t\t\tconst order = new Map(marks.map((node, index) => [node.key, index]));\n\t\t\tfor (const key of before.keys()) {\n\t\t\t\tif (after.has(key)) continue;\n\t\t\t\tpaths.delete(key);\n\t\t\t\tfor (const channel of [\n\t\t\t\t\t...(CHANNELS[before.get(key)?.kind ?? \"group\"] ?? []),\n\t\t\t\t\tOPACITY,\n\t\t\t\t]) {\n\t\t\t\t\tnumbers.delete(channelKey(key, channel));\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const node of after.values()) {\n\t\t\t\tconst delay = staggerDelay(\n\t\t\t\t\ttiming,\n\t\t\t\t\torder.get(node.key) ?? 0,\n\t\t\t\t\tmarks.length,\n\t\t\t\t);\n\t\t\t\tmoveNode(node, before.get(node.key), now + delay * 1000, now);\n\t\t\t}\n\t\t\ttarget = scene;\n\t\t},\n\t\tsnap(scene) {\n\t\t\tnumbers.clear();\n\t\t\tpaths.clear();\n\t\t\ttarget = scene;\n\t\t},\n\t\tframe(now) {\n\t\t\tfor (const [key, motion] of numbers) {\n\t\t\t\tif (done(motion, now)) numbers.delete(key);\n\t\t\t}\n\t\t\tfor (const [key, motion] of paths) {\n\t\t\t\tif (done(motion, now)) paths.delete(key);\n\t\t\t}\n\t\t\tif (numbers.size === 0 && paths.size === 0) return target;\n\t\t\treturn { ...target, nodes: target.nodes.map((node) => paint(node, now)) };\n\t\t},\n\t\tsettled(now) {\n\t\t\treturn [...numbers.values(), ...paths.values()].every((motion) =>\n\t\t\t\tdone(motion, now),\n\t\t\t);\n\t\t},\n\t};\n}\n"],
|
|
5
|
-
"mappings": "AAAA,SAAyB,QAAQ,aAAa;AAC9C,SAA2B,oBAAoB;
|
|
6
|
-
"names": []
|
|
4
|
+
"sourcesContent": ["import { type Generator, spring, tween } from \"@voila.dev/motion\";\nimport { enterFrom, exitTo } from \"#/core/motion/enter-exit.ts\";\nimport {\n\ttype LeavingGuide,\n\tleavingGuides,\n\twithLeaving,\n} from \"#/core/motion/leaving.ts\";\nimport {\n\tSTRING_CHANNELS,\n\ttype StringChannel,\n\tstringMixer,\n\tstringOf,\n\twithStrings,\n} from \"#/core/motion/strings.ts\";\nimport { type ChartTiming, staggerDelay } from \"#/core/motion/timing.ts\";\nimport type {\n\tChartScene,\n\tGeometryMotion,\n\tGeometryPlan,\n\tSceneNode,\n} from \"#/core/types.ts\";\n\n/**\n * Every moving number of a chart, as springs keyed by node and channel. A\n * new scene retargets them: each channel starts from where it is painted, at\n * the speed it has, so an update landing mid-flight bends the motion instead\n * of kinking it. Pure and clocked from outside (milliseconds), so the SVG and\n * Canvas renderers move identically and tests step it by hand. Hit-testing\n * and focus never read it: they read the scene it moves towards, which never\n * holds the marks collapsing or the guides fading on their way out.\n */\nexport interface MotionStore {\n\tretarget(scene: ChartScene, now: number): void;\n\t/** The first render: lines that `enter: \"draw\"` trace themselves in. False when none does. */\n\tintroduce(now: number): boolean;\n\t/** Jumps to `scene`: a resize, or reduced motion. */\n\tsnap(scene: ChartScene): void;\n\tframe(now: number): ChartScene;\n\tsettled(now: number): boolean;\n}\n\ninterface Motion {\n\treadonly generator: Generator;\n\t/** Milliseconds, the delay included. */\n\treadonly start: number;\n}\n\n/** A path or a colour: a progress from 0 to 1, and the mix it reads. */\ninterface StringMotion extends Motion {\n\treadonly mix: (progress: number) => string;\n}\n\n/** A guide fading out where it stood. */\ninterface GuideMotion extends Motion {\n\treadonly guide: LeavingGuide;\n}\n\n/** A data mark collapsing on its way out: drawn after its old sibling until its springs settle. */\ninterface Leaving {\n\treadonly node: SceneNode;\n\treadonly after: string | undefined;\n\treadonly siblings: readonly SceneNode[];\n}\n\ntype Numeric = Record<string, number>;\n\nconst FIELDS: Record<SceneNode[\"kind\"], readonly string[]> = {\n\trect: [\"x\", \"y\", \"width\", \"height\"],\n\tcircle: [\"cx\", \"cy\", \"r\"],\n\tline: [\"x1\", \"y1\", \"x2\", \"y2\"],\n\ttext: [\"x\", \"y\"],\n\tpath: [],\n\tgroup: [],\n};\n\nconst OPACITY = \"opacity\";\nconst DRAWN = \"drawn\";\nconst SEPARATOR = \"\\u0000\";\n\nfunction walk(\n\tnodes: readonly SceneNode[],\n\tvisit: (node: SceneNode, siblings: readonly SceneNode[]) => void,\n) {\n\tfor (const node of nodes) {\n\t\tvisit(node, nodes);\n\t\tif (node.kind === \"group\") walk(node.children, visit);\n\t}\n}\n\nfunction index(nodes: readonly SceneNode[]) {\n\tconst byKey = new Map<string, SceneNode>();\n\tconst siblings = new Map<string, readonly SceneNode[]>();\n\twalk(nodes, (node, list) => {\n\t\tbyKey.set(node.key, node);\n\t\tsiblings.set(node.key, list);\n\t});\n\treturn { byKey, siblings };\n}\n\nfunction channelKey(node: string, channel: string): string {\n\treturn `${node}${SEPARATOR}${channel}`;\n}\n\nfunction elapsed(motion: Motion, now: number): number {\n\treturn Math.max(0, (now - motion.start) / 1000);\n}\n\nfunction done(motion: Motion, now: number): boolean {\n\treturn elapsed(motion, now) >= motion.generator.duration;\n}\n\nfunction clamp(value: number): number {\n\treturn Math.min(1, Math.max(0, value));\n}\n\nexport function createMotionStore(\n\tinitial: ChartScene,\n\ttiming: ChartTiming,\n): MotionStore {\n\tlet target = initial;\n\tconst numbers = new Map<string, Motion>();\n\tconst strings = new Map<string, StringMotion>();\n\tconst guides = new Map<string, GuideMotion>();\n\tconst shapes = new Map<\n\t\tstring,\n\t\t{ readonly plan: GeometryPlan; readonly motion: GeometryMotion }\n\t>();\n\tconst leaving = new Map<string, Leaving>();\n\n\tfunction generator(from: number, to: number, velocity: number): Generator {\n\t\treturn timing.type === \"spring\"\n\t\t\t? spring({\n\t\t\t\t\tfrom,\n\t\t\t\t\tto,\n\t\t\t\t\tvelocity,\n\t\t\t\t\tduration: timing.duration,\n\t\t\t\t\tbounce: timing.bounce,\n\t\t\t\t})\n\t\t\t: tween({\n\t\t\t\t\tkeyframes: [from, to],\n\t\t\t\t\tduration: timing.duration,\n\t\t\t\t\tease: timing.easing,\n\t\t\t\t});\n\t}\n\n\tfunction value(node: string, channel: string, fallback: number, now: number) {\n\t\tconst motion = numbers.get(channelKey(node, channel));\n\t\treturn motion ? motion.generator.at(elapsed(motion, now)).value : fallback;\n\t}\n\n\t/** Springs one channel from `from` to `to`, at the speed it already has. */\n\tfunction spring1(\n\t\tnode: string,\n\t\tchannel: string,\n\t\tfrom: number,\n\t\tto: number,\n\t\tstart: number,\n\t\tnow: number,\n\t) {\n\t\tconst key = channelKey(node, channel);\n\t\tconst running = numbers.get(key);\n\t\tconst velocity = running\n\t\t\t? running.generator.at(elapsed(running, now)).velocity\n\t\t\t: 0;\n\t\tnumbers.delete(key);\n\t\tif (from === to && velocity === 0) return;\n\t\tnumbers.set(key, { generator: generator(from, to, velocity), start });\n\t}\n\n\t/** Mixes one string channel from what is painted to what `to` asks for. */\n\tfunction mixString(\n\t\tfrom: SceneNode,\n\t\tto: SceneNode,\n\t\tchannel: StringChannel,\n\t\tstart: number,\n\t) {\n\t\tconst key = channelKey(to.key, channel);\n\t\tstrings.delete(key);\n\t\tconst was = stringOf(from, channel);\n\t\tconst goal = stringOf(to, channel);\n\t\tif (was === undefined || goal === undefined || was === goal) return;\n\t\tstrings.set(key, {\n\t\t\tgenerator: generator(0, 1, 0),\n\t\t\tstart,\n\t\t\tmix: stringMixer(to, channel, was, goal),\n\t\t});\n\t}\n\n\tfunction drop(node: string) {\n\t\tfor (const motions of [numbers, strings]) {\n\t\t\tfor (const key of motions.keys()) {\n\t\t\t\tif (key.startsWith(node + SEPARATOR)) motions.delete(key);\n\t\t\t}\n\t\t}\n\t\tshapes.delete(node);\n\t\tleaving.delete(node);\n\t}\n\n\t/** `from` is the node as painted now (or the shape it enters from), `to` where it goes. */\n\tfunction move(from: SceneNode, to: SceneNode, start: number, now: number) {\n\t\tconst key = to.key;\n\t\tfor (const field of FIELDS[to.kind]) {\n\t\t\tconst was = (from as unknown as Numeric)[field] as number;\n\t\t\tspring1(\n\t\t\t\tkey,\n\t\t\t\tfield,\n\t\t\t\twas,\n\t\t\t\t(to as unknown as Numeric)[field] as number,\n\t\t\t\tstart,\n\t\t\t\tnow,\n\t\t\t);\n\t\t}\n\t\tmixString(from, to, \"fill\", start);\n\t\tmixString(from, to, \"stroke\", start);\n\t\tif (to.kind !== \"path\" || from.kind !== \"path\") return;\n\t\tconst previous = shapes.get(key);\n\t\tshapes.delete(key);\n\t\tstrings.delete(channelKey(key, \"d\"));\n\t\tconst motion = to.motion;\n\t\tconst plan =\n\t\t\tmotion && from.geometry && to.geometry\n\t\t\t\t? motion.plan(from.geometry, to.geometry)\n\t\t\t\t: undefined;\n\t\tif (!plan) {\n\t\t\t// No meaning to move: the node's own morph, else the numbers of `d`.\n\t\t\tmixString(from, to, \"d\", start);\n\t\t\treturn;\n\t\t}\n\t\tfor (const channel of previous?.plan.targets.keys() ?? []) {\n\t\t\tif (!plan.targets.has(channel)) {\n\t\t\t\tnumbers.delete(channelKey(key, `g${channel}`));\n\t\t\t}\n\t\t}\n\t\tfor (const [channel, goal] of plan.targets) {\n\t\t\tconst was = plan.starts.get(channel) ?? goal;\n\t\t\tspring1(key, `g${channel}`, was, goal, start, now);\n\t\t}\n\t\tshapes.set(key, { plan, motion: motion as GeometryMotion });\n\t}\n\n\tfunction paintNode(node: SceneNode, now: number): SceneNode {\n\t\tif (node.kind === \"group\") {\n\t\t\treturn { ...node, children: paintList(node.children, node.key, now) };\n\t\t}\n\t\tconst key = node.key;\n\t\tconst moved: Numeric = {};\n\t\tfor (const field of FIELDS[node.kind]) {\n\t\t\tmoved[field] = value(\n\t\t\t\tkey,\n\t\t\t\tfield,\n\t\t\t\t(node as unknown as Numeric)[field] as number,\n\t\t\t\tnow,\n\t\t\t);\n\t\t}\n\t\tlet next = { ...node, ...moved } as Exclude<SceneNode, { kind: \"group\" }>;\n\t\tconst shape = shapes.get(key);\n\t\tif (next.kind === \"path\" && shape) {\n\t\t\tconst geometry = shape.plan.build((channel) =>\n\t\t\t\tvalue(key, `g${channel}`, shape.plan.targets.get(channel) ?? 0, now),\n\t\t\t);\n\t\t\tnext = { ...next, geometry, d: shape.motion.draw(geometry) };\n\t\t}\n\t\tconst mixed: Partial<Record<StringChannel, string>> = {};\n\t\tfor (const channel of STRING_CHANNELS) {\n\t\t\tconst motion = strings.get(channelKey(key, channel));\n\t\t\tif (motion) {\n\t\t\t\tmixed[channel] = motion.mix(\n\t\t\t\t\tmotion.generator.at(elapsed(motion, now)).value,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tnext = withStrings(next, mixed) as typeof next;\n\t\tconst opacity = value(key, OPACITY, 1, now);\n\t\tconst drawn = value(key, DRAWN, 1, now);\n\t\tif (opacity === 1 && drawn === 1) return next;\n\t\tconst geometry = next.kind === \"path\" ? next.geometry : undefined;\n\t\tconst length =\n\t\t\tgeometry && next.kind === \"path\" ? next.motion?.length?.(geometry) : 0;\n\t\treturn {\n\t\t\t...next,\n\t\t\tpaint: {\n\t\t\t\t...next.paint,\n\t\t\t\topacity: (next.paint.opacity ?? 1) * clamp(opacity),\n\t\t\t\t...(drawn < 1 && geometry\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tdrawn: {\n\t\t\t\t\t\t\t\tfraction: clamp(drawn),\n\t\t\t\t\t\t\t\tlength: length ?? 0,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}\n\t\t\t\t\t: {}),\n\t\t\t},\n\t\t} as SceneNode;\n\t}\n\n\t/**\n\t * The painted list, with the marks still collapsing after the sibling they\n\t * followed, and the guides still fading back at their places.\n\t */\n\tfunction paintList(\n\t\tlist: readonly SceneNode[],\n\t\tparent: string | null,\n\t\tnow: number,\n\t): SceneNode[] {\n\t\tconst out: SceneNode[] = [];\n\t\tfunction place(after: string | undefined) {\n\t\t\tfor (const [key, exit] of leaving) {\n\t\t\t\tif (exit.after !== after) continue;\n\t\t\t\tout.push(paintNode(exit.node, now));\n\t\t\t\tplace(key);\n\t\t\t}\n\t\t}\n\t\tif (parent === null) place(undefined);\n\t\tfor (const node of list) {\n\t\t\tout.push(paintNode(node, now));\n\t\t\tplace(node.key);\n\t\t}\n\t\tif (guides.size === 0) return out;\n\t\tconst fading = [...guides.values()].map(\n\t\t\t(motion) =>\n\t\t\t\t[\n\t\t\t\t\tmotion.guide,\n\t\t\t\t\tMath.max(0, motion.generator.at(elapsed(motion, now)).value),\n\t\t\t\t] as const,\n\t\t);\n\t\treturn withLeaving(out, parent, fading);\n\t}\n\n\tfunction prune(now: number) {\n\t\tfor (const motions of [numbers, strings, guides]) {\n\t\t\tfor (const [key, motion] of motions) {\n\t\t\t\tif (done(motion, now)) motions.delete(key);\n\t\t\t}\n\t\t}\n\t\tconst moving = new Set(\n\t\t\t[...numbers.keys(), ...strings.keys()].map(\n\t\t\t\t(key) => key.split(SEPARATOR)[0],\n\t\t\t),\n\t\t);\n\t\tfor (const key of shapes.keys()) {\n\t\t\tif (!moving.has(key)) shapes.delete(key);\n\t\t}\n\t\tfor (const key of leaving.keys()) {\n\t\t\tif (!moving.has(key)) leaving.delete(key);\n\t\t}\n\t}\n\n\treturn {\n\t\tretarget(scene, now) {\n\t\t\tconst before = index(target.nodes);\n\t\t\tconst after = index(scene.nodes);\n\t\t\tfunction painted(key: string): SceneNode | undefined {\n\t\t\t\tconst node =\n\t\t\t\t\tbefore.byKey.get(key) ??\n\t\t\t\t\tleaving.get(key)?.node ??\n\t\t\t\t\tguides.get(key)?.guide.node;\n\t\t\t\treturn node && paintNode(node, now);\n\t\t\t}\n\t\t\t// Read before the exits below drop what the guides were showing.\n\t\t\tfor (const guide of leavingGuides(target.nodes, (key) =>\n\t\t\t\tafter.byKey.has(key),\n\t\t\t)) {\n\t\t\t\tguides.set(guide.node.key, {\n\t\t\t\t\tgenerator: generator(value(guide.node.key, OPACITY, 1, now), 0, 0),\n\t\t\t\t\tstart: now,\n\t\t\t\t\tguide,\n\t\t\t\t});\n\t\t\t}\n\t\t\tfor (const key of new Set([...before.byKey.keys(), ...leaving.keys()])) {\n\t\t\t\tif (after.byKey.has(key)) continue;\n\t\t\t\tconst base = (before.byKey.get(key) ??\n\t\t\t\t\tleaving.get(key)?.node) as SceneNode;\n\t\t\t\tconst siblings =\n\t\t\t\t\tbefore.siblings.get(key) ?? leaving.get(key)?.siblings ?? [];\n\t\t\t\tconst goal = exitTo(base, siblings, after.byKey);\n\t\t\t\tconst from = painted(key);\n\t\t\t\tif (!goal || !from) {\n\t\t\t\t\tdrop(key);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tmove(from, goal, now, now);\n\t\t\t\tconst at = siblings.findIndex((node) => node.key === key);\n\t\t\t\tleaving.set(key, {\n\t\t\t\t\tnode: goal,\n\t\t\t\t\tafter: siblings[at - 1]?.key,\n\t\t\t\t\tsiblings,\n\t\t\t\t});\n\t\t\t}\n\t\t\tconst marks = [...after.byKey.values()].filter(\n\t\t\t\t(node) => node.role === \"mark\",\n\t\t\t);\n\t\t\tconst order = new Map(marks.map((node, at) => [node.key, at]));\n\t\t\tfor (const node of after.byKey.values()) {\n\t\t\t\tif (node.kind === \"group\") continue;\n\t\t\t\tconst start =\n\t\t\t\t\tnow +\n\t\t\t\t\tstaggerDelay(timing, order.get(node.key) ?? 0, marks.length) * 1000;\n\t\t\t\tconst old = painted(node.key);\n\t\t\t\tleaving.delete(node.key);\n\t\t\t\tconst from =\n\t\t\t\t\told ??\n\t\t\t\t\tenterFrom(node, after.siblings.get(node.key) ?? [], before.byKey);\n\t\t\t\tif (from) move(from, node, start, now);\n\t\t\t\tconst fading = numbers.get(channelKey(node.key, OPACITY));\n\t\t\t\tconst returning = guides.get(node.key);\n\t\t\t\tif ((!from && node.enter !== \"none\") || fading || returning) {\n\t\t\t\t\tconst shown = returning\n\t\t\t\t\t\t? Math.max(0, returning.generator.at(elapsed(returning, now)).value)\n\t\t\t\t\t\t: fading\n\t\t\t\t\t\t\t? value(node.key, OPACITY, 1, now)\n\t\t\t\t\t\t\t: 0;\n\t\t\t\t\tspring1(node.key, OPACITY, shown, 1, start, now);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (const key of after.byKey.keys()) guides.delete(key);\n\t\t\ttarget = scene;\n\t\t},\n\t\tintroduce(now) {\n\t\t\tlet any = false;\n\t\t\twalk(target.nodes, (node) => {\n\t\t\t\tif (node.kind !== \"path\" || node.enter !== \"draw\") return;\n\t\t\t\tif (node.geometry?.kind !== \"points\" || node.paint.strokeDasharray) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tspring1(node.key, DRAWN, 0, 1, now, now);\n\t\t\t\tany = true;\n\t\t\t});\n\t\t\treturn any;\n\t\t},\n\t\tsnap(scene) {\n\t\t\tfor (const motions of [numbers, strings, guides, shapes, leaving]) {\n\t\t\t\tmotions.clear();\n\t\t\t}\n\t\t\ttarget = scene;\n\t\t},\n\t\tframe(now) {\n\t\t\tprune(now);\n\t\t\tif (numbers.size + strings.size + guides.size === 0) return target;\n\t\t\treturn { ...target, nodes: paintList(target.nodes, null, now) };\n\t\t},\n\t\tsettled(now) {\n\t\t\treturn [\n\t\t\t\t...numbers.values(),\n\t\t\t\t...strings.values(),\n\t\t\t\t...guides.values(),\n\t\t\t].every((motion) => done(motion, now));\n\t\t},\n\t};\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAyB,QAAQ,aAAa;AAC9C,SAAS,WAAW,cAAc;AAClC;AAAA,EAEC;AAAA,EACA;AAAA,OACM;AACP;AAAA,EACC;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACM;AACP,SAA2B,oBAAoB;AAoD/C,MAAM,SAAuD;AAAA,EAC5D,MAAM,CAAC,KAAK,KAAK,SAAS,QAAQ;AAAA,EAClC,QAAQ,CAAC,MAAM,MAAM,GAAG;AAAA,EACxB,MAAM,CAAC,MAAM,MAAM,MAAM,IAAI;AAAA,EAC7B,MAAM,CAAC,KAAK,GAAG;AAAA,EACf,MAAM,CAAC;AAAA,EACP,OAAO,CAAC;AACT;AAEA,MAAM,UAAU;AAChB,MAAM,QAAQ;AACd,MAAM,YAAY;AAElB,SAAS,KACR,OACA,OACC;AACD,aAAW,QAAQ,OAAO;AACzB,UAAM,MAAM,KAAK;AACjB,QAAI,KAAK,SAAS,QAAS,MAAK,KAAK,UAAU,KAAK;AAAA,EACrD;AACD;AAEA,SAAS,MAAM,OAA6B;AAC3C,QAAM,QAAQ,oBAAI,IAAuB;AACzC,QAAM,WAAW,oBAAI,IAAkC;AACvD,OAAK,OAAO,CAAC,MAAM,SAAS;AAC3B,UAAM,IAAI,KAAK,KAAK,IAAI;AACxB,aAAS,IAAI,KAAK,KAAK,IAAI;AAAA,EAC5B,CAAC;AACD,SAAO,EAAE,OAAO,SAAS;AAC1B;AAEA,SAAS,WAAW,MAAc,SAAyB;AAC1D,SAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO;AACrC;AAEA,SAAS,QAAQ,QAAgB,KAAqB;AACrD,SAAO,KAAK,IAAI,IAAI,MAAM,OAAO,SAAS,GAAI;AAC/C;AAEA,SAAS,KAAK,QAAgB,KAAsB;AACnD,SAAO,QAAQ,QAAQ,GAAG,KAAK,OAAO,UAAU;AACjD;AAEA,SAAS,MAAM,OAAuB;AACrC,SAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,CAAC;AACtC;AAEO,SAAS,kBACf,SACA,QACc;AACd,MAAI,SAAS;AACb,QAAM,UAAU,oBAAI,IAAoB;AACxC,QAAM,UAAU,oBAAI,IAA0B;AAC9C,QAAM,SAAS,oBAAI,IAAyB;AAC5C,QAAM,SAAS,oBAAI,IAGjB;AACF,QAAM,UAAU,oBAAI,IAAqB;AAEzC,WAAS,UAAU,MAAc,IAAY,UAA6B;AACzE,WAAO,OAAO,SAAS,WACpB,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,IAChB,CAAC,IACA,MAAM;AAAA,MACN,WAAW,CAAC,MAAM,EAAE;AAAA,MACpB,UAAU,OAAO;AAAA,MACjB,MAAM,OAAO;AAAA,IACd,CAAC;AAAA,EACJ;AAEA,WAAS,MAAM,MAAc,SAAiB,UAAkB,KAAa;AAC5E,UAAM,SAAS,QAAQ,IAAI,WAAW,MAAM,OAAO,CAAC;AACpD,WAAO,SAAS,OAAO,UAAU,GAAG,QAAQ,QAAQ,GAAG,CAAC,EAAE,QAAQ;AAAA,EACnE;AAGA,WAAS,QACR,MACA,SACA,MACA,IACA,OACA,KACC;AACD,UAAM,MAAM,WAAW,MAAM,OAAO;AACpC,UAAM,UAAU,QAAQ,IAAI,GAAG;AAC/B,UAAM,WAAW,UACd,QAAQ,UAAU,GAAG,QAAQ,SAAS,GAAG,CAAC,EAAE,WAC5C;AACH,YAAQ,OAAO,GAAG;AAClB,QAAI,SAAS,MAAM,aAAa,EAAG;AACnC,YAAQ,IAAI,KAAK,EAAE,WAAW,UAAU,MAAM,IAAI,QAAQ,GAAG,MAAM,CAAC;AAAA,EACrE;AAGA,WAAS,UACR,MACA,IACA,SACA,OACC;AACD,UAAM,MAAM,WAAW,GAAG,KAAK,OAAO;AACtC,YAAQ,OAAO,GAAG;AAClB,UAAM,MAAM,SAAS,MAAM,OAAO;AAClC,UAAM,OAAO,SAAS,IAAI,OAAO;AACjC,QAAI,QAAQ,UAAa,SAAS,UAAa,QAAQ,KAAM;AAC7D,YAAQ,IAAI,KAAK;AAAA,MAChB,WAAW,UAAU,GAAG,GAAG,CAAC;AAAA,MAC5B;AAAA,MACA,KAAK,YAAY,IAAI,SAAS,KAAK,IAAI;AAAA,IACxC,CAAC;AAAA,EACF;AAEA,WAAS,KAAK,MAAc;AAC3B,eAAW,WAAW,CAAC,SAAS,OAAO,GAAG;AACzC,iBAAW,OAAO,QAAQ,KAAK,GAAG;AACjC,YAAI,IAAI,WAAW,OAAO,SAAS,EAAG,SAAQ,OAAO,GAAG;AAAA,MACzD;AAAA,IACD;AACA,WAAO,OAAO,IAAI;AAClB,YAAQ,OAAO,IAAI;AAAA,EACpB;AAGA,WAAS,KAAK,MAAiB,IAAe,OAAe,KAAa;AACzE,UAAM,MAAM,GAAG;AACf,eAAW,SAAS,OAAO,GAAG,IAAI,GAAG;AACpC,YAAM,MAAO,KAA4B,KAAK;AAC9C;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACC,GAA0B,KAAK;AAAA,QAChC;AAAA,QACA;AAAA,MACD;AAAA,IACD;AACA,cAAU,MAAM,IAAI,QAAQ,KAAK;AACjC,cAAU,MAAM,IAAI,UAAU,KAAK;AACnC,QAAI,GAAG,SAAS,UAAU,KAAK,SAAS,OAAQ;AAChD,UAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,WAAO,OAAO,GAAG;AACjB,YAAQ,OAAO,WAAW,KAAK,GAAG,CAAC;AACnC,UAAM,SAAS,GAAG;AAClB,UAAM,OACL,UAAU,KAAK,YAAY,GAAG,WAC3B,OAAO,KAAK,KAAK,UAAU,GAAG,QAAQ,IACtC;AACJ,QAAI,CAAC,MAAM;AAEV,gBAAU,MAAM,IAAI,KAAK,KAAK;AAC9B;AAAA,IACD;AACA,eAAW,WAAW,UAAU,KAAK,QAAQ,KAAK,KAAK,CAAC,GAAG;AAC1D,UAAI,CAAC,KAAK,QAAQ,IAAI,OAAO,GAAG;AAC/B,gBAAQ,OAAO,WAAW,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,MAC9C;AAAA,IACD;AACA,eAAW,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS;AAC3C,YAAM,MAAM,KAAK,OAAO,IAAI,OAAO,KAAK;AACxC,cAAQ,KAAK,IAAI,OAAO,IAAI,KAAK,MAAM,OAAO,GAAG;AAAA,IAClD;AACA,WAAO,IAAI,KAAK,EAAE,MAAM,OAAiC,CAAC;AAAA,EAC3D;AAEA,WAAS,UAAU,MAAiB,KAAwB;AAC3D,QAAI,KAAK,SAAS,SAAS;AAC1B,aAAO,EAAE,GAAG,MAAM,UAAU,UAAU,KAAK,UAAU,KAAK,KAAK,GAAG,EAAE;AAAA,IACrE;AACA,UAAM,MAAM,KAAK;AACjB,UAAM,QAAiB,CAAC;AACxB,eAAW,SAAS,OAAO,KAAK,IAAI,GAAG;AACtC,YAAM,KAAK,IAAI;AAAA,QACd;AAAA,QACA;AAAA,QACC,KAA4B,KAAK;AAAA,QAClC;AAAA,MACD;AAAA,IACD;AACA,QAAI,OAAO,EAAE,GAAG,MAAM,GAAG,MAAM;AAC/B,UAAM,QAAQ,OAAO,IAAI,GAAG;AAC5B,QAAI,KAAK,SAAS,UAAU,OAAO;AAClC,YAAMA,YAAW,MAAM,KAAK;AAAA,QAAM,CAAC,YAClC,MAAM,KAAK,IAAI,OAAO,IAAI,MAAM,KAAK,QAAQ,IAAI,OAAO,KAAK,GAAG,GAAG;AAAA,MACpE;AACA,aAAO,EAAE,GAAG,MAAM,UAAAA,WAAU,GAAG,MAAM,OAAO,KAAKA,SAAQ,EAAE;AAAA,IAC5D;AACA,UAAM,QAAgD,CAAC;AACvD,eAAW,WAAW,iBAAiB;AACtC,YAAM,SAAS,QAAQ,IAAI,WAAW,KAAK,OAAO,CAAC;AACnD,UAAI,QAAQ;AACX,cAAM,OAAO,IAAI,OAAO;AAAA,UACvB,OAAO,UAAU,GAAG,QAAQ,QAAQ,GAAG,CAAC,EAAE;AAAA,QAC3C;AAAA,MACD;AAAA,IACD;AACA,WAAO,YAAY,MAAM,KAAK;AAC9B,UAAM,UAAU,MAAM,KAAK,SAAS,GAAG,GAAG;AAC1C,UAAM,QAAQ,MAAM,KAAK,OAAO,GAAG,GAAG;AACtC,QAAI,YAAY,KAAK,UAAU,EAAG,QAAO;AACzC,UAAM,WAAW,KAAK,SAAS,SAAS,KAAK,WAAW;AACxD,UAAM,SACL,YAAY,KAAK,SAAS,SAAS,KAAK,QAAQ,SAAS,QAAQ,IAAI;AACtE,WAAO;AAAA,MACN,GAAG;AAAA,MACH,OAAO;AAAA,QACN,GAAG,KAAK;AAAA,QACR,UAAU,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO;AAAA,QAClD,GAAI,QAAQ,KAAK,WACd;AAAA,UACA,OAAO;AAAA,YACN,UAAU,MAAM,KAAK;AAAA,YACrB,QAAQ,UAAU;AAAA,UACnB;AAAA,QACD,IACC,CAAC;AAAA,MACL;AAAA,IACD;AAAA,EACD;AAMA,WAAS,UACR,MACA,QACA,KACc;AACd,UAAM,MAAmB,CAAC;AAC1B,aAAS,MAAM,OAA2B;AACzC,iBAAW,CAAC,KAAK,IAAI,KAAK,SAAS;AAClC,YAAI,KAAK,UAAU,MAAO;AAC1B,YAAI,KAAK,UAAU,KAAK,MAAM,GAAG,CAAC;AAClC,cAAM,GAAG;AAAA,MACV;AAAA,IACD;AACA,QAAI,WAAW,KAAM,OAAM,MAAS;AACpC,eAAW,QAAQ,MAAM;AACxB,UAAI,KAAK,UAAU,MAAM,GAAG,CAAC;AAC7B,YAAM,KAAK,GAAG;AAAA,IACf;AACA,QAAI,OAAO,SAAS,EAAG,QAAO;AAC9B,UAAM,SAAS,CAAC,GAAG,OAAO,OAAO,CAAC,EAAE;AAAA,MACnC,CAAC,WACA;AAAA,QACC,OAAO;AAAA,QACP,KAAK,IAAI,GAAG,OAAO,UAAU,GAAG,QAAQ,QAAQ,GAAG,CAAC,EAAE,KAAK;AAAA,MAC5D;AAAA,IACF;AACA,WAAO,YAAY,KAAK,QAAQ,MAAM;AAAA,EACvC;AAEA,WAAS,MAAM,KAAa;AAC3B,eAAW,WAAW,CAAC,SAAS,SAAS,MAAM,GAAG;AACjD,iBAAW,CAAC,KAAK,MAAM,KAAK,SAAS;AACpC,YAAI,KAAK,QAAQ,GAAG,EAAG,SAAQ,OAAO,GAAG;AAAA,MAC1C;AAAA,IACD;AACA,UAAM,SAAS,IAAI;AAAA,MAClB,CAAC,GAAG,QAAQ,KAAK,GAAG,GAAG,QAAQ,KAAK,CAAC,EAAE;AAAA,QACtC,CAAC,QAAQ,IAAI,MAAM,SAAS,EAAE,CAAC;AAAA,MAChC;AAAA,IACD;AACA,eAAW,OAAO,OAAO,KAAK,GAAG;AAChC,UAAI,CAAC,OAAO,IAAI,GAAG,EAAG,QAAO,OAAO,GAAG;AAAA,IACxC;AACA,eAAW,OAAO,QAAQ,KAAK,GAAG;AACjC,UAAI,CAAC,OAAO,IAAI,GAAG,EAAG,SAAQ,OAAO,GAAG;AAAA,IACzC;AAAA,EACD;AAEA,SAAO;AAAA,IACN,SAAS,OAAO,KAAK;AACpB,YAAM,SAAS,MAAM,OAAO,KAAK;AACjC,YAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,eAAS,QAAQ,KAAoC;AACpD,cAAM,OACL,OAAO,MAAM,IAAI,GAAG,KACpB,QAAQ,IAAI,GAAG,GAAG,QAClB,OAAO,IAAI,GAAG,GAAG,MAAM;AACxB,eAAO,QAAQ,UAAU,MAAM,GAAG;AAAA,MACnC;AAEA,iBAAW,SAAS;AAAA,QAAc,OAAO;AAAA,QAAO,CAAC,QAChD,MAAM,MAAM,IAAI,GAAG;AAAA,MACpB,GAAG;AACF,eAAO,IAAI,MAAM,KAAK,KAAK;AAAA,UAC1B,WAAW,UAAU,MAAM,MAAM,KAAK,KAAK,SAAS,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,UACjE,OAAO;AAAA,UACP;AAAA,QACD,CAAC;AAAA,MACF;AACA,iBAAW,OAAO,oBAAI,IAAI,CAAC,GAAG,OAAO,MAAM,KAAK,GAAG,GAAG,QAAQ,KAAK,CAAC,CAAC,GAAG;AACvE,YAAI,MAAM,MAAM,IAAI,GAAG,EAAG;AAC1B,cAAM,OAAQ,OAAO,MAAM,IAAI,GAAG,KACjC,QAAQ,IAAI,GAAG,GAAG;AACnB,cAAM,WACL,OAAO,SAAS,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,GAAG,YAAY,CAAC;AAC5D,cAAM,OAAO,OAAO,MAAM,UAAU,MAAM,KAAK;AAC/C,cAAM,OAAO,QAAQ,GAAG;AACxB,YAAI,CAAC,QAAQ,CAAC,MAAM;AACnB,eAAK,GAAG;AACR;AAAA,QACD;AACA,aAAK,MAAM,MAAM,KAAK,GAAG;AACzB,cAAM,KAAK,SAAS,UAAU,CAAC,SAAS,KAAK,QAAQ,GAAG;AACxD,gBAAQ,IAAI,KAAK;AAAA,UAChB,MAAM;AAAA,UACN,OAAO,SAAS,KAAK,CAAC,GAAG;AAAA,UACzB;AAAA,QACD,CAAC;AAAA,MACF;AACA,YAAM,QAAQ,CAAC,GAAG,MAAM,MAAM,OAAO,CAAC,EAAE;AAAA,QACvC,CAAC,SAAS,KAAK,SAAS;AAAA,MACzB;AACA,YAAM,QAAQ,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,OAAO,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;AAC7D,iBAAW,QAAQ,MAAM,MAAM,OAAO,GAAG;AACxC,YAAI,KAAK,SAAS,QAAS;AAC3B,cAAM,QACL,MACA,aAAa,QAAQ,MAAM,IAAI,KAAK,GAAG,KAAK,GAAG,MAAM,MAAM,IAAI;AAChE,cAAM,MAAM,QAAQ,KAAK,GAAG;AAC5B,gBAAQ,OAAO,KAAK,GAAG;AACvB,cAAM,OACL,OACA,UAAU,MAAM,MAAM,SAAS,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,OAAO,KAAK;AACjE,YAAI,KAAM,MAAK,MAAM,MAAM,OAAO,GAAG;AACrC,cAAM,SAAS,QAAQ,IAAI,WAAW,KAAK,KAAK,OAAO,CAAC;AACxD,cAAM,YAAY,OAAO,IAAI,KAAK,GAAG;AACrC,YAAK,CAAC,QAAQ,KAAK,UAAU,UAAW,UAAU,WAAW;AAC5D,gBAAM,QAAQ,YACX,KAAK,IAAI,GAAG,UAAU,UAAU,GAAG,QAAQ,WAAW,GAAG,CAAC,EAAE,KAAK,IACjE,SACC,MAAM,KAAK,KAAK,SAAS,GAAG,GAAG,IAC/B;AACJ,kBAAQ,KAAK,KAAK,SAAS,OAAO,GAAG,OAAO,GAAG;AAAA,QAChD;AAAA,MACD;AACA,iBAAW,OAAO,MAAM,MAAM,KAAK,EAAG,QAAO,OAAO,GAAG;AACvD,eAAS;AAAA,IACV;AAAA,IACA,UAAU,KAAK;AACd,UAAI,MAAM;AACV,WAAK,OAAO,OAAO,CAAC,SAAS;AAC5B,YAAI,KAAK,SAAS,UAAU,KAAK,UAAU,OAAQ;AACnD,YAAI,KAAK,UAAU,SAAS,YAAY,KAAK,MAAM,iBAAiB;AACnE;AAAA,QACD;AACA,gBAAQ,KAAK,KAAK,OAAO,GAAG,GAAG,KAAK,GAAG;AACvC,cAAM;AAAA,MACP,CAAC;AACD,aAAO;AAAA,IACR;AAAA,IACA,KAAK,OAAO;AACX,iBAAW,WAAW,CAAC,SAAS,SAAS,QAAQ,QAAQ,OAAO,GAAG;AAClE,gBAAQ,MAAM;AAAA,MACf;AACA,eAAS;AAAA,IACV;AAAA,IACA,MAAM,KAAK;AACV,YAAM,GAAG;AACT,UAAI,QAAQ,OAAO,QAAQ,OAAO,OAAO,SAAS,EAAG,QAAO;AAC5D,aAAO,EAAE,GAAG,QAAQ,OAAO,UAAU,OAAO,OAAO,MAAM,GAAG,EAAE;AAAA,IAC/D;AAAA,IACA,QAAQ,KAAK;AACZ,aAAO;AAAA,QACN,GAAG,QAAQ,OAAO;AAAA,QAClB,GAAG,QAAQ,OAAO;AAAA,QAClB,GAAG,OAAO,OAAO;AAAA,MAClB,EAAE,MAAM,CAAC,WAAW,KAAK,QAAQ,GAAG,CAAC;AAAA,IACtC;AAAA,EACD;AACD;",
|
|
6
|
+
"names": ["geometry"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { GeometryMotion, SceneGeometry } from "../types.js";
|
|
2
|
+
/** A line, an area or a radar outline through its points. */
|
|
3
|
+
export declare function pointsPath(geometry: SceneGeometry): string;
|
|
4
|
+
/** Lines, areas and radar outlines: points keyed by x (or by axis). */
|
|
5
|
+
export declare const POINTS_MOTION: GeometryMotion;
|
|
6
|
+
//# sourceMappingURL=points-motion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"points-motion.d.ts","sourceRoot":"","sources":["../../../src/core/motion/points-motion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,cAAc,EAGd,aAAa,EAEb,MAAM,iBAAiB,CAAC;AAMzB,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAkB1D;AAoJD,uEAAuE;AACvE,eAAO,MAAM,aAAa,EAAE,cAQ3B,CAAC"}
|