@pixodesk/svg-animator-web 1.0.27 → 1.0.29
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/index.cjs +227 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +226 -18
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.prerendered-waapi.umd.js.map +1 -1
- package/dist/index.prerendered.umd.js +155 -8
- package/dist/index.prerendered.umd.js.map +1 -1
- package/dist/index.prerendered.umd.min.js +1 -1
- package/dist/index.umd.js +225 -18
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -1
- package/package.json +2 -2
|
@@ -2258,6 +2258,10 @@ var PixodeskAnimator = (() => {
|
|
|
2258
2258
|
if (!config || !isScrollTimeline(config)) return null;
|
|
2259
2259
|
const scroll = config.scroll || {};
|
|
2260
2260
|
const kind = (_a = scroll.kind) != null ? _a : "view";
|
|
2261
|
+
if (scroll.smoothing) {
|
|
2262
|
+
console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
|
|
2263
|
+
return null;
|
|
2264
|
+
}
|
|
2261
2265
|
const g = globalThis;
|
|
2262
2266
|
const view = kind === "view";
|
|
2263
2267
|
const Ctor = view ? g.ViewTimeline : g.ScrollTimeline;
|
|
@@ -2266,7 +2270,7 @@ var PixodeskAnimator = (() => {
|
|
|
2266
2270
|
let timeline;
|
|
2267
2271
|
try {
|
|
2268
2272
|
if (view) {
|
|
2269
|
-
timeline = new Ctor({ subject, axis });
|
|
2273
|
+
timeline = new Ctor({ subject: resolveScrollSubject(subject, scroll.subject), axis });
|
|
2270
2274
|
} else {
|
|
2271
2275
|
const source = scroll.source === "root" ? documentScroller() : findNearestScroller(subject, "y") || findNearestScroller(subject, "x") || documentScroller();
|
|
2272
2276
|
timeline = new Ctor({ source, axis });
|
|
@@ -2282,7 +2286,10 @@ var PixodeskAnimator = (() => {
|
|
|
2282
2286
|
};
|
|
2283
2287
|
}
|
|
2284
2288
|
function findNearestScroller(el, axis) {
|
|
2289
|
+
const body = document.body;
|
|
2290
|
+
const root = document.documentElement;
|
|
2285
2291
|
for (let p = el.parentElement; p; p = p.parentElement) {
|
|
2292
|
+
if (p === body || p === root) return null;
|
|
2286
2293
|
const style = getComputedStyle(p);
|
|
2287
2294
|
const overflow = axis === "y" ? style.overflowY : style.overflowX;
|
|
2288
2295
|
if (overflow === "auto" || overflow === "scroll" || overflow === "hidden" || overflow === "overlay") {
|
|
@@ -2294,11 +2301,42 @@ var PixodeskAnimator = (() => {
|
|
|
2294
2301
|
function documentScroller() {
|
|
2295
2302
|
return document.scrollingElement || document.documentElement;
|
|
2296
2303
|
}
|
|
2304
|
+
var SUBJECT_PARENT = "parent";
|
|
2305
|
+
var SUBJECT_SCROLLER = "scroller";
|
|
2306
|
+
function resolveScrollSubject(svgRoot, subject) {
|
|
2307
|
+
var _a, _b;
|
|
2308
|
+
const spec = subject == null ? void 0 : subject.trim();
|
|
2309
|
+
if (!spec) return svgRoot;
|
|
2310
|
+
if (spec === SUBJECT_PARENT) {
|
|
2311
|
+
let outermostPinned = null;
|
|
2312
|
+
for (let p = svgRoot.parentElement; p && p !== document.body; p = p.parentElement) {
|
|
2313
|
+
const position = getComputedStyle(p).position;
|
|
2314
|
+
if (position === "sticky" || position === "fixed") outermostPinned = p;
|
|
2315
|
+
}
|
|
2316
|
+
return (_b = (_a = outermostPinned == null ? void 0 : outermostPinned.parentElement) != null ? _a : svgRoot.parentElement) != null ? _b : svgRoot;
|
|
2317
|
+
}
|
|
2318
|
+
if (spec === SUBJECT_SCROLLER) {
|
|
2319
|
+
return findNearestScroller(svgRoot, "y") || findNearestScroller(svgRoot, "x") || documentScroller();
|
|
2320
|
+
}
|
|
2321
|
+
let found = null;
|
|
2322
|
+
try {
|
|
2323
|
+
found = document.querySelector(spec);
|
|
2324
|
+
} catch (e) {
|
|
2325
|
+
console.warn('scroll timeline: subject "' + spec + '" is not a valid selector \u2014 measuring the SVG itself');
|
|
2326
|
+
return svgRoot;
|
|
2327
|
+
}
|
|
2328
|
+
if (!found) {
|
|
2329
|
+
console.warn('scroll timeline: subject "' + spec + '" matched no element \u2014 measuring the SVG itself');
|
|
2330
|
+
return svgRoot;
|
|
2331
|
+
}
|
|
2332
|
+
return found;
|
|
2333
|
+
}
|
|
2297
2334
|
function createScrollDriver(subject, config, onProgress) {
|
|
2298
|
-
var _a;
|
|
2335
|
+
var _a, _b;
|
|
2299
2336
|
if (!config || !isScrollTimeline(config)) return null;
|
|
2300
2337
|
const scroll = config.scroll || {};
|
|
2301
2338
|
const kind = (_a = scroll.kind) != null ? _a : "view";
|
|
2339
|
+
const measured = resolveScrollSubject(subject, scroll.subject);
|
|
2302
2340
|
const nearest = findNearestScroller(subject, "y") || findNearestScroller(subject, "x");
|
|
2303
2341
|
const scroller = kind === "scroll" && scroll.source === "root" ? documentScroller() : nearest || documentScroller();
|
|
2304
2342
|
const isRootScroller = scroller === documentScroller();
|
|
@@ -2309,7 +2347,7 @@ var PixodeskAnimator = (() => {
|
|
|
2309
2347
|
const maxOffset = axis === "y" ? scroller.scrollHeight - scroller.clientHeight : scroller.scrollWidth - scroller.clientWidth;
|
|
2310
2348
|
return scrollOffsetProgress(offset, maxOffset, scroll.range);
|
|
2311
2349
|
}
|
|
2312
|
-
const subjectRect =
|
|
2350
|
+
const subjectRect = measured.getBoundingClientRect();
|
|
2313
2351
|
let portStart, portSize;
|
|
2314
2352
|
if (isRootScroller) {
|
|
2315
2353
|
portStart = 0;
|
|
@@ -2323,12 +2361,43 @@ var PixodeskAnimator = (() => {
|
|
|
2323
2361
|
const subjectSize = axis === "y" ? subjectRect.height : subjectRect.width;
|
|
2324
2362
|
return scrollViewProgress(subjectStart, subjectSize, portSize, scroll.range);
|
|
2325
2363
|
};
|
|
2326
|
-
|
|
2364
|
+
const smoothingSec = Math.max(0, (_b = scroll.smoothing) != null ? _b : 0) / 1e3;
|
|
2365
|
+
const SETTLE_EPSILON = 1e-3;
|
|
2327
2366
|
let destroyed = false;
|
|
2367
|
+
let smoothed = null;
|
|
2368
|
+
let smoothRaf = null;
|
|
2369
|
+
let lastFrameMs = 0;
|
|
2370
|
+
const emit = (target) => {
|
|
2371
|
+
if (!smoothingSec) {
|
|
2372
|
+
onProgress(target);
|
|
2373
|
+
return;
|
|
2374
|
+
}
|
|
2375
|
+
if (smoothed === null) {
|
|
2376
|
+
smoothed = target;
|
|
2377
|
+
onProgress(target);
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
if (smoothRaf !== null) return;
|
|
2381
|
+
lastFrameMs = 0;
|
|
2382
|
+
const step = (nowMs) => {
|
|
2383
|
+
smoothRaf = null;
|
|
2384
|
+
if (destroyed) return;
|
|
2385
|
+
const dtSec = lastFrameMs ? Math.min(0.1, (nowMs - lastFrameMs) / 1e3) : 1 / 60;
|
|
2386
|
+
lastFrameMs = nowMs;
|
|
2387
|
+
const goal = compute();
|
|
2388
|
+
const k = 1 - Math.exp(-dtSec / smoothingSec);
|
|
2389
|
+
smoothed = smoothed + (goal - smoothed) * k;
|
|
2390
|
+
if (Math.abs(goal - smoothed) < SETTLE_EPSILON) smoothed = goal;
|
|
2391
|
+
onProgress(smoothed);
|
|
2392
|
+
if (smoothed !== goal) smoothRaf = requestAnimationFrame(step);
|
|
2393
|
+
};
|
|
2394
|
+
smoothRaf = requestAnimationFrame(step);
|
|
2395
|
+
};
|
|
2396
|
+
let rafId = null;
|
|
2328
2397
|
const tick = () => {
|
|
2329
2398
|
rafId = null;
|
|
2330
2399
|
if (destroyed) return;
|
|
2331
|
-
|
|
2400
|
+
emit(compute());
|
|
2332
2401
|
};
|
|
2333
2402
|
const schedule = () => {
|
|
2334
2403
|
if (destroyed || rafId !== null) return;
|
|
@@ -2340,7 +2409,8 @@ var PixodeskAnimator = (() => {
|
|
|
2340
2409
|
let resizeObserver;
|
|
2341
2410
|
if (typeof ResizeObserver !== "undefined") {
|
|
2342
2411
|
resizeObserver = new ResizeObserver(schedule);
|
|
2343
|
-
resizeObserver.observe(
|
|
2412
|
+
resizeObserver.observe(measured);
|
|
2413
|
+
if (measured !== subject) resizeObserver.observe(subject);
|
|
2344
2414
|
if (!isRootScroller) resizeObserver.observe(scroller);
|
|
2345
2415
|
}
|
|
2346
2416
|
const driver = {
|
|
@@ -2354,14 +2424,76 @@ var PixodeskAnimator = (() => {
|
|
|
2354
2424
|
cancelAnimationFrame(rafId);
|
|
2355
2425
|
rafId = null;
|
|
2356
2426
|
}
|
|
2427
|
+
if (smoothRaf !== null) {
|
|
2428
|
+
cancelAnimationFrame(smoothRaf);
|
|
2429
|
+
smoothRaf = null;
|
|
2430
|
+
}
|
|
2357
2431
|
},
|
|
2432
|
+
// `refresh` is a deliberate JUMP (attach, host relayout) — never eased.
|
|
2358
2433
|
refresh: () => {
|
|
2359
|
-
if (!destroyed)
|
|
2434
|
+
if (!destroyed) {
|
|
2435
|
+
smoothed = compute();
|
|
2436
|
+
onProgress(smoothed);
|
|
2437
|
+
}
|
|
2360
2438
|
}
|
|
2361
2439
|
};
|
|
2362
2440
|
driver.refresh();
|
|
2363
2441
|
return driver;
|
|
2364
2442
|
}
|
|
2443
|
+
function pinScrollportHeight(svgRoot) {
|
|
2444
|
+
const scroller = findNearestScroller(svgRoot, "y");
|
|
2445
|
+
return scroller ? scroller.clientHeight : document.documentElement.clientHeight;
|
|
2446
|
+
}
|
|
2447
|
+
function applyScrollPin(svgRoot, scroll) {
|
|
2448
|
+
const styled = svgRoot;
|
|
2449
|
+
if (!(scroll == null ? void 0 : scroll.pin) || !styled.style) return () => {
|
|
2450
|
+
};
|
|
2451
|
+
const style = styled.style;
|
|
2452
|
+
const prevPosition = style.position;
|
|
2453
|
+
const prevTop = style.top;
|
|
2454
|
+
style.position = "sticky";
|
|
2455
|
+
const alignFactor = scroll.pinAlign === "center" ? 0.5 : scroll.pinAlign === "bottom" ? 1 : 0;
|
|
2456
|
+
const applyTop = () => {
|
|
2457
|
+
var _a;
|
|
2458
|
+
const extra = (_a = scroll.pinTop) != null ? _a : 0;
|
|
2459
|
+
if (!alignFactor) {
|
|
2460
|
+
style.top = extra + "px";
|
|
2461
|
+
return;
|
|
2462
|
+
}
|
|
2463
|
+
const portSize = pinScrollportHeight(svgRoot);
|
|
2464
|
+
const ownSize = svgRoot.getBoundingClientRect().height;
|
|
2465
|
+
style.top = Math.round((portSize - ownSize) * alignFactor + extra) + "px";
|
|
2466
|
+
};
|
|
2467
|
+
applyTop();
|
|
2468
|
+
let resizeObserver = null;
|
|
2469
|
+
const onWindowResize = alignFactor ? applyTop : null;
|
|
2470
|
+
if (alignFactor) {
|
|
2471
|
+
if (onWindowResize) window.addEventListener("resize", onWindowResize);
|
|
2472
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
2473
|
+
resizeObserver = new ResizeObserver(applyTop);
|
|
2474
|
+
resizeObserver.observe(svgRoot);
|
|
2475
|
+
}
|
|
2476
|
+
}
|
|
2477
|
+
let wrapper = null;
|
|
2478
|
+
const parent = svgRoot.parentElement;
|
|
2479
|
+
if (scroll.pinDistance && scroll.pinDistance > 0 && parent) {
|
|
2480
|
+
wrapper = document.createElement("div");
|
|
2481
|
+
wrapper.setAttribute("data-px-pin", "");
|
|
2482
|
+
wrapper.style.height = scroll.pinDistance * 100 + "vh";
|
|
2483
|
+
parent.insertBefore(wrapper, svgRoot);
|
|
2484
|
+
wrapper.appendChild(svgRoot);
|
|
2485
|
+
}
|
|
2486
|
+
return () => {
|
|
2487
|
+
if (onWindowResize) window.removeEventListener("resize", onWindowResize);
|
|
2488
|
+
resizeObserver == null ? void 0 : resizeObserver.disconnect();
|
|
2489
|
+
style.position = prevPosition;
|
|
2490
|
+
style.top = prevTop;
|
|
2491
|
+
if (wrapper == null ? void 0 : wrapper.parentElement) {
|
|
2492
|
+
wrapper.parentElement.insertBefore(svgRoot, wrapper);
|
|
2493
|
+
wrapper.remove();
|
|
2494
|
+
}
|
|
2495
|
+
};
|
|
2496
|
+
}
|
|
2365
2497
|
|
|
2366
2498
|
// src/PxAnimatorBind.ts
|
|
2367
2499
|
function finaliseAnimator(animatorConfig, callbacks, make) {
|
|
@@ -2388,7 +2520,10 @@ var PixodeskAnimator = (() => {
|
|
|
2388
2520
|
if (isScrollTimeline(animatorConfig)) {
|
|
2389
2521
|
return finaliseAnimator(animatorConfig, callbacks, (cb) => {
|
|
2390
2522
|
var _a, _b;
|
|
2523
|
+
let unpin = () => {
|
|
2524
|
+
};
|
|
2391
2525
|
if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
|
|
2526
|
+
unpin = applyScrollPin(rootElement, animatorConfig.scroll);
|
|
2392
2527
|
const native = createNativeScrollTimeline(rootElement, animatorConfig);
|
|
2393
2528
|
if (native) {
|
|
2394
2529
|
const api2 = createWebApiAnimator(
|
|
@@ -2398,12 +2533,23 @@ var PixodeskAnimator = (() => {
|
|
|
2398
2533
|
animatorConfig.mode === PxAnimatorMode.waapi,
|
|
2399
2534
|
native
|
|
2400
2535
|
);
|
|
2401
|
-
if (api2)
|
|
2536
|
+
if (api2) {
|
|
2537
|
+
const destroyNative = api2.destroy.bind(api2);
|
|
2538
|
+
api2.destroy = () => {
|
|
2539
|
+
unpin();
|
|
2540
|
+
destroyNative();
|
|
2541
|
+
};
|
|
2542
|
+
return api2;
|
|
2543
|
+
}
|
|
2402
2544
|
}
|
|
2545
|
+
unpin();
|
|
2546
|
+
unpin = () => {
|
|
2547
|
+
};
|
|
2403
2548
|
}
|
|
2404
2549
|
const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
|
|
2405
2550
|
const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
|
|
2406
2551
|
if (subject) {
|
|
2552
|
+
unpin = applyScrollPin(subject, animatorConfig.scroll);
|
|
2407
2553
|
const totalMs = scrollTotalDurationMs(animatorConfig);
|
|
2408
2554
|
const driver = createScrollDriver(
|
|
2409
2555
|
subject,
|
|
@@ -2414,6 +2560,7 @@ var PixodeskAnimator = (() => {
|
|
|
2414
2560
|
const destroy = api.destroy.bind(api);
|
|
2415
2561
|
api.destroy = () => {
|
|
2416
2562
|
driver.destroy();
|
|
2563
|
+
unpin();
|
|
2417
2564
|
destroy();
|
|
2418
2565
|
};
|
|
2419
2566
|
}
|