@pixodesk/svg-animator-web 1.0.43 → 1.0.45

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.
@@ -575,14 +575,18 @@ var PixodeskAnimator = (() => {
575
575
  alternate: "alternate",
576
576
  alternateReverse: "alternate-reverse"
577
577
  };
578
- var PxStartOn = {
578
+ var PxTriggerStart = {
579
579
  load: "load",
580
580
  mouseOver: "mouseOver",
581
581
  click: "click",
582
- scrollIntoView: "scrollIntoView",
583
- programmatic: "programmatic"
582
+ none: "none"
583
+ };
584
+ var PxOffScreenAction = {
585
+ pause: "pause",
586
+ continue: "continue",
587
+ reset: "reset"
584
588
  };
585
- var PxOutAction = {
589
+ var PxMouseOutAction = {
586
590
  continue: "continue",
587
591
  pause: "pause",
588
592
  reset: "reset",
@@ -641,16 +645,20 @@ var PixodeskAnimator = (() => {
641
645
  auto: "auto"
642
646
  });
643
647
  var PX_TRIGGER_DEFAULTS = {
644
- startOn: "load",
645
- outAction: "continue",
646
- scrollIntoViewThreshold: 0
648
+ start: "load",
649
+ offScreen: "pause",
650
+ mouseOut: "continue",
651
+ visibilityThreshold: 0.5,
652
+ visibilityDebounce: 150
647
653
  };
648
654
  function resolveTrigger(trigger) {
649
- var _a, _b, _c;
655
+ var _a, _b, _c, _d, _e;
650
656
  return {
651
- startOn: (_a = trigger == null ? void 0 : trigger.startOn) != null ? _a : PX_TRIGGER_DEFAULTS.startOn,
652
- outAction: (_b = trigger == null ? void 0 : trigger.outAction) != null ? _b : PX_TRIGGER_DEFAULTS.outAction,
653
- scrollIntoViewThreshold: (_c = trigger == null ? void 0 : trigger.scrollIntoViewThreshold) != null ? _c : PX_TRIGGER_DEFAULTS.scrollIntoViewThreshold
657
+ start: (_a = trigger == null ? void 0 : trigger.start) != null ? _a : PX_TRIGGER_DEFAULTS.start,
658
+ offScreen: (_b = trigger == null ? void 0 : trigger.offScreen) != null ? _b : PX_TRIGGER_DEFAULTS.offScreen,
659
+ mouseOut: (_c = trigger == null ? void 0 : trigger.mouseOut) != null ? _c : PX_TRIGGER_DEFAULTS.mouseOut,
660
+ visibilityThreshold: (_d = trigger == null ? void 0 : trigger.visibilityThreshold) != null ? _d : PX_TRIGGER_DEFAULTS.visibilityThreshold,
661
+ visibilityDebounce: (_e = trigger == null ? void 0 : trigger.visibilityDebounce) != null ? _e : PX_TRIGGER_DEFAULTS.visibilityDebounce
654
662
  };
655
663
  }
656
664
  var PxLoopRepeatAt = {
@@ -768,9 +776,9 @@ var PixodeskAnimator = (() => {
768
776
  } else {
769
777
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
770
778
  if (timeline.trigger !== void 0) {
771
- const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest(_b, ["finishAction"]);
779
+ const _b = timeline.trigger, { finish } = _b, restTrigger = __objRest(_b, ["finish"]);
772
780
  if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
773
- if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
781
+ if (finish !== void 0) flat.resetOnFinish = finish === "reset";
774
782
  }
775
783
  if (timeline.delay !== void 0) flat.delay = timeline.delay;
776
784
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
@@ -871,13 +879,15 @@ var PixodeskAnimator = (() => {
871
879
  PxAnimationDefinitionSchema
872
880
  ]));
873
881
  var PxTriggerSchema = implementsInterface()(px.object({
874
- startOn: px.enum([PxStartOn.load, PxStartOn.mouseOver, PxStartOn.click, PxStartOn.scrollIntoView, PxStartOn.programmatic], PX_TRIGGER_DEFAULTS.startOn).optional(),
875
- outAction: px.enum([PxOutAction.continue, PxOutAction.pause, PxOutAction.reset, PxOutAction.reverse], PX_TRIGGER_DEFAULTS.outAction).optional(),
882
+ start: px.enum([PxTriggerStart.load, PxTriggerStart.mouseOver, PxTriggerStart.click, PxTriggerStart.none], PX_TRIGGER_DEFAULTS.start).optional(),
883
+ offScreen: px.enum([PxOffScreenAction.pause, PxOffScreenAction.continue, PxOffScreenAction.reset], PX_TRIGGER_DEFAULTS.offScreen).optional(),
884
+ mouseOut: px.enum([PxMouseOutAction.continue, PxMouseOutAction.pause, PxMouseOutAction.reset, PxMouseOutAction.reverse], PX_TRIGGER_DEFAULTS.mouseOut).optional(),
876
885
  // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
877
- // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
878
- // happens when the trigger condition ends"); both end-of-life knobs now read alike.
879
- finishAction: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
880
- scrollIntoViewThreshold: px.number().optional()
886
+ // `fill`) or `'reset'` (snap back to the start state). One of four occasion keys
887
+ // (`start`, `offScreen`, `mouseOut`, `finish`), all named the same way.
888
+ finish: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
889
+ visibilityThreshold: px.number().optional(),
890
+ visibilityDebounce: px.number().optional()
881
891
  }));
882
892
  var PxGlyphSchema = implementsInterface()(px.object({
883
893
  width: px.number(),
@@ -1586,6 +1596,38 @@ var PixodeskAnimator = (() => {
1586
1596
  return cubicBezier(flipped);
1587
1597
  }
1588
1598
 
1599
+ // ../svg-animator-core/src/animation/PxStaticTransformMerge.ts
1600
+ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
1601
+ if (!animDef) return animDef;
1602
+ const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
1603
+ if (!staticParts || !Object.keys(staticParts).length) return animDef;
1604
+ const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
1605
+ const transformAnim = animDef[TRANSFORM_ATTR];
1606
+ if (transformAnim && typeof transformAnim === "object") {
1607
+ const anim = transformAnim;
1608
+ if (Array.isArray(anim.keyframes)) {
1609
+ const out = __spreadProps(__spreadValues({}, anim), {
1610
+ keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
1611
+ });
1612
+ if (out.value !== void 0) out.value = mergeKfValue(out.value);
1613
+ return __spreadProps(__spreadValues({}, animDef), { transform: out });
1614
+ }
1615
+ return animDef;
1616
+ }
1617
+ const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
1618
+ if (channels.length !== 1) return animDef;
1619
+ const ch = channels[0];
1620
+ const chAnim = animDef[ch];
1621
+ if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
1622
+ const lifted = __spreadProps(__spreadValues({}, chAnim), {
1623
+ keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
1624
+ });
1625
+ if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
1626
+ const rest = __spreadValues({}, animDef);
1627
+ delete rest[ch];
1628
+ return __spreadProps(__spreadValues({}, rest), { transform: lifted });
1629
+ }
1630
+
1589
1631
  // ../svg-animator-core/src/materialize/PxMotionPath.ts
1590
1632
  function getKfTranslate(kf) {
1591
1633
  const v = keyframeValue(kf);
@@ -2347,36 +2389,6 @@ var PixodeskAnimator = (() => {
2347
2389
  function generateElementId() {
2348
2390
  return "_px_el_" + ++_elementIdCounter;
2349
2391
  }
2350
- function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2351
- if (!animDef) return animDef;
2352
- const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2353
- if (!staticParts || !Object.keys(staticParts).length) return animDef;
2354
- const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
2355
- const transformAnim = animDef[TRANSFORM_ATTR];
2356
- if (transformAnim && typeof transformAnim === "object") {
2357
- const anim = transformAnim;
2358
- if (Array.isArray(anim.keyframes)) {
2359
- const out = __spreadProps(__spreadValues({}, anim), {
2360
- keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
2361
- });
2362
- if (out.value !== void 0) out.value = mergeKfValue(out.value);
2363
- return __spreadProps(__spreadValues({}, animDef), { transform: out });
2364
- }
2365
- return animDef;
2366
- }
2367
- const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
2368
- if (channels.length !== 1) return animDef;
2369
- const ch = channels[0];
2370
- const chAnim = animDef[ch];
2371
- if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
2372
- const lifted = __spreadProps(__spreadValues({}, chAnim), {
2373
- keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
2374
- });
2375
- if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
2376
- const rest = __spreadValues({}, animDef);
2377
- delete rest[ch];
2378
- return __spreadProps(__spreadValues({}, rest), { transform: lifted });
2379
- }
2380
2392
  function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
2381
2393
  const normalized = {};
2382
2394
  for (const [propName, propAnim] of Object.entries(animDef)) {
@@ -2565,6 +2577,196 @@ var PixodeskAnimator = (() => {
2565
2577
  return e instanceof Error ? e : new Error(String(e));
2566
2578
  }
2567
2579
 
2580
+ // src/registry/PxAnimatorRegistry.ts
2581
+ var STORE_KEY = /* @__PURE__ */ Symbol.for("@pixodesk/svg-animator-web:animators");
2582
+ var GLOBAL_NAME = "__pixodeskAnimators";
2583
+ function store() {
2584
+ const g = globalThis;
2585
+ let s = g[STORE_KEY];
2586
+ if (!s) {
2587
+ const animators = /* @__PURE__ */ new Set();
2588
+ const listeners = /* @__PURE__ */ new Set();
2589
+ s = {
2590
+ animators,
2591
+ listeners,
2592
+ getAll: () => Array.from(animators),
2593
+ subscribe: (listener) => {
2594
+ listeners.add(listener);
2595
+ return () => {
2596
+ listeners.delete(listener);
2597
+ };
2598
+ }
2599
+ };
2600
+ g[STORE_KEY] = s;
2601
+ if (g[GLOBAL_NAME] === void 0) g[GLOBAL_NAME] = s;
2602
+ }
2603
+ return s;
2604
+ }
2605
+ function notify(event, animator) {
2606
+ for (const listener of store().listeners) {
2607
+ try {
2608
+ listener(event, animator);
2609
+ } catch (e) {
2610
+ setTimeout(() => {
2611
+ throw e;
2612
+ }, 0);
2613
+ }
2614
+ }
2615
+ }
2616
+ function registerAnimator(animator) {
2617
+ const s = store();
2618
+ if (s.animators.has(animator)) return;
2619
+ s.animators.add(animator);
2620
+ notify("add", animator);
2621
+ const destroy = animator.destroy.bind(animator);
2622
+ animator.destroy = () => {
2623
+ destroy();
2624
+ if (s.animators.delete(animator)) notify("remove", animator);
2625
+ };
2626
+ }
2627
+ function withRegistryEvents(callbacks, api) {
2628
+ const fire = (event) => {
2629
+ const a = api();
2630
+ if (a) notify(event, a);
2631
+ };
2632
+ return __spreadProps(__spreadValues({}, callbacks), {
2633
+ onPlay: () => {
2634
+ var _a;
2635
+ (_a = callbacks == null ? void 0 : callbacks.onPlay) == null ? void 0 : _a.call(callbacks);
2636
+ fire("play");
2637
+ },
2638
+ onPause: () => {
2639
+ var _a;
2640
+ (_a = callbacks == null ? void 0 : callbacks.onPause) == null ? void 0 : _a.call(callbacks);
2641
+ fire("pause");
2642
+ },
2643
+ onCancel: () => {
2644
+ var _a;
2645
+ (_a = callbacks == null ? void 0 : callbacks.onCancel) == null ? void 0 : _a.call(callbacks);
2646
+ fire("cancel");
2647
+ },
2648
+ onFinish: () => {
2649
+ var _a;
2650
+ (_a = callbacks == null ? void 0 : callbacks.onFinish) == null ? void 0 : _a.call(callbacks);
2651
+ fire("finish");
2652
+ }
2653
+ });
2654
+ }
2655
+
2656
+ // src/triggers/PxVisibilityGate.ts
2657
+ var PLAY_WHEN_VISIBLE_DEFAULTS = {
2658
+ offScreen: PX_TRIGGER_DEFAULTS.offScreen,
2659
+ visibilityThreshold: PX_TRIGGER_DEFAULTS.visibilityThreshold,
2660
+ visibilityDebounce: PX_TRIGGER_DEFAULTS.visibilityDebounce
2661
+ };
2662
+ var THRESHOLD_STEPS = Array.from({ length: 21 }, (_, i) => i / 20);
2663
+ function effectiveRatio(entry) {
2664
+ var _a, _b;
2665
+ const target = entry.boundingClientRect;
2666
+ const visible = entry.intersectionRect;
2667
+ if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
2668
+ const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
2669
+ const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
2670
+ const viewport = Math.min(live, declared);
2671
+ const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
2672
+ return denom > 0 ? visible.height / denom : entry.intersectionRatio;
2673
+ }
2674
+ function openGate(host) {
2675
+ return {
2676
+ requestStart: () => host.play(),
2677
+ dispose: () => {
2678
+ }
2679
+ };
2680
+ }
2681
+ function isGated(offScreen) {
2682
+ return offScreen !== PxOffScreenAction.continue;
2683
+ }
2684
+ function createVisibilityGate(root, trigger, host) {
2685
+ if (!isGated(trigger.offScreen)) return openGate(host);
2686
+ if (typeof IntersectionObserver === "undefined") return openGate(host);
2687
+ const threshold = trigger.visibilityThreshold;
2688
+ const debounceMs = trigger.visibilityDebounce;
2689
+ let isOpen = void 0;
2690
+ let startPending = false;
2691
+ let pausedByGate = false;
2692
+ let lastRatio = 0;
2693
+ let openTimer;
2694
+ const cancelPendingOpen = () => {
2695
+ if (openTimer !== void 0) {
2696
+ clearTimeout(openTimer);
2697
+ openTimer = void 0;
2698
+ }
2699
+ };
2700
+ const open = () => {
2701
+ openTimer = void 0;
2702
+ if (isOpen === true) return;
2703
+ isOpen = true;
2704
+ if (startPending || pausedByGate) {
2705
+ startPending = false;
2706
+ pausedByGate = false;
2707
+ host.play();
2708
+ }
2709
+ };
2710
+ const close = () => {
2711
+ cancelPendingOpen();
2712
+ if (isOpen === false) return;
2713
+ isOpen = false;
2714
+ if (!host.isPlaying()) return;
2715
+ if (trigger.offScreen === PxOffScreenAction.reset) {
2716
+ host.cancel();
2717
+ } else {
2718
+ host.pause();
2719
+ }
2720
+ pausedByGate = true;
2721
+ };
2722
+ const apply = (ratio) => {
2723
+ lastRatio = ratio;
2724
+ if (typeof document !== "undefined" && document.visibilityState === "hidden") {
2725
+ close();
2726
+ return;
2727
+ }
2728
+ if (ratio >= threshold) {
2729
+ if (isOpen === true || openTimer !== void 0) return;
2730
+ if (debounceMs > 0) openTimer = setTimeout(open, debounceMs);
2731
+ else open();
2732
+ return;
2733
+ }
2734
+ if (ratio <= 0) {
2735
+ close();
2736
+ return;
2737
+ }
2738
+ if (isOpen !== true) cancelPendingOpen();
2739
+ };
2740
+ const observer = new IntersectionObserver((entries) => {
2741
+ const last = entries[entries.length - 1];
2742
+ if (last) apply(last.isIntersecting ? effectiveRatio(last) : 0);
2743
+ }, { threshold: THRESHOLD_STEPS });
2744
+ observer.observe(root);
2745
+ const onVisibilityChange = () => {
2746
+ apply(lastRatio);
2747
+ };
2748
+ const hasDocument = typeof document !== "undefined";
2749
+ if (hasDocument) document.addEventListener("visibilitychange", onVisibilityChange);
2750
+ return {
2751
+ requestStart: (immediate) => {
2752
+ if (immediate || isOpen === true) {
2753
+ cancelPendingOpen();
2754
+ isOpen = true;
2755
+ startPending = false;
2756
+ pausedByGate = false;
2757
+ host.play();
2758
+ return;
2759
+ }
2760
+ startPending = true;
2761
+ },
2762
+ dispose: () => {
2763
+ cancelPendingOpen();
2764
+ observer.disconnect();
2765
+ if (hasDocument) document.removeEventListener("visibilitychange", onVisibilityChange);
2766
+ }
2767
+ };
2768
+ }
2769
+
2568
2770
  // src/triggers/PxAnimatorTriggers.ts
2569
2771
  function setupAnimationTriggers(api, trigger, diag) {
2570
2772
  const report = diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]");
@@ -2572,7 +2774,7 @@ var PixodeskAnimator = (() => {
2572
2774
  const dispose = () => {
2573
2775
  for (const undo of cleanups.splice(0)) undo();
2574
2776
  };
2575
- const { startOn, outAction, scrollIntoViewThreshold } = resolveTrigger(trigger);
2777
+ const resolved = resolveTrigger(trigger);
2576
2778
  const root = api.getRootElement();
2577
2779
  if (!root) {
2578
2780
  report.warn(PxDiagnosticKind.host, 1201 /* triggersNoRoot */);
@@ -2586,27 +2788,34 @@ var PixodeskAnimator = (() => {
2586
2788
  }
2587
2789
  api.play();
2588
2790
  };
2589
- const handleEndAction = () => {
2590
- switch (outAction) {
2591
- case "pause":
2791
+ const gate = createVisibilityGate(root, resolved, {
2792
+ isPlaying: () => api.isPlaying(),
2793
+ play: start,
2794
+ pause: () => api.pause(),
2795
+ cancel: () => api.cancel()
2796
+ });
2797
+ cleanups.push(() => gate.dispose());
2798
+ const handleMouseOut = () => {
2799
+ switch (resolved.mouseOut) {
2800
+ case PxMouseOutAction.pause:
2592
2801
  api.pause();
2593
2802
  break;
2594
- case "reset":
2803
+ case PxMouseOutAction.reset:
2595
2804
  api.cancel();
2596
2805
  break;
2597
- case "reverse":
2806
+ case PxMouseOutAction.reverse:
2598
2807
  reversed = true;
2599
2808
  api.setPlaybackRate(-1);
2600
2809
  api.play();
2601
2810
  break;
2602
- case "continue":
2811
+ case PxMouseOutAction.continue:
2603
2812
  default:
2604
2813
  break;
2605
2814
  }
2606
2815
  };
2607
- switch (startOn) {
2608
- case "load": {
2609
- const startHandler = () => start();
2816
+ switch (resolved.start) {
2817
+ case PxTriggerStart.load: {
2818
+ const startHandler = () => gate.requestStart(false);
2610
2819
  if (document.readyState === "complete") {
2611
2820
  startHandler();
2612
2821
  } else {
@@ -2615,14 +2824,14 @@ var PixodeskAnimator = (() => {
2615
2824
  }
2616
2825
  break;
2617
2826
  }
2618
- case "mouseOver": {
2827
+ case PxTriggerStart.mouseOver: {
2619
2828
  let enteredOnce = false;
2620
2829
  const mouseOverHandler = () => {
2621
2830
  enteredOnce = true;
2622
- start();
2831
+ gate.requestStart(true);
2623
2832
  };
2624
2833
  const mouseOutHandler = () => {
2625
- if (enteredOnce) handleEndAction();
2834
+ if (enteredOnce) handleMouseOut();
2626
2835
  };
2627
2836
  root.addEventListener("mouseenter", mouseOverHandler);
2628
2837
  root.addEventListener("mouseleave", mouseOutHandler);
@@ -2632,51 +2841,16 @@ var PixodeskAnimator = (() => {
2632
2841
  });
2633
2842
  break;
2634
2843
  }
2635
- case "click": {
2844
+ case PxTriggerStart.click: {
2636
2845
  const clickHandler = () => {
2637
- if (api.isPlaying()) {
2638
- handleEndAction();
2639
- } else {
2640
- start();
2641
- }
2846
+ if (api.isPlaying()) api.pause();
2847
+ else gate.requestStart(true);
2642
2848
  };
2643
2849
  root.addEventListener("click", clickHandler);
2644
2850
  cleanups.push(() => root.removeEventListener("click", clickHandler));
2645
2851
  break;
2646
2852
  }
2647
- case "scrollIntoView": {
2648
- const effectiveRatio = (entry) => {
2649
- var _a, _b;
2650
- const target = entry.boundingClientRect;
2651
- const visible = entry.intersectionRect;
2652
- if (!(target == null ? void 0 : target.height) || !visible) return entry.intersectionRatio;
2653
- const live = typeof window !== "undefined" && window.innerHeight ? window.innerHeight : Infinity;
2654
- const declared = (_b = (_a = entry.rootBounds) == null ? void 0 : _a.height) != null ? _b : Infinity;
2655
- const viewport = Math.min(live, declared);
2656
- const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);
2657
- return denom > 0 ? visible.height / denom : entry.intersectionRatio;
2658
- };
2659
- const thresholdSteps = Array.from({ length: 21 }, (_, i) => i / 20);
2660
- let wasIntersecting = false;
2661
- const observer = new IntersectionObserver(
2662
- (entries) => {
2663
- entries.forEach((entry) => {
2664
- if (entry.isIntersecting && effectiveRatio(entry) >= scrollIntoViewThreshold) {
2665
- wasIntersecting = true;
2666
- start();
2667
- } else if (wasIntersecting) {
2668
- wasIntersecting = false;
2669
- handleEndAction();
2670
- }
2671
- });
2672
- },
2673
- { threshold: thresholdSteps }
2674
- );
2675
- observer.observe(root);
2676
- cleanups.push(() => observer.disconnect());
2677
- break;
2678
- }
2679
- case "programmatic":
2853
+ case PxTriggerStart.none:
2680
2854
  break;
2681
2855
  }
2682
2856
  return dispose;
@@ -2684,7 +2858,12 @@ var PixodeskAnimator = (() => {
2684
2858
 
2685
2859
  // src/engines/PxAnimatorFrameLoop.ts
2686
2860
  function getSelector(id) {
2687
- return "#" + id;
2861
+ return "#" + escapeCssId(id);
2862
+ }
2863
+ function escapeCssId(id) {
2864
+ const css = globalThis.CSS;
2865
+ if (typeof (css == null ? void 0 : css.escape) === "function") return css.escape(id);
2866
+ return id.replace(/^([0-9])/, (_all, digit) => "\\3" + digit + " ").replace(/([^\w\-\\ ])/g, "\\$1");
2688
2867
  }
2689
2868
 
2690
2869
  // src/engines/PxAnimatorWebApi.ts
@@ -3006,16 +3185,21 @@ var PixodeskAnimator = (() => {
3006
3185
  return createInertAnimator();
3007
3186
  }
3008
3187
  }
3188
+ function registered(options, build) {
3189
+ let apiRef;
3190
+ const api = build(withRegistryEvents(toEngineCallbacks(options), () => apiRef));
3191
+ if (api.isReady()) {
3192
+ apiRef = api;
3193
+ registerAnimator(api);
3194
+ }
3195
+ return api;
3196
+ }
3009
3197
  function createPrerenderedWaapiAnimator(options) {
3010
3198
  const doc = requireDoc(options);
3011
- return buildOrReport(options, () => {
3199
+ return registered(options, (callbacks) => buildOrReport(options, () => {
3012
3200
  const animatorConfig = getAnimatorConfig(doc) || {};
3013
- return finaliseAnimator(
3014
- animatorConfig,
3015
- toEngineCallbacks(options),
3016
- (cb) => createWebApiAnimator(doc, cb, null, true)
3017
- );
3018
- });
3201
+ return finaliseAnimator(animatorConfig, callbacks, (cb) => createWebApiAnimator(doc, cb, null, true));
3202
+ }));
3019
3203
  }
3020
3204
 
3021
3205
  // src/shared/PxAnimatorKeys.ts