@pixodesk/svg-animator-rn 1.0.39 → 1.0.40
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 +18 -36
- package/dist/index.cjs +62 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -191
- package/dist/index.d.ts +10 -191
- package/dist/index.js +23 -72
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/PixodeskSvgAnimator.tsx +26 -39
- package/src/PxRnErrorBoundary.tsx +11 -6
- package/src/PxRnPropNames.ts +2 -1
- package/src/PxRnRender.tsx +8 -13
- package/src/PxRnSafety.ts +3 -1
- package/src/PxRnTracks.ts +7 -9
- package/src/PxRnTypeMap.ts +1 -0
- package/src/index.ts +0 -9
package/README.md
CHANGED
|
@@ -188,9 +188,10 @@ const [time, setTime] = useState(0);
|
|
|
188
188
|
| `onCancel` | `() => void` | Called on cancel |
|
|
189
189
|
| `onRemove` | `() => void` | Called when the animator is thrown away — the component unmounted, or a new `doc` replaced it |
|
|
190
190
|
| `onStop` | `() => void` | Called whenever playback halts (pause / cancel / finish / remove) |
|
|
191
|
-
| `onError` | `(
|
|
192
|
-
| `onWarn` | `(diagnostic) => void` |
|
|
193
|
-
| `
|
|
191
|
+
| `onError` | `(diagnostic) => void` | this instance will not play — the document could not be compiled or rendered; `fallback` shows instead. `diagnostic.error` is the Error, `diagnostic.detail.componentStack` when the error boundary caught it |
|
|
192
|
+
| `onWarn` | `(diagnostic) => void` | it plays, but something was ignored, degraded or misspelled; without it → `console.warn` |
|
|
193
|
+
| `muteWarn` | `boolean` | switch the `console.warn` fallback off — for when you know the player has something to say about this document and are prepared to tolerate it. `onWarn`, if you gave it, still fires: mute is about the console, not about you |
|
|
194
|
+
| `muteError` | `boolean` | the same switch for `console.error` |
|
|
194
195
|
| `fallback` | `(error) => ReactElement \| null` | Rendered in place of a failed animation (default: nothing) |
|
|
195
196
|
|
|
196
197
|
With none of `autoplay` / `play` / `pause` / `progress` / `time` set, the component
|
|
@@ -200,14 +201,14 @@ renders the animation statically (initial state, no playback).
|
|
|
200
201
|
|
|
201
202
|
The component never throws for a bad document. Compilation and rendering both
|
|
202
203
|
run inside `try`/`catch`, and the rendered tree sits behind an error boundary,
|
|
203
|
-
so a failure is reported through `onError`
|
|
204
|
-
surrounding screen keeps working.
|
|
204
|
+
so a failure is reported through `onError` — the shared diagnostic (`diagnostic.error` is the
|
|
205
|
+
Error), exactly as on the web — and shows `fallback` while the surrounding screen keeps working.
|
|
205
206
|
|
|
206
207
|
```tsx
|
|
207
208
|
<PixodeskSvgAnimator
|
|
208
209
|
doc={doc}
|
|
209
210
|
autoplay
|
|
210
|
-
onError={
|
|
211
|
+
onError={d => console.warn('animation failed:', d.message)}
|
|
211
212
|
fallback={() => <Text>could not play this animation</Text>}
|
|
212
213
|
/>
|
|
213
214
|
```
|
|
@@ -222,7 +223,7 @@ renderer never reaches JavaScript and cannot be caught — see
|
|
|
222
223
|
| Prop | Why it differs |
|
|
223
224
|
|---|---|
|
|
224
225
|
| `timeline.engine` | Accepted inside `timeline` but ignored. There is no Web Animations API on React Native; playback is always native-driven. |
|
|
225
|
-
| `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
|
|
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. |
|
|
226
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
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. |
|
|
228
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. |
|
|
@@ -259,7 +260,7 @@ properties actually change over time.
|
|
|
259
260
|
|---|---|---|
|
|
260
261
|
| `svg`, `g`, `defs` | ✅ | |
|
|
261
262
|
| `rect`, `circle`, `ellipse`, `line`, `path`, `polygon`, `polyline` | ✅ | |
|
|
262
|
-
| `text`, `tspan` | ✅ | content via
|
|
263
|
+
| `text`, `tspan` | ✅ | content via `textContent` |
|
|
263
264
|
| `textPath` | ✅ | see *Text along a path* below |
|
|
264
265
|
| `image` | ✅ | `href` accepts `data:` URIs; remote URLs are blocked by the sanitizer |
|
|
265
266
|
| `use`, `symbol` | ✅ | animated targets are **inlined into real clones** before render — `<use>` does not propagate animation natively in React Native |
|
|
@@ -275,16 +276,16 @@ properties actually change over time.
|
|
|
275
276
|
<!-- px-check off support matrix, prose -->
|
|
276
277
|
| Attribute | Animates | Notes |
|
|
277
278
|
|---|---|---|
|
|
278
|
-
| `opacity`, `
|
|
279
|
-
| `fill`, `stroke`, `
|
|
280
|
-
| `
|
|
279
|
+
| `opacity`, `fillOpacity`, `strokeOpacity` | ✅ | |
|
|
280
|
+
| `fill`, `stroke`, `stopColor` | ✅ | interpolated as RGBA |
|
|
281
|
+
| `strokeWidth`, `strokeDasharray`, `strokeDashoffset` | ✅ | dash arrays are converted to the numeric form React Native expects |
|
|
281
282
|
| `x`, `y`, `width`, `height`, `cx`, `cy`, `r`, `rx`, `ry` | ✅ | |
|
|
282
283
|
| `d` (**path morphing**) | ✅ | keyframes must share command structure |
|
|
283
284
|
| `transform` (unified parts record) | ✅ | `translate`, `rotate`, `skew`, `scale`, `origin` |
|
|
284
285
|
| `translate` / `rotate` / `scale` (legacy per-key form) | ✅ | |
|
|
285
|
-
| `offset` and `
|
|
286
|
+
| `offset` and `stopColor` on gradient stops | ✅ | |
|
|
286
287
|
| filter primitive attrs (e.g. `stdDeviation`) | ✅ | compiles correctly; on-device rendering unverified |
|
|
287
|
-
| `
|
|
288
|
+
| `fontSize` | ✅ | |
|
|
288
289
|
| Any other numeric SVG attribute | ✅ | interpolated numerically and written straight through |
|
|
289
290
|
|
|
290
291
|
### Effects (`node.effects`)
|
|
@@ -314,8 +315,8 @@ player sees plain nodes. **All are supported:**
|
|
|
314
315
|
| **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` |
|
|
315
316
|
| Per-property `loop` (incl. `alternate` pingpong) | ✅ | expanded before playback |
|
|
316
317
|
| Easing (cubic-bezier and named refs) | ✅ | baked into the sampled tracks |
|
|
317
|
-
| `definitions.animations` / `easings` / `
|
|
318
|
-
| `node.style` (inline
|
|
318
|
+
| `definitions.animations` / `easings` / `fonts` | ✅ | named refs resolved |
|
|
319
|
+
| `node.style` (inline record) | ✅ | applied as props — React Native has no CSS, so explicit attributes win |
|
|
319
320
|
|
|
320
321
|
### Playback and triggers
|
|
321
322
|
|
|
@@ -333,7 +334,7 @@ player sees plain nodes. **All are supported:**
|
|
|
333
334
|
| Trigger `click` | ✅ | wrapped in a `Pressable`; a second tap applies `outAction` |
|
|
334
335
|
| Trigger `scrollIntoView` | ✅ | visibility sampled by measuring against the window (React Native has no `IntersectionObserver`); honors `scrollIntoViewThreshold` and `outAction` |
|
|
335
336
|
| Trigger `mouseOver` | ❌ | no touch equivalent — use `click`, or drive `play` yourself |
|
|
336
|
-
| `timeline.frameRate` | n/a | reanimated runs at the display refresh rate;
|
|
337
|
+
| `timeline.frameRate` | n/a | reanimated runs at the display refresh rate; the player prepares 60 snapshots per second of animation |
|
|
337
338
|
| `timeline.engine` (`auto` / `native` / `js`) | n/a | there is no Web Animations API on React Native — playback is always native-driven |
|
|
338
339
|
|
|
339
340
|
### Known limitations
|
|
@@ -352,7 +353,7 @@ player sees plain nodes. **All are supported:**
|
|
|
352
353
|
glyph placement by `startOffset … startOffset + pathLength` instead of
|
|
353
354
|
`0 … pathLength`, so glyphs past the end of the path reach a lookup that
|
|
354
355
|
returns `NSNotFound`. On native the player gives such a `<textPath>` its own
|
|
355
|
-
open copy of the path
|
|
356
|
+
open copy of the path, which restores the
|
|
356
357
|
correct bounds. Text that would have wrapped around past the end of the loop
|
|
357
358
|
is clipped instead. Web is unaffected and left untouched.
|
|
358
359
|
|
|
@@ -391,25 +392,6 @@ config.resolver.resolveRequest = (context, moduleName, platform) => {
|
|
|
391
392
|
A complete config is in
|
|
392
393
|
[`examples/react-native-preview-player/metro.config.js`](../../examples/react-native-preview-player/metro.config.js).
|
|
393
394
|
|
|
394
|
-
## Advanced exports
|
|
395
|
-
|
|
396
|
-
For custom rendering or diagnostics:
|
|
397
|
-
|
|
398
|
-
- `renderRnNode(node, opts)` — render a `PxNode` tree to `react-native-svg`
|
|
399
|
-
elements, with a `decorate` hook for wrapping animated elements.
|
|
400
|
-
- `compileTracks(doc, { sampleRate, maxSamples, native })` — build the sampled
|
|
401
|
-
tracks yourself; `sampleRate` trades memory for temporal precision
|
|
402
|
-
(default 60/s). `native` selects the value form: the default is the SVG/DOM
|
|
403
|
-
one, `true` gives what the native views want (a `transform` becomes a
|
|
404
|
-
6-number matrix).
|
|
405
|
-
- `sampleProps(tracks, tMs, stepMs, sampleCount, native)` — the worklet-safe
|
|
406
|
-
lookup. `native` renames `transform` to the native views' `matrix`; pass it
|
|
407
|
-
only for values going through reanimated's animated-props path on a device.
|
|
408
|
-
- `openClosedTextPathTargets(doc, warnings?)` — the closed-path `<textPath>`
|
|
409
|
-
workaround described under [Known limitations](#known-limitations).
|
|
410
|
-
- `PxRnErrorBoundary` — the boundary the component wraps itself in.
|
|
411
|
-
- `RN_SVG_COMPONENTS`, `toRnPropName` — the tag and attribute maps.
|
|
412
|
-
|
|
413
395
|
## Example app
|
|
414
396
|
|
|
415
397
|
A full preview player with six animations and transport controls:
|
package/dist/index.cjs
CHANGED
|
@@ -60,29 +60,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
60
60
|
var index_exports = {};
|
|
61
61
|
__export(index_exports, {
|
|
62
62
|
PixodeskSvgAnimator: () => PixodeskSvgAnimator,
|
|
63
|
-
|
|
64
|
-
RN_SVG_COMPONENTS: () => RN_SVG_COMPONENTS,
|
|
65
|
-
compileTracks: () => compileTracks,
|
|
66
|
-
default: () => PixodeskSvgAnimator_default,
|
|
67
|
-
openClosedTextPathTargets: () => openClosedTextPathTargets,
|
|
68
|
-
renderRnNode: () => renderRnNode,
|
|
69
|
-
sampleProps: () => sampleProps,
|
|
70
|
-
toRnPropName: () => toRnPropName,
|
|
71
|
-
toRnProps: () => toRnProps
|
|
63
|
+
default: () => PixodeskSvgAnimator_default
|
|
72
64
|
});
|
|
73
65
|
module.exports = __toCommonJS(index_exports);
|
|
74
66
|
|
|
75
67
|
// src/PixodeskSvgAnimator.tsx
|
|
76
|
-
var
|
|
68
|
+
var import_svg_animator_core4 = require("@pixodesk/svg-animator-core");
|
|
69
|
+
var import_internal6 = require("@pixodesk/svg-animator-core/internal");
|
|
77
70
|
var import_react3 = require("react");
|
|
78
71
|
var import_react_native = require("react-native");
|
|
79
72
|
var import_react_native_reanimated = __toESM(require("react-native-reanimated"), 1);
|
|
80
73
|
|
|
81
74
|
// src/PxRnTracks.ts
|
|
82
|
-
var
|
|
75
|
+
var import_svg_animator_core = require("@pixodesk/svg-animator-core");
|
|
76
|
+
var import_internal2 = require("@pixodesk/svg-animator-core/internal");
|
|
83
77
|
|
|
84
78
|
// src/PxRnPropNames.ts
|
|
85
|
-
var
|
|
79
|
+
var import_internal = require("@pixodesk/svg-animator-core/internal");
|
|
86
80
|
|
|
87
81
|
// src/PxRnMatrix.ts
|
|
88
82
|
var DEG = Math.PI / 180;
|
|
@@ -159,7 +153,7 @@ function toRnPropName(attrName) {
|
|
|
159
153
|
if (DROPPED_ATTRS.has(attrName)) return void 0;
|
|
160
154
|
const override = ATTR_NAME_OVERRIDES[attrName];
|
|
161
155
|
if (override) return override;
|
|
162
|
-
return (0,
|
|
156
|
+
return (0, import_internal.kebabToCamelCaseWord)(attrName);
|
|
163
157
|
}
|
|
164
158
|
var LENGTH_LIST_PROPS = /* @__PURE__ */ new Set(["strokeDasharray"]);
|
|
165
159
|
function toRnPropValue(rnPropName, value, tag, native = false) {
|
|
@@ -179,8 +173,8 @@ function toRnPropValue(rnPropName, value, tag, native = false) {
|
|
|
179
173
|
// src/PxRnTracks.ts
|
|
180
174
|
function compileTracks(doc, opts) {
|
|
181
175
|
var _a, _b, _c, _d;
|
|
182
|
-
const config = (0,
|
|
183
|
-
const duration = +(config.duration ||
|
|
176
|
+
const config = (0, import_svg_animator_core.getAnimatorConfig)(doc) || {};
|
|
177
|
+
const duration = +(config.duration || import_internal2.DEFAULT_DURATION_MS);
|
|
184
178
|
const _iterations = config.iterations;
|
|
185
179
|
let iterations = 1;
|
|
186
180
|
if (typeof _iterations === "number") iterations = _iterations || 1;
|
|
@@ -199,7 +193,7 @@ function compileTracks(doc, opts) {
|
|
|
199
193
|
((_a2 = n == null ? void 0 : n.children) != null ? _a2 : []).forEach(indexTags);
|
|
200
194
|
};
|
|
201
195
|
indexTags(doc);
|
|
202
|
-
const bindings = (0,
|
|
196
|
+
const bindings = (0, import_svg_animator_core.getNormalizedBindings)(doc, import_svg_animator_core.PxTimelineEngine.js) || [];
|
|
203
197
|
const elements = [];
|
|
204
198
|
for (const binding of bindings) {
|
|
205
199
|
const animDef = binding.animate;
|
|
@@ -207,7 +201,7 @@ function compileTracks(doc, opts) {
|
|
|
207
201
|
const props = {};
|
|
208
202
|
for (let i = 0; i < sampleCount; i++) {
|
|
209
203
|
const t = i === sampleCount - 1 ? duration : i * stepMs;
|
|
210
|
-
const values = (0,
|
|
204
|
+
const values = (0, import_svg_animator_core.calcAnimationValues)(animDef, t);
|
|
211
205
|
for (const [attr, value] of Object.entries(values)) {
|
|
212
206
|
const rnProp = toRnPropName(attr);
|
|
213
207
|
if (!rnProp) continue;
|
|
@@ -259,7 +253,8 @@ function sampleProps(tracks, tMs, stepMs, sampleCount, native = false) {
|
|
|
259
253
|
}
|
|
260
254
|
|
|
261
255
|
// src/PxRnRender.tsx
|
|
262
|
-
var
|
|
256
|
+
var import_svg_animator_core2 = require("@pixodesk/svg-animator-core");
|
|
257
|
+
var import_internal3 = require("@pixodesk/svg-animator-core/internal");
|
|
263
258
|
var import_react = require("react");
|
|
264
259
|
|
|
265
260
|
// src/PxRnTypeMap.ts
|
|
@@ -326,10 +321,10 @@ var RN_SVG_COMPONENTS = {
|
|
|
326
321
|
|
|
327
322
|
// src/PxRnRender.tsx
|
|
328
323
|
function toRnProps(props, warnings, tag) {
|
|
329
|
-
const normalized = (0,
|
|
324
|
+
const normalized = (0, import_svg_animator_core2.getNormalizedProps)(props);
|
|
330
325
|
const out = {};
|
|
331
326
|
for (const key of Object.keys(normalized)) {
|
|
332
|
-
const sanitized = (0,
|
|
327
|
+
const sanitized = (0, import_internal3.sanitizeAttributeValue)(key, normalized[key]);
|
|
333
328
|
if (sanitized === void 0) continue;
|
|
334
329
|
const rnKey = toRnPropName(key);
|
|
335
330
|
if (!rnKey) continue;
|
|
@@ -344,7 +339,7 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
344
339
|
const tag = String(type || "g");
|
|
345
340
|
const domType = props.domType;
|
|
346
341
|
if (domType !== void 0) delete props.domType;
|
|
347
|
-
if (
|
|
342
|
+
if (import_internal3.DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {
|
|
348
343
|
(_b = opts.warnings) == null ? void 0 : _b.push("tag blocked (dangerous): " + tag);
|
|
349
344
|
return null;
|
|
350
345
|
}
|
|
@@ -355,17 +350,17 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
355
350
|
}
|
|
356
351
|
const rnProps = toRnProps(props, opts.warnings, tag);
|
|
357
352
|
if (domType !== void 0) rnProps.type = domType;
|
|
358
|
-
const resolved =
|
|
353
|
+
const resolved = style;
|
|
359
354
|
if (resolved) {
|
|
360
355
|
for (const [k, v] of Object.entries(resolved)) {
|
|
361
356
|
const rnKey = toRnPropName(k);
|
|
362
357
|
if (!rnKey || rnKey in rnProps) continue;
|
|
363
|
-
const sanitized = (0,
|
|
358
|
+
const sanitized = (0, import_internal3.sanitizeAttributeValue)(rnKey, v);
|
|
364
359
|
if (sanitized === void 0) continue;
|
|
365
360
|
rnProps[rnKey] = toRnPropValue(rnKey, String(sanitized), tag);
|
|
366
361
|
}
|
|
367
362
|
}
|
|
368
|
-
const textContent = props[
|
|
363
|
+
const textContent = props[import_internal3.TEXT_CONTENT_ATTR];
|
|
369
364
|
let childElements = void 0;
|
|
370
365
|
if (Array.isArray(children) && children.length > 0) {
|
|
371
366
|
childElements = children.map((ch, i) => {
|
|
@@ -391,7 +386,8 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
391
386
|
|
|
392
387
|
// src/PxRnErrorBoundary.tsx
|
|
393
388
|
var import_react2 = require("react");
|
|
394
|
-
var
|
|
389
|
+
var import_svg_animator_core3 = require("@pixodesk/svg-animator-core");
|
|
390
|
+
var import_internal4 = require("@pixodesk/svg-animator-core/internal");
|
|
395
391
|
var PxRnErrorBoundary = class extends import_react2.Component {
|
|
396
392
|
constructor() {
|
|
397
393
|
super(...arguments);
|
|
@@ -401,9 +397,8 @@ var PxRnErrorBoundary = class extends import_react2.Component {
|
|
|
401
397
|
return { error };
|
|
402
398
|
}
|
|
403
399
|
componentDidCatch(error, info) {
|
|
404
|
-
var _a, _b
|
|
405
|
-
(
|
|
406
|
-
((_d = this.props.diag) != null ? _d : (0, import_svg_animator_core4.createDiagnostics)(void 0, "[PixodeskSvgAnimator]")).warn(import_svg_animator_core4.PxDiagnosticKind.internal, "render failed: " + ((_e = error == null ? void 0 : error.message) != null ? _e : String(error)));
|
|
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 });
|
|
407
402
|
}
|
|
408
403
|
componentDidUpdate(prev) {
|
|
409
404
|
if (this.state.error && prev.children !== this.props.children) {
|
|
@@ -418,7 +413,7 @@ var PxRnErrorBoundary = class extends import_react2.Component {
|
|
|
418
413
|
};
|
|
419
414
|
|
|
420
415
|
// src/PxRnSafety.ts
|
|
421
|
-
var
|
|
416
|
+
var import_internal5 = require("@pixodesk/svg-animator-core/internal");
|
|
422
417
|
function isClosedPath(d) {
|
|
423
418
|
return typeof d === "string" && /[zZ]/.test(d);
|
|
424
419
|
}
|
|
@@ -443,7 +438,7 @@ function openClosedTextPathTargets(doc, warnings) {
|
|
|
443
438
|
if (String(n.type) === "textPath") hasTextPath = true;
|
|
444
439
|
});
|
|
445
440
|
if (!hasTextPath) return doc;
|
|
446
|
-
const result = (0,
|
|
441
|
+
const result = (0, import_internal5.deepClone)(doc);
|
|
447
442
|
const byId = /* @__PURE__ */ new Map();
|
|
448
443
|
forEachNode(result, (n) => {
|
|
449
444
|
const id = n.id;
|
|
@@ -470,8 +465,8 @@ function openClosedTextPathTargets(doc, warnings) {
|
|
|
470
465
|
if (!target || !isClosedPath(target.d)) return;
|
|
471
466
|
let copyId = openCopies.get(targetId);
|
|
472
467
|
if (!copyId) {
|
|
473
|
-
const copy = (0,
|
|
474
|
-
copyId = "px_open_" + (0,
|
|
468
|
+
const copy = (0, import_internal5.deepClone)(target);
|
|
469
|
+
copyId = "px_open_" + (0, import_internal5.generateUniqueId)();
|
|
475
470
|
copy.id = copyId;
|
|
476
471
|
copy.d = openPath(String(copy.d));
|
|
477
472
|
delete copy.animate;
|
|
@@ -564,20 +559,20 @@ var EMPTY_TRACKS = {
|
|
|
564
559
|
};
|
|
565
560
|
function compileDocument(doc, overrides, diag) {
|
|
566
561
|
const { timeline, resetTimeline, duration, delay, iterations, startOn } = overrides;
|
|
567
|
-
const warnings = (0,
|
|
568
|
-
for (const w of warnings) diag.warn(
|
|
569
|
-
(0,
|
|
570
|
-
const patch = (0,
|
|
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);
|
|
564
|
+
(0, import_internal6.reportDocumentDiagnostics)(doc, "[PixodeskSvgAnimator]");
|
|
565
|
+
const patch = (0, import_svg_animator_core4.foldTimelineOverride)(timeline, { duration, delay, iterations, startOn });
|
|
571
566
|
if (patch !== void 0 || resetTimeline) {
|
|
572
|
-
const applied = (0,
|
|
573
|
-
for (const w of applied.warnings) diag.warn(
|
|
567
|
+
const applied = (0, import_svg_animator_core4.applyAnimatorConfig)(doc, patch != null ? patch : {}, { resetDefaults: !!resetTimeline });
|
|
568
|
+
for (const w of applied.warnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, "timeline override: " + w);
|
|
574
569
|
doc = applied.doc;
|
|
575
570
|
}
|
|
576
|
-
let prepared = (0,
|
|
571
|
+
let prepared = (0, import_svg_animator_core4.materializeAllInTree)(doc, import_svg_animator_core4.PxTimelineEngine.native);
|
|
577
572
|
if (NATIVE_SVG_VIEWS) {
|
|
578
573
|
prepared = openClosedTextPathTargets(prepared);
|
|
579
574
|
}
|
|
580
|
-
prepared = (0,
|
|
575
|
+
prepared = (0, import_svg_animator_core4.generateNewIds)(prepared);
|
|
581
576
|
const tracks = compileTracks(prepared, { native: NATIVE_SVG_VIEWS });
|
|
582
577
|
return { doc: prepared, tracks, error: null };
|
|
583
578
|
}
|
|
@@ -605,21 +600,15 @@ function PixodeskSvgAnimator({
|
|
|
605
600
|
onError,
|
|
606
601
|
fallback,
|
|
607
602
|
onWarn,
|
|
608
|
-
|
|
603
|
+
muteWarn,
|
|
604
|
+
muteError
|
|
609
605
|
}) {
|
|
610
606
|
var _a, _b;
|
|
611
607
|
const timelineKey = typeof timeline === "string" ? timeline : JSON.stringify(timeline != null ? timeline : null);
|
|
612
|
-
const makeDiag = () => (0,
|
|
613
|
-
onWarn,
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
// keeps "not given" as undefined, so the console fallback still fires.
|
|
617
|
-
onError: onError ? (d) => {
|
|
618
|
-
var _a2;
|
|
619
|
-
return onError((_a2 = d.error) != null ? _a2 : new Error(d.message));
|
|
620
|
-
} : void 0,
|
|
621
|
-
silent
|
|
622
|
-
}, "[PixodeskSvgAnimator]");
|
|
608
|
+
const makeDiag = () => (0, import_internal6.createDiagnostics)(
|
|
609
|
+
{ onWarn, onError, muteWarn, muteError },
|
|
610
|
+
"[PixodeskSvgAnimator]"
|
|
611
|
+
);
|
|
623
612
|
const compiled = (0, import_react3.useMemo)(() => {
|
|
624
613
|
try {
|
|
625
614
|
return compileDocument(
|
|
@@ -629,14 +618,14 @@ function PixodeskSvgAnimator({
|
|
|
629
618
|
);
|
|
630
619
|
} catch (e) {
|
|
631
620
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
632
|
-
makeDiag().
|
|
621
|
+
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, error, { phase: "compile" });
|
|
633
622
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
634
623
|
}
|
|
635
624
|
}, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);
|
|
636
625
|
const tracks = compiled.tracks;
|
|
637
|
-
const totalDuration = (0,
|
|
638
|
-
const seekCeiling = (0,
|
|
639
|
-
const runClock = (0, import_react3.useMemo)(() => (0,
|
|
626
|
+
const totalDuration = (0, import_svg_animator_core4.progressSpanMs)(tracks.duration, tracks.iterations);
|
|
627
|
+
const seekCeiling = (0, import_svg_animator_core4.seekCeilingMs)(tracks.duration, tracks.iterations);
|
|
628
|
+
const runClock = (0, import_react3.useMemo)(() => (0, import_svg_animator_core4.createRunClock)(seekCeiling), [seekCeiling]);
|
|
640
629
|
const progress = (0, import_react_native_reanimated.useSharedValue)(0);
|
|
641
630
|
const playingRef = (0, import_react3.useRef)(false);
|
|
642
631
|
const rateRef = (0, import_react3.useRef)(1);
|
|
@@ -717,8 +706,8 @@ function PixodeskSvgAnimator({
|
|
|
717
706
|
onStop == null ? void 0 : onStop();
|
|
718
707
|
},
|
|
719
708
|
setPlaybackRate: (rate) => {
|
|
720
|
-
if (!(0,
|
|
721
|
-
makeDiag().warn(
|
|
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);
|
|
722
711
|
return;
|
|
723
712
|
}
|
|
724
713
|
rateRef.current = rate;
|
|
@@ -735,41 +724,41 @@ function PixodeskSvgAnimator({
|
|
|
735
724
|
const wasPlaying = playingRef.current;
|
|
736
725
|
(0, import_react_native_reanimated.cancelAnimation)(progress);
|
|
737
726
|
playingRef.current = false;
|
|
738
|
-
const clamped = (0,
|
|
727
|
+
const clamped = (0, import_svg_animator_core4.clampSeekMs)(t, seekCeiling);
|
|
739
728
|
runClock.seek(clamped);
|
|
740
729
|
const withinIteration = tracks.duration > 0 ? clamped % tracks.duration || (clamped === 0 ? 0 : tracks.duration) : 0;
|
|
741
730
|
progress.value = withinIteration;
|
|
742
731
|
if (wasPlaying) startFrom(withinIteration);
|
|
743
732
|
else runClock.stop();
|
|
744
733
|
},
|
|
745
|
-
getCurrentProgress: () => (0,
|
|
734
|
+
getCurrentProgress: () => (0, import_svg_animator_core4.timeToProgress)(runClock.now(), tracks.duration, tracks.iterations),
|
|
746
735
|
setCurrentProgress: (p) => {
|
|
747
|
-
api.setCurrentTime((0,
|
|
736
|
+
api.setCurrentTime((0, import_svg_animator_core4.progressToTimeMs)(p, tracks.duration, tracks.iterations));
|
|
748
737
|
}
|
|
749
738
|
};
|
|
750
739
|
(0, import_react3.useImperativeHandle)(apiRef, () => api, [compiled]);
|
|
751
|
-
const trigger = (0,
|
|
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);
|
|
752
741
|
const effectiveStartOn = trigger.startOn;
|
|
753
742
|
const effectiveOutAction = trigger.outAction;
|
|
754
|
-
const { mode: compMode, warnings: modeWarnings } = (0,
|
|
743
|
+
const { mode: compMode, warnings: modeWarnings } = (0, import_svg_animator_core4.resolveControlMode)({ progress: progressProp, time, play, pause, autoplay });
|
|
755
744
|
(0, import_react3.useEffect)(() => {
|
|
756
745
|
const diag = makeDiag();
|
|
757
|
-
for (const w of modeWarnings) diag.warn(
|
|
746
|
+
for (const w of modeWarnings) diag.warn(import_svg_animator_core4.PxDiagnosticKind.usage, w);
|
|
758
747
|
}, [modeWarnings.join("|")]);
|
|
759
748
|
(0, import_react3.useEffect)(() => {
|
|
760
|
-
if (compMode ===
|
|
761
|
-
const seekMs = time !== void 0 ? time : (0,
|
|
749
|
+
if (compMode === import_svg_animator_core4.PxControlMode.fixedTime) {
|
|
750
|
+
const seekMs = time !== void 0 ? time : (0, import_svg_animator_core4.progressToTimeMs)(progressProp != null ? progressProp : 0, tracks.duration, tracks.iterations);
|
|
762
751
|
api.setCurrentTime(seekMs);
|
|
763
752
|
return;
|
|
764
753
|
}
|
|
765
|
-
if (compMode ===
|
|
754
|
+
if (compMode === import_svg_animator_core4.PxControlMode.play) {
|
|
766
755
|
if (play && !pause) api.play();
|
|
767
756
|
else if (pause) api.pause();
|
|
768
757
|
else if (play === false) api.pause();
|
|
769
758
|
else api.play();
|
|
770
759
|
return;
|
|
771
760
|
}
|
|
772
|
-
if (compMode ===
|
|
761
|
+
if (compMode === import_svg_animator_core4.PxControlMode.autoplay && effectiveStartOn === "load") {
|
|
773
762
|
api.play();
|
|
774
763
|
}
|
|
775
764
|
}, [compiled, compMode, autoplay, play, pause, progressProp, time]);
|
|
@@ -825,7 +814,7 @@ function PixodeskSvgAnimator({
|
|
|
825
814
|
if (!compiled.doc) return null;
|
|
826
815
|
const renderOpts = {
|
|
827
816
|
warnings: warningsRef.current,
|
|
828
|
-
defs: (0,
|
|
817
|
+
defs: (0, import_svg_animator_core4.getDefs)(compiled.doc)
|
|
829
818
|
};
|
|
830
819
|
try {
|
|
831
820
|
return renderRnNode(compiled.doc, __spreadProps(__spreadValues({}, renderOpts), {
|
|
@@ -865,18 +854,15 @@ function PixodeskSvgAnimator({
|
|
|
865
854
|
} catch (e) {
|
|
866
855
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
867
856
|
renderErrorRef.current = error;
|
|
868
|
-
makeDiag().
|
|
857
|
+
makeDiag().error(import_svg_animator_core4.PxDiagnosticKind.internal, error, { phase: "render" });
|
|
869
858
|
return null;
|
|
870
859
|
}
|
|
871
860
|
}, [compiled, trackById]);
|
|
872
861
|
(0, import_react3.useEffect)(() => {
|
|
873
862
|
const diag = makeDiag();
|
|
874
|
-
for (const w of warningsRef.current) diag.warn(
|
|
863
|
+
for (const w of warningsRef.current) diag.warn(import_svg_animator_core4.PxDiagnosticKind.platform, w);
|
|
875
864
|
}, [root]);
|
|
876
865
|
const failure = (_b = compiled.error) != null ? _b : renderErrorRef.current;
|
|
877
|
-
(0, import_react3.useEffect)(() => {
|
|
878
|
-
if (failure) onError == null ? void 0 : onError(failure);
|
|
879
|
-
}, [failure]);
|
|
880
866
|
if (failure) return fallback ? fallback(failure) : null;
|
|
881
867
|
let content = root;
|
|
882
868
|
if (autoplay && effectiveStartOn === "scrollIntoView" && root) {
|
|
@@ -901,19 +887,11 @@ function PixodeskSvgAnimator({
|
|
|
901
887
|
}
|
|
902
888
|
);
|
|
903
889
|
}
|
|
904
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PxRnErrorBoundary, {
|
|
890
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PxRnErrorBoundary, { fallback, diag: makeDiag(), children: content });
|
|
905
891
|
}
|
|
906
892
|
var PixodeskSvgAnimator_default = PixodeskSvgAnimator;
|
|
907
893
|
// Annotate the CommonJS export names for ESM import in node:
|
|
908
894
|
0 && (module.exports = {
|
|
909
|
-
PixodeskSvgAnimator
|
|
910
|
-
PxRnErrorBoundary,
|
|
911
|
-
RN_SVG_COMPONENTS,
|
|
912
|
-
compileTracks,
|
|
913
|
-
openClosedTextPathTargets,
|
|
914
|
-
renderRnNode,
|
|
915
|
-
sampleProps,
|
|
916
|
-
toRnPropName,
|
|
917
|
-
toRnProps
|
|
895
|
+
PixodeskSvgAnimator
|
|
918
896
|
});
|
|
919
897
|
//# sourceMappingURL=index.cjs.map
|