@pixodesk/svg-animator-rn 1.0.41 → 1.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -114,7 +114,7 @@ Four ways to drive playback. Pick one — they are mutually exclusive.
114
114
 
115
115
  ### Autoplay
116
116
 
117
- Uses the trigger defined in the animation document (`startOn: 'load'` plays on mount):
117
+ Uses the trigger defined in the animation document (`start: 'load'` plays once it is on screen):
118
118
 
119
119
  ```tsx
120
120
  <PixodeskSvgAnimator doc={doc} autoplay />
@@ -181,7 +181,7 @@ const [time, setTime] = useState(0);
181
181
  | `duration` | `number` | Shortcut for `timeline.duration` (ms) |
182
182
  | `delay` | `number` | Shortcut for `timeline.delay` (ms) |
183
183
  | `iterations` | `number \| 'infinite'` | Shortcut for `timeline.iterations` |
184
- | `startOn` | `PxStartOn` | Shortcut for `timeline.trigger.startOn`. `mouseOver` has no touch equivalent and is ignored |
184
+ | `start` | `PxTriggerStart` | Shortcut for `timeline.trigger.start`. `mouseOver` has no touch equivalent and is ignored |
185
185
  | `onPlay` | `() => void` | Called on play/resume |
186
186
  | `onPause` | `() => void` | Called on pause |
187
187
  | `onFinish` | `() => void` | Called when the animation reaches its end — every iteration played, or `finish()` was called |
@@ -224,7 +224,7 @@ renderer never reaches JavaScript and cannot be caught — see
224
224
  |---|---|
225
225
  | `timeline.engine` | Accepted inside `timeline` but ignored. There is no Web Animations API on React Native; playback is always native-driven. |
226
226
  | `timeline.frameRate` | Ignored. The screen's own refresh rate is used. The player does not compute values frame by frame: when the document loads it works out the animated values in advance, as a list of snapshots (60 per second of animation), and each screen refresh shows the nearest one. The closest thing to a frame rate is how many snapshots per second are prepared, which the player fixes at 60. |
227
- | `startOn: 'mouseOver'` | Has no touch equivalent, so it is not honored. The other four values (`load`, `click`, `scrollIntoView`, `programmatic`) work as they do on the web, from the file or from the `startOn` prop. |
227
+ | `start: 'mouseOver'` | Has no touch equivalent, so it is not honored. The other three values (`load`, `click`, `none`) work as they do on the web, from the file or from the `start` prop. |
228
228
  | `className` / `style` | Not accepted — you cannot style the component itself. It fills whatever `View` you put it in, so to set its size, give that `View` a `width` and `height`. Styling *inside* the document (`style` on an element in the JSON) is supported. |
229
229
  | `onRemove` | Never called. On the web it tells you the animator was thrown away; here there is nothing to tell — when the component leaves the screen, React removes it and everything it created. To run code at that moment, use a `useEffect` cleanup function in your own component. |
230
230
 
@@ -326,13 +326,13 @@ player sees plain nodes. **All are supported:**
326
326
  | `duration`, `delay`, `iterations` (incl. `'infinite'`) | ✅ | |
327
327
  | `direction` — all four values | ✅ | |
328
328
  | `fillMode` — `forwards` / `backwards` / `both` / `none` | ✅ | |
329
- | `trigger.finishAction: 'reset'` | ✅ | |
329
+ | `trigger.finish: 'reset'` | ✅ | |
330
330
  | `play` / `pause` / `cancel` / `finish` | ✅ | |
331
331
  | `setCurrentTime` — jump to a time, including **while playing** | ✅ | playback continues from the new point |
332
332
  | `setPlaybackRate` — faster, slower and **reverse** (negative) | ✅ | composes with `direction` |
333
333
  | Trigger `load` / `programmatic` | ✅ | |
334
- | Trigger `click` | ✅ | wrapped in a `Pressable`; a second tap applies `outAction` |
335
- | Trigger `scrollIntoView` | ✅ | visibility sampled by measuring against the window (React Native has no `IntersectionObserver`); honors `scrollIntoViewThreshold` and `outAction` |
334
+ | Trigger `click` | ✅ | wrapped in a `Pressable`; a second tap pauses |
335
+ | Visibility gate | ✅ | visibility sampled by measuring against the window (React Native has no `IntersectionObserver`); honors `visibilityThreshold` and `offScreen` |
336
336
  | Trigger `mouseOver` | ❌ | no touch equivalent — use `click`, or drive `play` yourself |
337
337
  | `timeline.frameRate` | n/a | reanimated runs at the display refresh rate; the player prepares 60 snapshots per second of animation |
338
338
  | `timeline.engine` (`auto` / `native` / `js`) | n/a | there is no Web Animations API on React Native — playback is always native-driven |
package/dist/index.cjs CHANGED
@@ -398,7 +398,7 @@ var PxRnErrorBoundary = class extends import_react2.Component {
398
398
  }
399
399
  componentDidCatch(error, info) {
400
400
  var _a, _b;
401
- ((_a = this.props.diag) != null ? _a : (0, import_internal4.createDiagnostics)(void 0, "[PixodeskSvgAnimator]")).error(import_svg_animator_core3.PxDiagnosticKind.internal, error, { componentStack: (_b = info == null ? void 0 : info.componentStack) != null ? _b : void 0 });
401
+ ((_a = this.props.diag) != null ? _a : (0, import_internal4.createDiagnostics)(void 0, "[PixodeskSvgAnimator]")).error(import_svg_animator_core3.PxDiagnosticKind.internal, import_svg_animator_core3.PxDiagnosticCode.rnBoundaryCaught, error, (_b = info == null ? void 0 : info.componentStack) != null ? _b : void 0);
402
402
  }
403
403
  componentDidUpdate(prev) {
404
404
  if (this.state.error && prev.children !== this.props.children) {
@@ -558,14 +558,14 @@ var EMPTY_TRACKS = {
558
558
  elements: []
559
559
  };
560
560
  function compileDocument(doc, overrides, diag) {
561
- const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
561
+ const { timeline, resetTimeline, duration, delay, iterations, start } = overrides;
562
562
  const warnings = (0, import_svg_animator_core4.validateNodeEffects)(doc);
563
- for (const w of warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.document, "effects shape: " + w);
563
+ for (const w of warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.document, import_svg_animator_core4.PxDiagnosticCode.effectsShape, w);
564
564
  (0, import_internal6.reportDocumentDiagnostics)(doc, "[PixodeskSvgAnimator]");
565
- const patch = (0, import_svg_animator_core4.foldTimelineOverride)(timeline, { duration, delay, iterations, startOn });
565
+ const patch = (0, import_svg_animator_core4.foldTimelineOverride)(timeline, { duration, delay, iterations, start });
566
566
  if (patch !== void 0 || resetTimeline) {
567
567
  const applied = (0, import_svg_animator_core4.applyAnimatorConfig)(doc, patch != null ? patch : {}, { resetTimeline: !!resetTimeline });
568
- for (const w of applied.warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, "timeline override: " + w);
568
+ for (const w of applied.warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.timelineOverrideIgnored, w);
569
569
  doc = applied.doc;
570
570
  }
571
571
  let prepared = (0, import_svg_animator_core4.materializeAllInTree)(doc, import_svg_animator_core4.PxTimelineEngine.native);
@@ -583,7 +583,7 @@ function PixodeskSvgAnimator({
583
583
  duration,
584
584
  delay,
585
585
  iterations,
586
- startOn,
586
+ start,
587
587
  // (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)
588
588
  autoplay,
589
589
  play,
@@ -613,15 +613,15 @@ function PixodeskSvgAnimator({
613
613
  try {
614
614
  return compileDocument(
615
615
  doc,
616
- { timeline, resetTimeline, duration, delay, iterations, startOn },
616
+ { timeline, resetTimeline, duration, delay, iterations, start },
617
617
  makeDiag()
618
618
  );
619
619
  } catch (e) {
620
620
  const error = e instanceof Error ? e : new Error(String(e));
621
- makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, error, { phase: "compile" });
621
+ makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, import_svg_animator_core4.PxDiagnosticCode.rnCompileFailed, error);
622
622
  return { doc: null, tracks: EMPTY_TRACKS, error };
623
623
  }
624
- }, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);
624
+ }, [doc, timelineKey, resetTimeline, duration, delay, iterations, start]);
625
625
  const tracks = compiled.tracks;
626
626
  const totalDuration = (0, import_svg_animator_core4.progressSpanMs)(tracks.duration, tracks.iterations);
627
627
  const seekCeiling = (0, import_svg_animator_core4.seekCeilingMs)(tracks.duration, tracks.iterations);
@@ -707,7 +707,7 @@ function PixodeskSvgAnimator({
707
707
  },
708
708
  setPlaybackRate: (rate) => {
709
709
  if (!(0, import_svg_animator_core4.isValidPlaybackRate)(rate)) {
710
- makeDiag().warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PX_RATE_REJECTED);
710
+ makeDiag().warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.rateRejected);
711
711
  return;
712
712
  }
713
713
  rateRef.current = rate;
@@ -738,12 +738,13 @@ function PixodeskSvgAnimator({
738
738
  };
739
739
  (0, import_react3.useImperativeHandle)(apiRef, () => api, [compiled]);
740
740
  const trigger = (0, import_svg_animator_core4.resolveTrigger)(compiled.doc ? (_a = (0, import_svg_animator_core4.getAnimatorConfig)(compiled.doc)) == null ? void 0 : _a.trigger : void 0);
741
- const effectiveStartOn = trigger.startOn;
742
- const effectiveOutAction = trigger.outAction;
741
+ const effectiveStart = trigger.start;
742
+ const effectiveOffScreen = trigger.offScreen;
743
+ const gated = effectiveOffScreen !== "continue";
743
744
  const { mode: compMode, warnings: modeWarnings } = (0, import_svg_animator_core4.resolveControlMode)({ progress: progressProp, time, play, pause, autoplay });
744
745
  (0, import_react3.useEffect)(() => {
745
746
  const diag = makeDiag();
746
- for (const w of modeWarnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, w);
747
+ for (const w of modeWarnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, import_svg_animator_core4.PxDiagnosticCode.controlPropsConflict, w);
747
748
  }, [modeWarnings.join("|")]);
748
749
  (0, import_react3.useEffect)(() => {
749
750
  if (compMode === import_svg_animator_core4.PxControlMode.fixedTime) {
@@ -758,15 +759,15 @@ function PixodeskSvgAnimator({
758
759
  else api.play();
759
760
  return;
760
761
  }
761
- if (compMode === import_svg_animator_core4.PxControlMode.autoplay && effectiveStartOn === "load") {
762
+ if (compMode === import_svg_animator_core4.PxControlMode.autoplay && effectiveStart === "load" && !gated) {
762
763
  api.play();
763
764
  }
764
765
  }, [compiled, compMode, autoplay, play, pause, progressProp, time]);
765
766
  const scrollRef = (0, import_react3.useRef)(null);
766
767
  const inViewRef = (0, import_react3.useRef)(false);
767
768
  (0, import_react3.useEffect)(() => {
768
- if (!autoplay || effectiveStartOn !== "scrollIntoView") return;
769
- const threshold = trigger.scrollIntoViewThreshold;
769
+ if (!autoplay || !gated) return;
770
+ const threshold = trigger.visibilityThreshold;
770
771
  inViewRef.current = false;
771
772
  const check = () => {
772
773
  const node = scrollRef.current;
@@ -782,17 +783,14 @@ function PixodeskSvgAnimator({
782
783
  if (isIn) {
783
784
  if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));
784
785
  api.play();
785
- } else if (effectiveOutAction === "reset") api.cancel();
786
- else if (effectiveOutAction === "reverse") {
787
- api.setPlaybackRate(-Math.abs(rateRef.current || 1));
788
- api.play();
789
- } else if (effectiveOutAction !== "continue") api.pause();
786
+ } else if (effectiveOffScreen === "reset") api.cancel();
787
+ else api.pause();
790
788
  });
791
789
  };
792
790
  check();
793
791
  const id = setInterval(check, 200);
794
792
  return () => clearInterval(id);
795
- }, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);
793
+ }, [compiled, autoplay, gated, effectiveOffScreen]);
796
794
  (0, import_react3.useEffect)(() => {
797
795
  return () => {
798
796
  (0, import_react_native_reanimated.cancelAnimation)(progress);
@@ -854,30 +852,24 @@ function PixodeskSvgAnimator({
854
852
  } catch (e) {
855
853
  const error = e instanceof Error ? e : new Error(String(e));
856
854
  renderErrorRef.current = error;
857
- makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, error, { phase: "render" });
855
+ makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, import_svg_animator_core4.PxDiagnosticCode.rnRenderFailed, error);
858
856
  return null;
859
857
  }
860
858
  }, [compiled, trackById]);
861
859
  (0, import_react3.useEffect)(() => {
862
860
  const diag = makeDiag();
863
- for (const w of warningsRef.current) diag.warn(import_svg_animator_core4.PxDiagnosticKind.platform, w);
861
+ for (const w of warningsRef.current) diag.warn(import_svg_animator_core4.PxDiagnosticKind.platform, import_svg_animator_core4.PxDiagnosticCode.rnUnsupported, w);
864
862
  }, [root]);
865
863
  const failure = (_b = compiled.error) != null ? _b : renderErrorRef.current;
866
864
  if (failure) return fallback ? fallback(failure) : null;
867
865
  let content = root;
868
- if (autoplay && effectiveStartOn === "scrollIntoView" && root) {
869
- content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { ref: scrollRef, collapsable: false, children: root });
870
- } else if (autoplay && effectiveStartOn === "click" && root) {
866
+ if (autoplay && effectiveStart === "click" && root) {
871
867
  content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
872
868
  import_react_native.Pressable,
873
869
  {
874
870
  onPress: () => {
875
871
  if (playingRef.current) {
876
- if (effectiveOutAction === "reset") api.cancel();
877
- else if (effectiveOutAction === "reverse") {
878
- api.setPlaybackRate(-Math.abs(rateRef.current || 1));
879
- api.play();
880
- } else if (effectiveOutAction !== "continue") api.pause();
872
+ api.pause();
881
873
  } else {
882
874
  if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));
883
875
  api.play();
@@ -887,6 +879,9 @@ function PixodeskSvgAnimator({
887
879
  }
888
880
  );
889
881
  }
882
+ if (autoplay && gated && content) {
883
+ content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { ref: scrollRef, collapsable: false, children: content });
884
+ }
890
885
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PxRnErrorBoundary, { fallback, diag: makeDiag(), children: content });
891
886
  }
892
887
  var PixodeskSvgAnimator_default = PixodeskSvgAnimator;