@brytdesigns/web-component-parallax 1.2.17 → 1.2.19
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/esm/index.js +58 -330
- package/dist/esm/index.js.map +1 -1
- package/dist/main/components/parallax-animation/index.js +13 -4
- package/dist/main/components/parallax-animation/index.js.map +1 -1
- package/dist/main/hooks/useParallaxStickyLayer.js +49 -330
- package/dist/main/hooks/useParallaxStickyLayer.js.map +1 -1
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -2,7 +2,9 @@ import { createWithElementContext, customShadowlessElement, correctElementType,
|
|
|
2
2
|
import { splitProps, createEffect, batch, onCleanup, mergeProps, createMemo } from 'solid-js';
|
|
3
3
|
import { createStore } from 'solid-js/store';
|
|
4
4
|
import { createContext, consume, provide } from 'component-register';
|
|
5
|
-
import { motionValue, scroll,
|
|
5
|
+
import { motionValue, scroll, transformValue, transform, frame, animate, styleEffect } from 'motion';
|
|
6
|
+
import { awaitAllAnimations } from '@brytdesigns/web-component-core/animation';
|
|
7
|
+
import { abortablePromise } from '@brytdesigns/web-component-core/promise';
|
|
6
8
|
|
|
7
9
|
var __defProp = Object.defineProperty;
|
|
8
10
|
var __export = (target, all) => {
|
|
@@ -118,48 +120,29 @@ function getLastTruthyIndex(values) {
|
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
// src/hooks/useParallaxStickyLayer.ts
|
|
121
|
-
var HANDOFF_EASE = "easeOut";
|
|
122
|
-
var ENTER_HYSTERESIS = 1e-3;
|
|
123
|
-
var EXIT_HYSTERESIS = 5e-3;
|
|
124
|
-
var HANDOFF_MIN_DELTA_PX = 0.75;
|
|
125
|
-
var EXIT_WAIT_TIMEOUT_MS = 500;
|
|
126
|
-
var PREDICT_LOOKAHEAD_MS = 28;
|
|
127
|
-
var PREDICT_ENTER_BAND = 6e-3;
|
|
128
|
-
var PREDICT_EXIT_BAND = 0.01;
|
|
129
|
-
var PREDICT_MIN_VELOCITY = 4e-4;
|
|
130
|
-
var LOW_VELOCITY_NO_TWEEN = 1e-3;
|
|
131
|
-
var HIGH_VELOCITY_SKIP_HANDOFF = 0.01;
|
|
132
|
-
var MAX_PREDICT_LOOKAHEAD_MS = 60;
|
|
133
|
-
var MAX_HANDOFF_DELTA_PX = 56;
|
|
134
|
-
function supportsStickyPosition() {
|
|
135
|
-
if (typeof CSS === "undefined" || typeof CSS.supports !== "function") {
|
|
136
|
-
return false;
|
|
137
|
-
}
|
|
138
|
-
return CSS.supports("position", "sticky") || CSS.supports("position", "-webkit-sticky");
|
|
139
|
-
}
|
|
140
123
|
function initializeParallaxStickyLayerContext(props) {
|
|
141
124
|
const [_internal, _state] = splitProps(props, ["root", "start", "end"]);
|
|
142
125
|
const parallax = useParallax(_internal.root);
|
|
143
|
-
const stickySupported = supportsStickyPosition();
|
|
144
126
|
const progress = motionValue(-1);
|
|
145
|
-
const rawScrollProgress = motionValue(-1);
|
|
146
127
|
const inRange = motionValue(false);
|
|
147
128
|
const belowRange = motionValue(false);
|
|
148
129
|
const aboveRange = motionValue(false);
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
const
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
130
|
+
const position = transformValue(
|
|
131
|
+
() => inRange.get() ? "sticky" : "absolute"
|
|
132
|
+
);
|
|
133
|
+
const transform$1 = transformValue(() => {
|
|
134
|
+
const isInRange2 = inRange.get();
|
|
135
|
+
const isBelowRange = belowRange.get();
|
|
136
|
+
const isAboveRange = aboveRange.get();
|
|
137
|
+
if (isInRange2) return "none";
|
|
138
|
+
if (isBelowRange) return `translate(0px, ${(_internal.start - 1) * 100}vh)`;
|
|
139
|
+
if (isAboveRange) return `translate(0px, ${(_internal.end - 1) * 100}vh)`;
|
|
140
|
+
});
|
|
141
|
+
const animations = motionValue([]);
|
|
142
|
+
const styles = transformValue(() => ({
|
|
143
|
+
position: position.get(),
|
|
144
|
+
transform: transform$1.get()
|
|
145
|
+
}));
|
|
163
146
|
_internal.root.style.top = "0px";
|
|
164
147
|
_internal.root.style.right = "0px";
|
|
165
148
|
_internal.root.style.bottom = "0px";
|
|
@@ -170,315 +153,51 @@ function initializeParallaxStickyLayerContext(props) {
|
|
|
170
153
|
if (window.getComputedStyle(_internal.root).display === "inline") {
|
|
171
154
|
_internal.root.style.display = "block";
|
|
172
155
|
}
|
|
173
|
-
function updateStyles() {
|
|
174
|
-
if (!stickySupported) {
|
|
175
|
-
const normStart = normStartValue.get();
|
|
176
|
-
const normEnd = normEndValue.get();
|
|
177
|
-
const raw = rawScrollProgress.get();
|
|
178
|
-
const span = Math.max(normEnd - normStart, Number.EPSILON);
|
|
179
|
-
const t = Math.min(Math.max((raw - normStart) / span, 0), 1);
|
|
180
|
-
const pageY = _internal.start - 1 + t * (_internal.end - _internal.start);
|
|
181
|
-
_internal.root.style.position = "absolute";
|
|
182
|
-
_internal.root.style.transform = `translate(0px, ${pageY * 100}vh)`;
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
const currentMode = mode.get();
|
|
186
|
-
const offset = handoffOffsetY.get();
|
|
187
|
-
const hasOffset = Math.abs(offset) >= 0.1;
|
|
188
|
-
if (currentMode === "sticky") {
|
|
189
|
-
_internal.root.style.position = "sticky";
|
|
190
|
-
_internal.root.style.transform = hasOffset ? `translate(0px, ${offset}px)` : "none";
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
const baseTransform = currentMode === "absolute-below" ? `translate(0px, ${(_internal.start - 1) * 100}vh)` : `translate(0px, ${(_internal.end - 1) * 100}vh)`;
|
|
194
|
-
_internal.root.style.position = "absolute";
|
|
195
|
-
_internal.root.style.transform = hasOffset ? `${baseTransform} translate(0px, ${offset}px)` : baseTransform;
|
|
196
|
-
}
|
|
197
|
-
function renderStyles() {
|
|
198
|
-
frame.render(updateStyles);
|
|
199
|
-
}
|
|
200
|
-
function stopHandoffAnimation() {
|
|
201
|
-
handoffAnimation?.stop();
|
|
202
|
-
handoffAnimation = null;
|
|
203
|
-
handoffOffsetY.set(0);
|
|
204
|
-
}
|
|
205
|
-
function clearExitWaitHandles() {
|
|
206
|
-
if (exitWaitRaf !== null) {
|
|
207
|
-
window.cancelAnimationFrame(exitWaitRaf);
|
|
208
|
-
exitWaitRaf = null;
|
|
209
|
-
}
|
|
210
|
-
if (exitWaitTimeout !== null) {
|
|
211
|
-
window.clearTimeout(exitWaitTimeout);
|
|
212
|
-
exitWaitTimeout = null;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
function pruneFinishedAnimations() {
|
|
216
|
-
for (const animation of activeContentAnimations) {
|
|
217
|
-
if (animation.state !== "running") {
|
|
218
|
-
activeContentAnimations.delete(animation);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
function hasActiveContentAnimations() {
|
|
223
|
-
pruneFinishedAnimations();
|
|
224
|
-
return activeContentAnimations.size > 0;
|
|
225
|
-
}
|
|
226
|
-
function registerContentAnimation(animation) {
|
|
227
|
-
activeContentAnimations.add(animation);
|
|
228
|
-
animation.then(
|
|
229
|
-
() => {
|
|
230
|
-
activeContentAnimations.delete(animation);
|
|
231
|
-
},
|
|
232
|
-
() => {
|
|
233
|
-
activeContentAnimations.delete(animation);
|
|
234
|
-
}
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
function getHandoffDuration(deltaY, velocity) {
|
|
238
|
-
const speed = Math.abs(velocity);
|
|
239
|
-
if (speed <= LOW_VELOCITY_NO_TWEEN) return 0;
|
|
240
|
-
const byDistance = Math.min(0.12, Math.max(0.05, Math.abs(deltaY) / 1400));
|
|
241
|
-
const speedScale = Math.min(speed / 0.01, 1);
|
|
242
|
-
return Math.max(0.04, byDistance - speedScale * 0.02);
|
|
243
|
-
}
|
|
244
|
-
function settleHandoffOverFrames(deltaY, frameCount) {
|
|
245
|
-
handoffOffsetY.set(deltaY);
|
|
246
|
-
updateStyles();
|
|
247
|
-
let remainingFrames = Math.max(frameCount, 1);
|
|
248
|
-
const settle = () => {
|
|
249
|
-
remainingFrames -= 1;
|
|
250
|
-
if (remainingFrames <= 0) {
|
|
251
|
-
handoffOffsetY.set(0);
|
|
252
|
-
updateStyles();
|
|
253
|
-
return;
|
|
254
|
-
}
|
|
255
|
-
frame.render(settle);
|
|
256
|
-
};
|
|
257
|
-
frame.render(settle);
|
|
258
|
-
}
|
|
259
|
-
function cancelPendingExit() {
|
|
260
|
-
pendingExitVersion += 1;
|
|
261
|
-
pendingExitMode = null;
|
|
262
|
-
clearExitWaitHandles();
|
|
263
|
-
}
|
|
264
|
-
function commitModeImmediately(nextMode) {
|
|
265
|
-
stopHandoffAnimation();
|
|
266
|
-
mode.set(nextMode);
|
|
267
|
-
updateStyles();
|
|
268
|
-
}
|
|
269
|
-
function waitForAnimations(nextMode) {
|
|
270
|
-
if (pendingExitMode === nextMode && (exitWaitRaf !== null || exitWaitTimeout !== null)) {
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
cancelPendingExit();
|
|
274
|
-
pendingExitMode = nextMode;
|
|
275
|
-
const version = pendingExitVersion;
|
|
276
|
-
const completeExit = () => {
|
|
277
|
-
if (version !== pendingExitVersion) return;
|
|
278
|
-
clearExitWaitHandles();
|
|
279
|
-
pendingExitMode = null;
|
|
280
|
-
const latest = Math.min(Math.max(rawScrollProgress.get(), 0), 1);
|
|
281
|
-
const stableMode = getTargetMode(
|
|
282
|
-
latest,
|
|
283
|
-
normStartValue.get(),
|
|
284
|
-
normEndValue.get()
|
|
285
|
-
);
|
|
286
|
-
if (stableMode !== nextMode) return;
|
|
287
|
-
commitModeImmediately(nextMode);
|
|
288
|
-
};
|
|
289
|
-
if (!hasActiveContentAnimations()) {
|
|
290
|
-
completeExit();
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const tick = () => {
|
|
294
|
-
if (version !== pendingExitVersion) return;
|
|
295
|
-
if (!hasActiveContentAnimations()) {
|
|
296
|
-
completeExit();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
|
-
exitWaitRaf = window.requestAnimationFrame(tick);
|
|
300
|
-
};
|
|
301
|
-
exitWaitTimeout = window.setTimeout(() => {
|
|
302
|
-
completeExit();
|
|
303
|
-
}, EXIT_WAIT_TIMEOUT_MS);
|
|
304
|
-
exitWaitRaf = window.requestAnimationFrame(tick);
|
|
305
|
-
}
|
|
306
|
-
function getTargetMode(value, normStart, normEnd) {
|
|
307
|
-
if (!stickySupported) {
|
|
308
|
-
if (value <= normStart) return "absolute-below";
|
|
309
|
-
if (value >= normEnd) return "absolute-above";
|
|
310
|
-
return "absolute-below";
|
|
311
|
-
}
|
|
312
|
-
const current = mode.get();
|
|
313
|
-
if (current === "sticky") {
|
|
314
|
-
if (value < normStart - EXIT_HYSTERESIS) return "absolute-below";
|
|
315
|
-
if (value > normEnd + EXIT_HYSTERESIS) return "absolute-above";
|
|
316
|
-
return "sticky";
|
|
317
|
-
}
|
|
318
|
-
if (current === "absolute-below") {
|
|
319
|
-
if (value >= normStart + ENTER_HYSTERESIS) return "sticky";
|
|
320
|
-
return "absolute-below";
|
|
321
|
-
}
|
|
322
|
-
if (value <= normEnd - ENTER_HYSTERESIS) return "sticky";
|
|
323
|
-
return "absolute-above";
|
|
324
|
-
}
|
|
325
|
-
function getModeDecisionValue(value, normStart, normEnd, allowPrediction) {
|
|
326
|
-
const now = performance.now();
|
|
327
|
-
let velocity = 0;
|
|
328
|
-
if (hasScrollSample) {
|
|
329
|
-
const elapsed = Math.max(now - lastScrollSampleTime, 1);
|
|
330
|
-
velocity = (value - lastScrollSampleValue) / elapsed;
|
|
331
|
-
}
|
|
332
|
-
lastScrollSampleValue = value;
|
|
333
|
-
lastScrollSampleTime = now;
|
|
334
|
-
hasScrollSample = true;
|
|
335
|
-
latestScrollVelocity = velocity;
|
|
336
|
-
if (!allowPrediction || Math.abs(velocity) < PREDICT_MIN_VELOCITY) {
|
|
337
|
-
return value;
|
|
338
|
-
}
|
|
339
|
-
const speed = Math.abs(velocity);
|
|
340
|
-
const speedScale = Math.min(speed / HIGH_VELOCITY_SKIP_HANDOFF, 1);
|
|
341
|
-
const lookaheadMs = PREDICT_LOOKAHEAD_MS + speedScale * (MAX_PREDICT_LOOKAHEAD_MS - PREDICT_LOOKAHEAD_MS);
|
|
342
|
-
const predicted = Math.min(Math.max(value + velocity * lookaheadMs, 0), 1);
|
|
343
|
-
const currentMode = mode.get();
|
|
344
|
-
if (currentMode === "absolute-below") {
|
|
345
|
-
const entryEdge = normStart + ENTER_HYSTERESIS;
|
|
346
|
-
const nearStart = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;
|
|
347
|
-
if (velocity > 0 && nearStart && value < entryEdge && predicted >= entryEdge) {
|
|
348
|
-
return entryEdge;
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
if (currentMode === "absolute-above") {
|
|
352
|
-
const entryEdge = normEnd - ENTER_HYSTERESIS;
|
|
353
|
-
const nearEnd = Math.abs(value - entryEdge) <= PREDICT_ENTER_BAND;
|
|
354
|
-
if (velocity < 0 && nearEnd && value > entryEdge && predicted <= entryEdge) {
|
|
355
|
-
return entryEdge;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
if (currentMode === "sticky") {
|
|
359
|
-
const exitTopEdge = normStart - EXIT_HYSTERESIS;
|
|
360
|
-
const exitBottomEdge = normEnd + EXIT_HYSTERESIS;
|
|
361
|
-
const nearTop = Math.abs(value - exitTopEdge) <= PREDICT_EXIT_BAND;
|
|
362
|
-
if (velocity < 0 && nearTop && value > exitTopEdge && predicted <= exitTopEdge) {
|
|
363
|
-
return exitTopEdge;
|
|
364
|
-
}
|
|
365
|
-
const nearBottom = Math.abs(value - exitBottomEdge) <= PREDICT_EXIT_BAND;
|
|
366
|
-
if (velocity > 0 && nearBottom && value < exitBottomEdge && predicted >= exitBottomEdge) {
|
|
367
|
-
return exitBottomEdge;
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
return value;
|
|
371
|
-
}
|
|
372
|
-
function applyModeWithHandoff(nextMode) {
|
|
373
|
-
if (!stickySupported) {
|
|
374
|
-
stopHandoffAnimation();
|
|
375
|
-
mode.set(nextMode);
|
|
376
|
-
renderStyles();
|
|
377
|
-
return;
|
|
378
|
-
}
|
|
379
|
-
stopHandoffAnimation();
|
|
380
|
-
const prevRect = _internal.root.getBoundingClientRect();
|
|
381
|
-
mode.set(nextMode);
|
|
382
|
-
updateStyles();
|
|
383
|
-
const nextRect = _internal.root.getBoundingClientRect();
|
|
384
|
-
const deltaY = prevRect.top - nextRect.top;
|
|
385
|
-
if (Math.abs(deltaY) <= HANDOFF_MIN_DELTA_PX) {
|
|
386
|
-
handoffOffsetY.set(0);
|
|
387
|
-
renderStyles();
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
if (Math.abs(latestScrollVelocity) >= HIGH_VELOCITY_SKIP_HANDOFF || Math.abs(deltaY) >= MAX_HANDOFF_DELTA_PX) {
|
|
391
|
-
settleHandoffOverFrames(deltaY, 2);
|
|
392
|
-
return;
|
|
393
|
-
}
|
|
394
|
-
handoffOffsetY.set(deltaY);
|
|
395
|
-
updateStyles();
|
|
396
|
-
const duration = getHandoffDuration(deltaY, latestScrollVelocity);
|
|
397
|
-
if (duration <= 0) {
|
|
398
|
-
settleHandoffOverFrames(deltaY, 1);
|
|
399
|
-
return;
|
|
400
|
-
}
|
|
401
|
-
handoffAnimation = animate([
|
|
402
|
-
[handoffOffsetY, 0, { duration, ease: HANDOFF_EASE }]
|
|
403
|
-
]);
|
|
404
|
-
handoffAnimation.then(() => {
|
|
405
|
-
if (!handoffAnimation) return;
|
|
406
|
-
handoffAnimation = null;
|
|
407
|
-
handoffOffsetY.set(0);
|
|
408
|
-
renderStyles();
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
function syncFromScroll(value, allowHandoff) {
|
|
412
|
-
const clamped = Math.min(Math.max(value, 0), 1);
|
|
413
|
-
rawScrollProgress.set(clamped);
|
|
414
|
-
const normStart = normStartValue.get();
|
|
415
|
-
const normEnd = normEndValue.get();
|
|
416
|
-
const range = [normStart, normEnd];
|
|
417
|
-
const span = Math.max(normEnd - normStart, Number.EPSILON);
|
|
418
|
-
const normalizedProgress = Math.min(
|
|
419
|
-
Math.max((clamped - normStart) / span, 0),
|
|
420
|
-
1
|
|
421
|
-
);
|
|
422
|
-
inRange.set(isInRange({ range, value: clamped }));
|
|
423
|
-
belowRange.set(clamped <= normStart);
|
|
424
|
-
aboveRange.set(clamped >= normEnd);
|
|
425
|
-
progress.set(normalizedProgress);
|
|
426
|
-
const decisionValue = getModeDecisionValue(
|
|
427
|
-
clamped,
|
|
428
|
-
normStart,
|
|
429
|
-
normEnd,
|
|
430
|
-
allowHandoff
|
|
431
|
-
);
|
|
432
|
-
const nextMode = getTargetMode(decisionValue, normStart, normEnd);
|
|
433
|
-
const currentMode = mode.get();
|
|
434
|
-
if (currentMode === "sticky" && nextMode !== "sticky" && allowHandoff) {
|
|
435
|
-
waitForAnimations(nextMode);
|
|
436
|
-
updateStyles();
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
cancelPendingExit();
|
|
440
|
-
if (nextMode === currentMode) {
|
|
441
|
-
if (!allowHandoff) {
|
|
442
|
-
stopHandoffAnimation();
|
|
443
|
-
updateStyles();
|
|
444
|
-
}
|
|
445
|
-
return;
|
|
446
|
-
}
|
|
447
|
-
if (allowHandoff) {
|
|
448
|
-
applyModeWithHandoff(nextMode);
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
commitModeImmediately(nextMode);
|
|
452
|
-
}
|
|
453
156
|
createEffect(() => {
|
|
454
157
|
const range = [_internal.start, _internal.end];
|
|
455
158
|
const maxPages = parallax.maxPages;
|
|
456
159
|
const normalizedRange = normalizeTuple(range, maxPages);
|
|
457
160
|
const [normStart, normEnd] = normalizedRange;
|
|
458
|
-
|
|
459
|
-
normEndValue.set(normEnd);
|
|
460
|
-
const initialValue = parallax.scrollYProgress.get();
|
|
461
|
-
syncFromScroll(initialValue, false);
|
|
462
|
-
renderStyles();
|
|
161
|
+
const transformer = transform(normalizedRange, [0, 1]);
|
|
463
162
|
const unsubscribe = parallax.scrollYProgress.on("change", (value) => {
|
|
464
|
-
|
|
163
|
+
inRange.set(isInRange({ range: normalizedRange, value }));
|
|
164
|
+
belowRange.set(value <= normStart);
|
|
165
|
+
aboveRange.set(value >= normEnd);
|
|
166
|
+
progress.set(transformer(value));
|
|
465
167
|
});
|
|
466
168
|
return onCleanup(() => {
|
|
467
169
|
unsubscribe();
|
|
468
170
|
});
|
|
469
171
|
});
|
|
470
|
-
|
|
172
|
+
function updateStyles() {
|
|
173
|
+
const s = styles.get();
|
|
174
|
+
_internal.root.style.position = s.position;
|
|
175
|
+
_internal.root.style.transform = s.transform;
|
|
176
|
+
}
|
|
177
|
+
function renderStyles() {
|
|
178
|
+
frame.render(updateStyles);
|
|
179
|
+
}
|
|
180
|
+
function waitForAnimations() {
|
|
181
|
+
const a = animations.get();
|
|
182
|
+
const controller = new AbortController();
|
|
183
|
+
abortablePromise(awaitAllAnimations(a), controller.signal).then(() => {
|
|
184
|
+
animations.set([]);
|
|
185
|
+
renderStyles();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const unsubStyles = styles.on("change", (_) => {
|
|
189
|
+
if (progress.get() === 1 || progress.get() === 0)
|
|
190
|
+
return waitForAnimations();
|
|
191
|
+
animations.set([]);
|
|
471
192
|
renderStyles();
|
|
472
193
|
});
|
|
473
194
|
function _animate(...args) {
|
|
474
195
|
const animation = animate(...args);
|
|
475
|
-
|
|
196
|
+
animations.set([...animations.get(), animation]);
|
|
476
197
|
return animation;
|
|
477
198
|
}
|
|
478
199
|
onCleanup(() => {
|
|
479
|
-
|
|
480
|
-
stopHandoffAnimation();
|
|
481
|
-
unsubHandoffOffset();
|
|
200
|
+
unsubStyles();
|
|
482
201
|
});
|
|
483
202
|
return [progress, { animate: _animate }];
|
|
484
203
|
}
|
|
@@ -681,6 +400,7 @@ ${messages.join("\n")}`
|
|
|
681
400
|
const active = activeProps();
|
|
682
401
|
const { range, ...props2 } = active;
|
|
683
402
|
const valueSubscribers = [];
|
|
403
|
+
let disposed = false;
|
|
684
404
|
const progressValue = Object.keys(PROP_DEFAULTS).reduce(
|
|
685
405
|
(values, key) => {
|
|
686
406
|
const fallback = Reflect.get(PROP_DEFAULTS, key);
|
|
@@ -714,11 +434,16 @@ ${messages.join("\n")}`
|
|
|
714
434
|
() => `translate(${animated.x?.get()}, ${animated.y?.get()}) scale(${animated.scale?.get()}) rotate(${animated.rotate?.get()}deg)`
|
|
715
435
|
);
|
|
716
436
|
function animateValues() {
|
|
437
|
+
if (disposed) return;
|
|
717
438
|
const sequence = Object.keys(animated).map((key) => {
|
|
718
|
-
|
|
719
|
-
|
|
439
|
+
const subject = animated[key];
|
|
440
|
+
const v = progressValue[key]?.get?.();
|
|
441
|
+
if (!subject) return null;
|
|
442
|
+
if (typeof v === "undefined" || v === null) return null;
|
|
443
|
+
if (typeof v !== "string" && typeof v !== "number") return null;
|
|
720
444
|
return [animated[key], v, { at: "<" }];
|
|
721
445
|
}).filter((v) => v !== null);
|
|
446
|
+
if (sequence.length === 0) return;
|
|
722
447
|
animate2(sequence);
|
|
723
448
|
}
|
|
724
449
|
function scheduleAnimation() {
|
|
@@ -738,9 +463,12 @@ ${messages.join("\n")}`
|
|
|
738
463
|
...styledValues
|
|
739
464
|
});
|
|
740
465
|
return onCleanup(() => {
|
|
466
|
+
disposed = true;
|
|
741
467
|
unstyle();
|
|
742
468
|
unsub();
|
|
743
|
-
valueSubscribers.forEach((unsub2) =>
|
|
469
|
+
valueSubscribers.forEach((unsub2) => {
|
|
470
|
+
unsub2();
|
|
471
|
+
});
|
|
744
472
|
Object.values(animated).forEach((value) => {
|
|
745
473
|
value.destroy();
|
|
746
474
|
});
|