@pixodesk/svg-animator-rn 1.0.30 โ 1.0.35
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 +36 -36
- package/dist/index.cjs +34 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -13
- package/dist/index.d.ts +16 -13
- package/dist/index.js +36 -46
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/PixodeskSvgAnimator.tsx +64 -66
- package/src/PxRnTracks.test.ts +8 -8
- package/src/PxRnTracks.ts +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# animator-rn
|
|
2
2
|
|
|
3
|
+
> ๐ Full user guide: [docs/library/react-native.md](../../docs/library/react-native.md) ยท [all docs](../../README.md#documentation)
|
|
4
|
+
|
|
3
5
|
[](https://github.com/pixodesk/pixodesk-svg-animator/actions/workflows/ci.yml)
|
|
4
6
|
[](https://opensource.org/licenses/MIT)
|
|
5
7
|
|
|
@@ -21,8 +23,8 @@ native SVG, driven on the UI thread.
|
|
|
21
23
|
- **One prop to render:** put the `.json` next to your component, import it, pass
|
|
22
24
|
it as `doc`.
|
|
23
25
|
- **Playback control:** declarative props (`autoplay`, `play`, `pause`,
|
|
24
|
-
`
|
|
25
|
-
- **
|
|
26
|
+
`time`) or an imperative ref (`play()`, `pause()`, `setCurrentTime()`, โฆ).
|
|
27
|
+
- **No size of its own:** it fills whatever `View` you put it in โ give that `View` a `width` and `height`.
|
|
26
28
|
|
|
27
29
|
## Quick start
|
|
28
30
|
|
|
@@ -49,7 +51,7 @@ document says so.
|
|
|
49
51
|
|
|
50
52
|
```tsx
|
|
51
53
|
// Play once when a screen opens, then hold the last frame
|
|
52
|
-
<PixodeskSvgAnimator doc={doc} autoplay iterations={1}
|
|
54
|
+
<PixodeskSvgAnimator doc={doc} autoplay iterations={1} config={{ timeline: { fillMode: 'forwards' } }} />
|
|
53
55
|
|
|
54
56
|
// Loop forever regardless of what the document says
|
|
55
57
|
<PixodeskSvgAnimator doc={doc} autoplay iterations="infinite" />
|
|
@@ -153,13 +155,13 @@ const api = useRef<RnAnimatorApi>(null);
|
|
|
153
155
|
|
|
154
156
|
### Controlled time
|
|
155
157
|
|
|
156
|
-
|
|
158
|
+
Move through the animation with a slider, or show one fixed frame:
|
|
157
159
|
|
|
158
160
|
```tsx
|
|
159
|
-
const [
|
|
161
|
+
const [time, setTime] = useState(0);
|
|
160
162
|
|
|
161
|
-
<PixodeskSvgAnimator doc={doc}
|
|
162
|
-
<Slider minimumValue={0} maximumValue={2000} value={
|
|
163
|
+
<PixodeskSvgAnimator doc={doc} time={time} />
|
|
164
|
+
<Slider minimumValue={0} maximumValue={2000} value={time} onValueChange={setTime} />
|
|
163
165
|
```
|
|
164
166
|
|
|
165
167
|
## Props
|
|
@@ -171,15 +173,14 @@ const [timeMs, setTimeMs] = useState(0);
|
|
|
171
173
|
| `play` | `boolean` | Start playback, ignoring document triggers |
|
|
172
174
|
| `pause` | `boolean` | Pause current playback |
|
|
173
175
|
| `apiRef` | `RefObject<RnAnimatorApi>` | Ref for imperative control |
|
|
174
|
-
| `
|
|
175
|
-
| `
|
|
176
|
-
| `
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
179
|
-
| `
|
|
180
|
-
| `
|
|
181
|
-
| `
|
|
182
|
-
| `outAction` | `OutAction` | What a second tap does with the `click` trigger (default: the document's, else `pause`) |
|
|
176
|
+
| `progress` | `number` | show the frame at this position in the whole timeline (duration ร iterations): `0` is the first frame, `0.5` the middle, `1` the last |
|
|
177
|
+
| `time` | `number` | show the frame at that time, in milliseconds from the start |
|
|
178
|
+
| `config` | `object \| string` | Per-instance override of the document's `animator` block, deep-merged over it โ same shape as the file (`{ timeline: { fillMode, direction, trigger: { outAction, finishAction, โฆ } } }`); `null` at a slot deletes that key. A JSON string is accepted too. `timeline.engine` is accepted but ignored here |
|
|
179
|
+
| `resetDocDefaults` | `boolean` | Ignore the document's playback settings and start from the player's defaults, with `config` on top |
|
|
180
|
+
| `duration` | `number` | Shortcut for `config.timeline.duration` (ms) |
|
|
181
|
+
| `delay` | `number` | Shortcut for `config.timeline.delay` (ms) |
|
|
182
|
+
| `iterations` | `number \| 'infinite'` | Shortcut for `config.timeline.iterations` |
|
|
183
|
+
| `startOn` | `StartOn` | Shortcut for `config.timeline.trigger.startOn`. `mouseOver` has no touch equivalent and is ignored |
|
|
183
184
|
| `onPlay` | `() => void` | Called on play/resume |
|
|
184
185
|
| `onPause` | `() => void` | Called on pause |
|
|
185
186
|
| `onFinish` | `() => void` | Called on natural finish |
|
|
@@ -188,7 +189,7 @@ const [timeMs, setTimeMs] = useState(0);
|
|
|
188
189
|
| `onError` | `(error, componentStack?) => void` | Called when a document cannot be compiled or rendered |
|
|
189
190
|
| `fallback` | `(error) => ReactElement \| null` | Rendered in place of a failed animation (default: nothing) |
|
|
190
191
|
|
|
191
|
-
With none of `autoplay` / `play` / `pause` / `
|
|
192
|
+
With none of `autoplay` / `play` / `pause` / `progress` / `time` set, the component
|
|
192
193
|
renders the animation statically (initial state, no playback).
|
|
193
194
|
|
|
194
195
|
### Failure handling
|
|
@@ -215,11 +216,11 @@ renderer never reaches JavaScript and cannot be caught โ see
|
|
|
215
216
|
|
|
216
217
|
| Prop | Why it differs |
|
|
217
218
|
|---|---|
|
|
218
|
-
| `
|
|
219
|
-
| `frameRate` |
|
|
220
|
-
| `startOn` |
|
|
221
|
-
| `className` / `style` | Not accepted
|
|
222
|
-
| `onRemove` |
|
|
219
|
+
| `timeline.engine` | Accepted inside `config` but ignored. There is no Web Animations API on React Native; playback is always native-driven. |
|
|
220
|
+
| `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 โ `compileTracks({ sampleRate })`, only available when you use the lower-level API instead of the component. |
|
|
221
|
+
| `startOn: 'mouseOver'` | Has no touch equivalent, so it is not honoured. The other four values (`load`, `click`, `scrollIntoView`, `programmatic`) work as they do on the web, from the file or from the `startOn` prop. |
|
|
222
|
+
| `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. |
|
|
223
|
+
| `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. |
|
|
223
224
|
|
|
224
225
|
## How playback works
|
|
225
226
|
|
|
@@ -255,11 +256,11 @@ properties actually change over time.
|
|
|
255
256
|
| `text`, `tspan` | โ
| content via the `text` attribute |
|
|
256
257
|
| `textPath` | โ
| see *Text along a path* below |
|
|
257
258
|
| `image` | โ
| `href` accepts `data:` URIs; remote URLs are blocked by the sanitiser |
|
|
258
|
-
| `use`, `symbol` | โ
| animated targets are **inlined into real clones** before render โ `<use>` does not propagate animation natively in
|
|
259
|
+
| `use`, `symbol` | โ
| animated targets are **inlined into real clones** before render โ `<use>` does not propagate animation natively in React Native |
|
|
259
260
|
| `linearGradient`, `radialGradient`, `stop` | โ
| |
|
|
260
261
|
| `pattern`, `marker` | โ
| static geometry verified; complex cases unverified on device |
|
|
261
262
|
| `mask`, `clipPath` | โ
| |
|
|
262
|
-
| `filter` + all 22 `fe*` primitives | โ
| `feGaussianBlur`, `feDropShadow`, `feColorMatrix`, `feMerge`, `feComponentTransfer` + `feFunc*`, โฆ
|
|
263
|
+
| `filter` + all 22 `fe*` primitives | โ
| `feGaussianBlur`, `feDropShadow`, `feColorMatrix`, `feMerge`, `feComponentTransfer` + `feFunc*`, โฆ **The visual result has not yet been checked on a real device** |
|
|
263
264
|
| `foreignObject` | โ | blocked by the shared sanitiser (embeds arbitrary host content) |
|
|
264
265
|
| `script` | โ | blocked by the shared sanitiser |
|
|
265
266
|
|
|
@@ -269,7 +270,7 @@ properties actually change over time.
|
|
|
269
270
|
|---|---|---|
|
|
270
271
|
| `opacity`, `fill-opacity`, `stroke-opacity` | โ
| |
|
|
271
272
|
| `fill`, `stroke`, `stop-color` | โ
| interpolated as RGBA |
|
|
272
|
-
| `stroke-width`, `stroke-dasharray`, `stroke-dashoffset` | โ
| dash arrays are converted to the numeric form
|
|
273
|
+
| `stroke-width`, `stroke-dasharray`, `stroke-dashoffset` | โ
| dash arrays are converted to the numeric form React Native expects |
|
|
273
274
|
| `x`, `y`, `width`, `height`, `cx`, `cy`, `r`, `rx`, `ry` | โ
| |
|
|
274
275
|
| `d` (**path morphing**) | โ
| keyframes must share command structure |
|
|
275
276
|
| `transform` (unified parts record) | โ
| `translate`, `rotate`, `skew`, `scale`, `origin` |
|
|
@@ -281,7 +282,7 @@ properties actually change over time.
|
|
|
281
282
|
|
|
282
283
|
### Effects (`node.effects`)
|
|
283
284
|
|
|
284
|
-
All effects are materialised by the shared core before rendering, so the
|
|
285
|
+
All effects are materialised by the shared core before rendering, so the React Native
|
|
285
286
|
player sees plain nodes. **All are supported:**
|
|
286
287
|
|
|
287
288
|
| Effect | Status | Notes |
|
|
@@ -294,8 +295,7 @@ player sees plain nodes. **All are supported:**
|
|
|
294
295
|
| `clone` + `retime` | โ
| each clone keeps its own time shift, incl. `retime.timeCrop` (a visibility window on the document timeline) |
|
|
295
296
|
| `fillGradient` / `strokeGradient` | โ
| animated stops **and animated geometry** (`animate.gradientX1`/`Cx`/`R`, โฆ); `gradientTransform` is static (core-wide) |
|
|
296
297
|
| `textPath` | โ
| incl. animated `startOffset` |
|
|
297
|
-
| `text.useGlyphs` | โ
| text becomes `<path>` outlines from `definitions.
|
|
298
|
-
| `isCombinedShape` | โ
| |
|
|
298
|
+
| `text.useGlyphs` | โ
| text becomes `<path>` outlines from `definitions.fonts` โ no font needed |
|
|
299
299
|
|
|
300
300
|
### Motion, timing and references
|
|
301
301
|
|
|
@@ -305,8 +305,8 @@ player sees plain nodes. **All are supported:**
|
|
|
305
305
|
| **Text along a path** | โ
two ways | native `textPath` (incl. animated `startOffset`), or **per-letter motion paths** for smooth results โ the example app uses the latter, since animating native `startOffset` is janky in `react-native-svg` |
|
|
306
306
|
| Per-property `loop` (incl. `alternate` pingpong) | โ
| expanded before playback |
|
|
307
307
|
| Easing (cubic-bezier and named refs) | โ
| baked into the sampled tracks |
|
|
308
|
-
| `definitions.animations` / `easings` / `styles` / `
|
|
309
|
-
| `node.style` (inline or named) | โ
| resolved to props โ
|
|
308
|
+
| `definitions.animations` / `easings` / `styles` / `fonts` | โ
| named refs resolved; `style` presets applied as props |
|
|
309
|
+
| `node.style` (inline or named) | โ
| resolved to props โ React Native has no CSS, so explicit attributes win |
|
|
310
310
|
|
|
311
311
|
### Playback and triggers
|
|
312
312
|
|
|
@@ -314,17 +314,17 @@ player sees plain nodes. **All are supported:**
|
|
|
314
314
|
|---|---|---|
|
|
315
315
|
| `duration`, `delay`, `iterations` (incl. `'infinite'`) | โ
| |
|
|
316
316
|
| `direction` โ all four values | โ
| |
|
|
317
|
-
| `
|
|
318
|
-
| `
|
|
317
|
+
| `fillMode` โ `forwards` / `backwards` / `both` / `none` | โ
| |
|
|
318
|
+
| `trigger.finishAction: 'reset'` | โ
| |
|
|
319
319
|
| `play` / `pause` / `cancel` / `finish` | โ
| |
|
|
320
|
-
| `setCurrentTime` โ
|
|
320
|
+
| `setCurrentTime` โ jump to a time, including **while playing** | โ
| playback continues from the new point |
|
|
321
321
|
| `setPlaybackRate` โ faster, slower and **reverse** (negative) | โ
| composes with `direction` |
|
|
322
322
|
| Trigger `load` / `programmatic` | โ
| |
|
|
323
323
|
| Trigger `click` | โ
| wrapped in a `Pressable`; a second tap applies `outAction` |
|
|
324
|
-
| Trigger `scrollIntoView` | โ
| visibility sampled by measuring against the window (
|
|
324
|
+
| Trigger `scrollIntoView` | โ
| visibility sampled by measuring against the window (React Native has no `IntersectionObserver`); honours `scrollIntoViewThreshold` and `outAction` |
|
|
325
325
|
| Trigger `mouseOver` | โ | no touch equivalent โ use `click`, or drive `play` yourself |
|
|
326
|
-
| `frameRate` | n/a | reanimated runs at the display refresh rate; use `compileTracks({sampleRate})` to trade memory for temporal precision |
|
|
327
|
-
| `
|
|
326
|
+
| `timeline.frameRate` | n/a | reanimated runs at the display refresh rate; use `compileTracks({sampleRate})` to trade memory for temporal precision |
|
|
327
|
+
| `timeline.engine` (`auto` / `native` / `js`) | n/a | there is no Web Animations API on React Native โ playback is always native-driven |
|
|
328
328
|
|
|
329
329
|
### Known limitations
|
|
330
330
|
|
package/dist/index.cjs
CHANGED
|
@@ -199,7 +199,7 @@ function compileTracks(doc, opts) {
|
|
|
199
199
|
((_a2 = n == null ? void 0 : n.children) != null ? _a2 : []).forEach(indexTags);
|
|
200
200
|
};
|
|
201
201
|
indexTags(doc);
|
|
202
|
-
const bindings = (0, import_svg_animator_core2.getNormalisedBindings)(doc, import_svg_animator_core2.
|
|
202
|
+
const bindings = (0, import_svg_animator_core2.getNormalisedBindings)(doc, import_svg_animator_core2.PxTimelineEngine.js) || [];
|
|
203
203
|
const elements = [];
|
|
204
204
|
for (const binding of bindings) {
|
|
205
205
|
const animDef = binding.animate;
|
|
@@ -562,43 +562,39 @@ var EMPTY_TRACKS = {
|
|
|
562
562
|
elements: []
|
|
563
563
|
};
|
|
564
564
|
function compileDocument(doc, overrides) {
|
|
565
|
-
const {
|
|
565
|
+
const { config, resetDocDefaults, duration, delay, iterations, startOn } = overrides;
|
|
566
566
|
const warnings = (0, import_svg_animator_core5.validateNodeEffects)(doc);
|
|
567
567
|
for (const w of warnings) console.warn("[PixodeskSvgAnimator] effects shape warning:", w);
|
|
568
|
-
|
|
568
|
+
(0, import_svg_animator_core5.reportDocumentDiagnostics)(doc, "[PixodeskSvgAnimator]");
|
|
569
|
+
const patch = (0, import_svg_animator_core5.foldAnimatorConfigShortcuts)(config, { duration, delay, iterations, startOn });
|
|
570
|
+
if (patch !== void 0 || resetDocDefaults) {
|
|
571
|
+
const applied = (0, import_svg_animator_core5.applyAnimatorConfig)(doc, patch != null ? patch : {}, { resetDefaults: !!resetDocDefaults });
|
|
572
|
+
for (const w of applied.warnings) console.warn("[PixodeskSvgAnimator] config override:", w);
|
|
573
|
+
doc = applied.doc;
|
|
574
|
+
}
|
|
575
|
+
let prepared = (0, import_svg_animator_core5.materialiseAllInTree)(doc, import_svg_animator_core5.PxTimelineEngine.native);
|
|
569
576
|
if (NATIVE_SVG_VIEWS) {
|
|
570
577
|
prepared = openClosedTextPathTargets(prepared);
|
|
571
578
|
}
|
|
572
|
-
const animator = (0, import_svg_animator_core5.getAnimatorConfig)(prepared) || {};
|
|
573
|
-
prepared = __spreadProps(__spreadValues({}, prepared), {
|
|
574
|
-
animator: __spreadProps(__spreadValues({}, animator), {
|
|
575
|
-
duration: duration !== void 0 ? duration : animator.duration,
|
|
576
|
-
delay: delay !== void 0 ? delay : animator.delay,
|
|
577
|
-
iterations: iterations !== void 0 ? iterations : animator.iterations,
|
|
578
|
-
fill: fill !== void 0 ? fill : animator.fill,
|
|
579
|
-
direction: direction !== void 0 ? direction : animator.direction,
|
|
580
|
-
resetOnFinish: resetOnFinish !== void 0 ? resetOnFinish : animator.resetOnFinish
|
|
581
|
-
})
|
|
582
|
-
});
|
|
583
579
|
prepared = (0, import_svg_animator_core5.generateNewIds)(prepared);
|
|
584
580
|
const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });
|
|
585
581
|
return { doc: prepared, tracks, error: null };
|
|
586
582
|
}
|
|
587
583
|
function PixodeskSvgAnimator({
|
|
588
584
|
doc,
|
|
585
|
+
config,
|
|
586
|
+
resetDocDefaults,
|
|
589
587
|
duration,
|
|
590
588
|
delay,
|
|
591
589
|
iterations,
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
resetOnFinish,
|
|
595
|
-
outAction: outActionProp,
|
|
590
|
+
startOn,
|
|
591
|
+
// (`progress` prop aliased โ the name is taken by the internal reanimated SharedValue)
|
|
596
592
|
autoplay,
|
|
597
593
|
play,
|
|
598
594
|
pause,
|
|
599
595
|
apiRef,
|
|
596
|
+
progress: progressProp,
|
|
600
597
|
time,
|
|
601
|
-
timeMs,
|
|
602
598
|
onPlay,
|
|
603
599
|
onStop,
|
|
604
600
|
onPause,
|
|
@@ -608,18 +604,19 @@ function PixodeskSvgAnimator({
|
|
|
608
604
|
fallback
|
|
609
605
|
}) {
|
|
610
606
|
var _a, _b, _c, _d;
|
|
607
|
+
const configKey = typeof config === "string" ? config : JSON.stringify(config != null ? config : null);
|
|
611
608
|
const compiled = (0, import_react3.useMemo)(() => {
|
|
612
609
|
try {
|
|
613
610
|
return compileDocument(
|
|
614
611
|
doc,
|
|
615
|
-
{
|
|
612
|
+
{ config, resetDocDefaults, duration, delay, iterations, startOn }
|
|
616
613
|
);
|
|
617
614
|
} catch (e) {
|
|
618
615
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
619
616
|
console.warn("[PixodeskSvgAnimator] could not compile the document:", error.message);
|
|
620
617
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
621
618
|
}
|
|
622
|
-
}, [doc,
|
|
619
|
+
}, [doc, configKey, resetDocDefaults, duration, delay, iterations, startOn]);
|
|
623
620
|
const tracks = compiled.tracks;
|
|
624
621
|
const totalDuration = tracks.duration * (tracks.iterations === Infinity ? 1 : tracks.iterations);
|
|
625
622
|
const progress = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
@@ -713,11 +710,11 @@ function PixodeskSvgAnimator({
|
|
|
713
710
|
};
|
|
714
711
|
(0, import_react3.useImperativeHandle)(apiRef, () => api, [compiled]);
|
|
715
712
|
const trigger = compiled.doc ? (_a = (0, import_svg_animator_core5.getAnimatorConfig)(compiled.doc)) == null ? void 0 : _a.trigger : void 0;
|
|
716
|
-
const
|
|
717
|
-
const
|
|
713
|
+
const effectiveStartOn = (_b = trigger == null ? void 0 : trigger.startOn) != null ? _b : "load";
|
|
714
|
+
const effectiveOutAction = (_c = trigger == null ? void 0 : trigger.outAction) != null ? _c : "pause";
|
|
718
715
|
(0, import_react3.useEffect)(() => {
|
|
719
|
-
if (
|
|
720
|
-
const seekMs =
|
|
716
|
+
if (progressProp !== void 0 || time !== void 0) {
|
|
717
|
+
const seekMs = time !== void 0 ? time : (progressProp != null ? progressProp : 0) * totalDuration;
|
|
721
718
|
api.setCurrentTime(seekMs);
|
|
722
719
|
return;
|
|
723
720
|
}
|
|
@@ -728,15 +725,15 @@ function PixodeskSvgAnimator({
|
|
|
728
725
|
else api.play();
|
|
729
726
|
return;
|
|
730
727
|
}
|
|
731
|
-
if (autoplay &&
|
|
728
|
+
if (autoplay && effectiveStartOn === "load") {
|
|
732
729
|
api.play();
|
|
733
730
|
}
|
|
734
|
-
}, [compiled, autoplay, play, pause,
|
|
731
|
+
}, [compiled, autoplay, play, pause, progressProp, time]);
|
|
735
732
|
const scrollRef = (0, import_react3.useRef)(null);
|
|
736
733
|
const inViewRef = (0, import_react3.useRef)(false);
|
|
737
734
|
(0, import_react3.useEffect)(() => {
|
|
738
735
|
var _a2;
|
|
739
|
-
if (!autoplay ||
|
|
736
|
+
if (!autoplay || effectiveStartOn !== "scrollIntoView") return;
|
|
740
737
|
const threshold = (_a2 = trigger == null ? void 0 : trigger.scrollIntoViewThreshold) != null ? _a2 : 0;
|
|
741
738
|
inViewRef.current = false;
|
|
742
739
|
const check = () => {
|
|
@@ -753,17 +750,17 @@ function PixodeskSvgAnimator({
|
|
|
753
750
|
if (isIn) {
|
|
754
751
|
if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));
|
|
755
752
|
api.play();
|
|
756
|
-
} else if (
|
|
757
|
-
else if (
|
|
753
|
+
} else if (effectiveOutAction === "reset") api.cancel();
|
|
754
|
+
else if (effectiveOutAction === "reverse") {
|
|
758
755
|
api.setPlaybackRate(-Math.abs(rateRef.current || 1));
|
|
759
756
|
api.play();
|
|
760
|
-
} else if (
|
|
757
|
+
} else if (effectiveOutAction !== "continue") api.pause();
|
|
761
758
|
});
|
|
762
759
|
};
|
|
763
760
|
check();
|
|
764
761
|
const id = setInterval(check, 200);
|
|
765
762
|
return () => clearInterval(id);
|
|
766
|
-
}, [compiled, autoplay,
|
|
763
|
+
}, [compiled, autoplay, effectiveStartOn, effectiveOutAction]);
|
|
767
764
|
(0, import_react3.useEffect)(() => {
|
|
768
765
|
return () => {
|
|
769
766
|
(0, import_react_native_reanimated.cancelAnimation)(progress);
|
|
@@ -836,19 +833,19 @@ function PixodeskSvgAnimator({
|
|
|
836
833
|
}, [failure]);
|
|
837
834
|
if (failure) return fallback ? fallback(failure) : null;
|
|
838
835
|
let content = root;
|
|
839
|
-
if (autoplay &&
|
|
836
|
+
if (autoplay && effectiveStartOn === "scrollIntoView" && root) {
|
|
840
837
|
content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_native.View, { ref: scrollRef, collapsable: false, children: root });
|
|
841
|
-
} else if (autoplay &&
|
|
838
|
+
} else if (autoplay && effectiveStartOn === "click" && root) {
|
|
842
839
|
content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
843
840
|
import_react_native.Pressable,
|
|
844
841
|
{
|
|
845
842
|
onPress: () => {
|
|
846
843
|
if (playingRef.current) {
|
|
847
|
-
if (
|
|
848
|
-
else if (
|
|
844
|
+
if (effectiveOutAction === "reset") api.cancel();
|
|
845
|
+
else if (effectiveOutAction === "reverse") {
|
|
849
846
|
api.setPlaybackRate(-Math.abs(rateRef.current || 1));
|
|
850
847
|
api.play();
|
|
851
|
-
} else if (
|
|
848
|
+
} else if (effectiveOutAction !== "continue") api.pause();
|
|
852
849
|
} else {
|
|
853
850
|
if (rateRef.current < 0) api.setPlaybackRate(Math.abs(rateRef.current));
|
|
854
851
|
api.play();
|