@pixodesk/svg-animator-rn 1.0.39 → 1.0.41
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 +12 -193
- package/dist/index.d.ts +12 -193
- package/dist/index.js +30 -79
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/PixodeskSvgAnimator.tsx +31 -44
- package/src/PxRnErrorBoundary.tsx +11 -6
- package/src/PxRnPropNames.ts +3 -2
- package/src/PxRnRender.tsx +12 -17
- package/src/PxRnSafety.ts +3 -1
- package/src/PxRnTracks.ts +9 -11
- package/src/PxRnTypeMap.ts +1 -0
- package/src/index.ts +0 -9
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import { clampSeekMs,
|
|
7
|
-
|
|
6
|
+
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PX_RATE_REJECTED, PxDiagnosticKind, seekCeilingMs, timeToProgress, type PxAnimatorHandle, type PxAnimatorCallbacks, type PxControlProps, type PxPlaybackOverride, type PxDiagnostics, generateNewIds, getAnimatorConfig, getDefinitions, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine, PxControlMode, resolveControlMode, type PxFillMode, type PxOutAction, type PxPlaybackDirection, type PxAnimatedSvgDocument, type PxTimelinePatch, type PxNode, applyAnimatorConfig, foldTimelineOverride } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { createDiagnostics, reportDocumentDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
8
8
|
import React, { createElement, useEffect, useImperativeHandle, useMemo, useRef, useState, type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
9
9
|
import { Dimensions, Platform, Pressable, View } from 'react-native';
|
|
10
10
|
import Animated, {
|
|
@@ -31,18 +31,19 @@ import { openClosedTextPathTargets } from './PxRnSafety';
|
|
|
31
31
|
* The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's
|
|
32
32
|
* name (review §9). It no longer "mirrors" the React one by hand: the local copy had already
|
|
33
33
|
* drifted (its `setPlaybackRate` comment lost "negative plays backwards"). One definition.
|
|
34
|
+
* @public
|
|
34
35
|
*/
|
|
35
36
|
export type RnAnimatorApi = PxAnimatorHandle;
|
|
36
37
|
|
|
37
38
|
/**
|
|
38
39
|
* The component's props. The playback override, the control props and the callbacks are core's
|
|
39
|
-
* shared shapes (review §9) — `
|
|
40
|
-
* `
|
|
41
|
-
* on this platform is declared here: `
|
|
42
|
-
*
|
|
40
|
+
* shared shapes (review §9) — `PxPlaybackOverride`, `PxControlProps` and
|
|
41
|
+
* `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs
|
|
42
|
+
* on this platform is declared here: `fallback`, which has no web counterpart.
|
|
43
|
+
* @public
|
|
43
44
|
*/
|
|
44
45
|
export interface PixodeskSvgAnimatorProps
|
|
45
|
-
extends
|
|
46
|
+
extends PxPlaybackOverride, PxControlProps, PxAnimatorCallbacks {
|
|
46
47
|
|
|
47
48
|
// -- Source ---------------------------------------------------------------
|
|
48
49
|
|
|
@@ -50,7 +51,7 @@ export interface PixodeskSvgAnimatorProps
|
|
|
50
51
|
doc: PxAnimatedSvgDocument;
|
|
51
52
|
|
|
52
53
|
/**
|
|
53
|
-
* Per-instance override of the document's `timeline` — see `
|
|
54
|
+
* Per-instance override of the document's `timeline` — see `PxPlaybackOverride`.
|
|
54
55
|
*
|
|
55
56
|
* `engine` is accepted but ignored here: React Native always uses the `native` (fully
|
|
56
57
|
* flattened) materialization, because react-native-svg has no `<use>` shadow-tree
|
|
@@ -67,18 +68,12 @@ export interface PixodeskSvgAnimatorProps
|
|
|
67
68
|
apiRef?: React.RefObject<RnAnimatorApi | null>;
|
|
68
69
|
|
|
69
70
|
// -- Failure handling -----------------------------------------------------
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
* Only JavaScript failures reach this — a crash inside react-native-svg's
|
|
77
|
-
* native renderer bypasses JavaScript entirely. Richer than the web's
|
|
78
|
-
* `onError(diagnostic)` because the error boundary hands it a component stack; it is
|
|
79
|
-
* adapted into the shared diagnostics channel rather than narrowed to match it.
|
|
80
|
-
*/
|
|
81
|
-
onError?: (error: Error, componentStack?: string) => void;
|
|
71
|
+
// A document that cannot be compiled or rendered is reported through `onError` — the same
|
|
72
|
+
// `(diagnostic) => void` as every other player (review §25.1), with `diagnostic.error` the
|
|
73
|
+
// thrown Error and, when the error boundary caught it, `diagnostic.detail.componentStack`.
|
|
74
|
+
// The component renders `fallback` instead of throwing, so one broken animation never
|
|
75
|
+
// takes down the screen around it. Only JavaScript failures reach this — a crash inside
|
|
76
|
+
// react-native-svg's native renderer bypasses JavaScript entirely.
|
|
82
77
|
|
|
83
78
|
/** Rendered in place of the animation after a failure. Default: nothing. */
|
|
84
79
|
fallback?: (error: Error) => ReactElement | null;
|
|
@@ -222,7 +217,7 @@ function SampledSubtree({
|
|
|
222
217
|
|
|
223
218
|
/** Overrides that shadow the document's own `animator` config. */
|
|
224
219
|
/** The override subset of the props — core's shared shape, not a local copy (review §9). */
|
|
225
|
-
type ConfigOverrides =
|
|
220
|
+
type ConfigOverrides = PxPlaybackOverride;
|
|
226
221
|
|
|
227
222
|
interface Compiled {
|
|
228
223
|
/** Materialized document, or null when compilation failed. */
|
|
@@ -254,7 +249,7 @@ function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides,
|
|
|
254
249
|
// patch would be read by none of the pipeline. Same call, same rules, on every surface.
|
|
255
250
|
const patch = foldTimelineOverride(timeline, { duration, delay, iterations, startOn });
|
|
256
251
|
if (patch !== undefined || resetTimeline) {
|
|
257
|
-
const applied = applyAnimatorConfig(doc, patch ?? {}, {
|
|
252
|
+
const applied = applyAnimatorConfig(doc, patch ?? {}, { resetTimeline: !!resetTimeline });
|
|
258
253
|
for (const w of applied.warnings) diag.warn(PxDiagnosticKind.usage, 'timeline override: ' + w);
|
|
259
254
|
doc = applied.doc;
|
|
260
255
|
}
|
|
@@ -293,12 +288,13 @@ function compileDocument(doc: PxAnimatedSvgDocument, overrides: ConfigOverrides,
|
|
|
293
288
|
* played back natively: a single reanimated progress value driven by
|
|
294
289
|
* `withTiming`/`withRepeat` on the UI thread, with per-element worklets
|
|
295
290
|
* indexing the precompiled tracks. No JS-thread frame loop.
|
|
291
|
+
* @public
|
|
296
292
|
*/
|
|
297
293
|
export function PixodeskSvgAnimator({
|
|
298
294
|
doc, timeline, resetTimeline, duration, delay, iterations, startOn,
|
|
299
295
|
// (`progress` prop aliased — the name is taken by the internal reanimated SharedValue)
|
|
300
296
|
autoplay, play, pause, apiRef, progress: progressProp, time,
|
|
301
|
-
onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn,
|
|
297
|
+
onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError,
|
|
302
298
|
}: PixodeskSvgAnimatorProps): ReactElement | null {
|
|
303
299
|
|
|
304
300
|
// -- Compile the document (once per doc/override change) ------------------
|
|
@@ -315,14 +311,8 @@ export function PixodeskSvgAnimator({
|
|
|
315
311
|
* be a function, so the channel would believe a handler exists and the console fallback
|
|
316
312
|
* would never fire for anyone who passed nothing.
|
|
317
313
|
*/
|
|
318
|
-
const makeDiag = (): PxDiagnostics => createDiagnostics(
|
|
319
|
-
onWarn,
|
|
320
|
-
// This component's public `onError` is richer — `(error, componentStack?)` — and the
|
|
321
|
-
// error boundary hands it a component stack. Adapt rather than narrow it; the ternary
|
|
322
|
-
// keeps "not given" as undefined, so the console fallback still fires.
|
|
323
|
-
onError: onError ? (d: PxDiagnostic) => onError(d.error ?? new Error(d.message)) : undefined,
|
|
324
|
-
silent,
|
|
325
|
-
}, '[PixodeskSvgAnimator]');
|
|
314
|
+
const makeDiag = (): PxDiagnostics => createDiagnostics(
|
|
315
|
+
{ onWarn, onError, muteWarn, muteError }, '[PixodeskSvgAnimator]');
|
|
326
316
|
|
|
327
317
|
const compiled = useMemo((): Compiled => {
|
|
328
318
|
try {
|
|
@@ -332,9 +322,10 @@ export function PixodeskSvgAnimator({
|
|
|
332
322
|
makeDiag(),
|
|
333
323
|
);
|
|
334
324
|
} catch (e) {
|
|
335
|
-
// A malformed document must not take the host screen down with it.
|
|
325
|
+
// A malformed document must not take the host screen down with it. This instance
|
|
326
|
+
// will not play — an ERROR, reported once, here (review §25.1).
|
|
336
327
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
337
|
-
makeDiag().
|
|
328
|
+
makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'compile' });
|
|
338
329
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
339
330
|
}
|
|
340
331
|
// `timeline` is an object prop, so a fresh literal each render would recompile the whole
|
|
@@ -611,7 +602,7 @@ export function PixodeskSvgAnimator({
|
|
|
611
602
|
|
|
612
603
|
const renderOpts: RenderRnNodeOptions = {
|
|
613
604
|
warnings: warningsRef.current,
|
|
614
|
-
defs:
|
|
605
|
+
defs: getDefinitions(compiled.doc),
|
|
615
606
|
};
|
|
616
607
|
try {
|
|
617
608
|
return renderRnNode(compiled.doc as PxNode, {
|
|
@@ -653,11 +644,11 @@ export function PixodeskSvgAnimator({
|
|
|
653
644
|
},
|
|
654
645
|
});
|
|
655
646
|
} catch (e) {
|
|
656
|
-
// Building the element tree threw — report it
|
|
657
|
-
//
|
|
647
|
+
// Building the element tree threw — this instance will not play: report it once
|
|
648
|
+
// (an ERROR, review §25.1) and render nothing rather than unmount the host screen.
|
|
658
649
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
659
650
|
renderErrorRef.current = error;
|
|
660
|
-
makeDiag().
|
|
651
|
+
makeDiag().error(PxDiagnosticKind.internal, error, { phase: 'render' });
|
|
661
652
|
return null;
|
|
662
653
|
}
|
|
663
654
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -671,13 +662,9 @@ export function PixodeskSvgAnimator({
|
|
|
671
662
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
672
663
|
}, [root]);
|
|
673
664
|
|
|
674
|
-
//
|
|
665
|
+
// A compile/render failure was reported where it was caught (once, as an error); here it
|
|
666
|
+
// only decides what to show.
|
|
675
667
|
const failure = compiled.error ?? renderErrorRef.current;
|
|
676
|
-
useEffect(() => {
|
|
677
|
-
if (failure) onError?.(failure);
|
|
678
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
679
|
-
}, [failure]);
|
|
680
|
-
|
|
681
668
|
if (failure) return fallback ? fallback(failure) : null;
|
|
682
669
|
|
|
683
670
|
// `startOn: 'click'` — the touch analogue of the web player's click trigger:
|
|
@@ -712,7 +699,7 @@ export function PixodeskSvgAnimator({
|
|
|
712
699
|
// and commit of the tree — react-native-svg internals, reanimated failing
|
|
713
700
|
// to attach to a component that turns out not to be a host view, and so on.
|
|
714
701
|
return (
|
|
715
|
-
<PxRnErrorBoundary
|
|
702
|
+
<PxRnErrorBoundary fallback={fallback} diag={makeDiag()}>
|
|
716
703
|
{content}
|
|
717
704
|
</PxRnErrorBoundary>
|
|
718
705
|
);
|
|
@@ -4,14 +4,19 @@
|
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
6
|
import { Component, type ErrorInfo, type ReactNode } from 'react';
|
|
7
|
-
import {
|
|
7
|
+
import { PxDiagnosticKind, type PxDiagnostics } from '@pixodesk/svg-animator-core';
|
|
8
|
+
import { createDiagnostics } from '@pixodesk/svg-animator-core/internal';
|
|
8
9
|
|
|
10
|
+
/** @public @advanced */
|
|
9
11
|
export interface PxRnErrorBoundaryProps {
|
|
10
12
|
children: ReactNode;
|
|
11
13
|
/** Rendered instead of the children once something has thrown. */
|
|
12
14
|
fallback?: (error: Error) => ReactNode;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Where the failure is reported (API review §5, §25.1): `error(internal, …)` with
|
|
17
|
+
* `{ componentStack }` as the detail — so it reaches `onError` like every other failure.
|
|
18
|
+
* Defaults to the console.
|
|
19
|
+
*/
|
|
15
20
|
diag?: PxDiagnostics;
|
|
16
21
|
}
|
|
17
22
|
|
|
@@ -25,12 +30,13 @@ interface State {
|
|
|
25
30
|
* A throw anywhere in the rendered SVG tree — an unsupported prop shape, a
|
|
26
31
|
* react-native-svg internal, a reanimated attachment failure — otherwise
|
|
27
32
|
* unmounts the whole React tree above it. Here it is contained to this one
|
|
28
|
-
* animation, reported through
|
|
33
|
+
* animation, reported through the diagnostics channel, and replaced by `fallback`.
|
|
29
34
|
*
|
|
30
35
|
* NOTE the limit: this catches JavaScript errors only. A crash INSIDE the
|
|
31
36
|
* native renderer (see `openClosedTextPathTargets` for a real example) never
|
|
32
37
|
* reaches JavaScript and cannot be caught here — those have to be avoided
|
|
33
38
|
* rather than handled.
|
|
39
|
+
* @public @advanced
|
|
34
40
|
*/
|
|
35
41
|
export class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {
|
|
36
42
|
override state: State = { error: null };
|
|
@@ -40,9 +46,8 @@ export class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State>
|
|
|
40
46
|
}
|
|
41
47
|
|
|
42
48
|
override componentDidCatch(error: Error, info: ErrorInfo): void {
|
|
43
|
-
this.props.onError?.(error, info?.componentStack ?? undefined);
|
|
44
49
|
(this.props.diag ?? createDiagnostics(undefined, '[PixodeskSvgAnimator]'))
|
|
45
|
-
.
|
|
50
|
+
.error(PxDiagnosticKind.internal, error, { componentStack: info?.componentStack ?? undefined });
|
|
46
51
|
}
|
|
47
52
|
|
|
48
53
|
override componentDidUpdate(prev: PxRnErrorBoundaryProps): void {
|
package/src/PxRnPropNames.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core';
|
|
6
|
+
import { kebabToCamelCaseWord } from '@pixodesk/svg-animator-core/internal';
|
|
7
7
|
import { svgTransformToMatrix } from './PxRnMatrix';
|
|
8
8
|
|
|
9
9
|
/** Attribute names with a react-native-svg prop equivalent under a
|
|
@@ -17,11 +17,12 @@ const DROPPED_ATTRS = new Set(['class', 'className', 'style', 'xmlns', 'xmlns:xl
|
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Converts one normalized wire attribute name (camelCase after core's
|
|
20
|
-
* `
|
|
20
|
+
* `toDomProps`, or kebab-case raw) to a react-native-svg prop name.
|
|
21
21
|
* Returns undefined for props that must be dropped.
|
|
22
22
|
*
|
|
23
23
|
* Pure (no react-native-svg import) so the track compiler and its tests
|
|
24
24
|
* don't need a React Native environment.
|
|
25
|
+
* @internal
|
|
25
26
|
*/
|
|
26
27
|
export function toRnPropName(attrName: string): string | undefined {
|
|
27
28
|
if (DROPPED_ATTRS.has(attrName)) return undefined;
|
package/src/PxRnRender.tsx
CHANGED
|
@@ -3,24 +3,18 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
resolveStyle,
|
|
9
|
-
sanitizeAttributeValue,
|
|
10
|
-
DISALLOWED_SVG_TAGS_LOWER,
|
|
11
|
-
TEXT_CONTENT_ATTR,
|
|
12
|
-
type PxDefs,
|
|
13
|
-
type PxNode,
|
|
14
|
-
} from '@pixodesk/svg-animator-core';
|
|
6
|
+
import { toDomProps, type PxDefinitions, type PxNode } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { sanitizeAttributeValue, PX_DISALLOWED_SVG_TAGS_LOWER, PX_TEXT_CONTENT_ATTR } from '@pixodesk/svg-animator-core/internal';
|
|
15
8
|
import { createElement, type ComponentType, type ReactElement, type ReactNode } from 'react';
|
|
16
9
|
import { RN_SVG_COMPONENTS } from './PxRnTypeMap';
|
|
17
10
|
import { toRnPropName, toRnPropValue } from './PxRnPropNames';
|
|
18
11
|
|
|
12
|
+
/** @internal */
|
|
19
13
|
export interface RenderRnNodeOptions {
|
|
20
14
|
/** Collects non-fatal issues (unsupported tags, dropped attrs). */
|
|
21
15
|
warnings?: Array<string>;
|
|
22
16
|
/** `definitions` from the document, used to resolve named `style` presets. */
|
|
23
|
-
defs?:
|
|
17
|
+
defs?: PxDefinitions;
|
|
24
18
|
/**
|
|
25
19
|
* Wraps the created element for animated nodes: receives the resolved
|
|
26
20
|
* component + static props and returns the element to mount (the animator
|
|
@@ -44,9 +38,10 @@ export interface RenderRnNodeOptions {
|
|
|
44
38
|
* Converts core-normalized wire props into react-native-svg props: RN prop
|
|
45
39
|
* naming, sanitization (same security rules as the web renderer), numeric
|
|
46
40
|
* coercion where possible.
|
|
41
|
+
* @internal
|
|
47
42
|
*/
|
|
48
43
|
export function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any> {
|
|
49
|
-
const normalized =
|
|
44
|
+
const normalized = toDomProps(props);
|
|
50
45
|
const out: Record<string, any> = {};
|
|
51
46
|
for (const key of Object.keys(normalized)) {
|
|
52
47
|
const sanitized = sanitizeAttributeValue(key, normalized[key]);
|
|
@@ -62,6 +57,7 @@ export function toRnProps(props: Record<string, any>, warnings?: Array<string>,
|
|
|
62
57
|
* Renders a (materialized) PxNode tree to react-native-svg elements.
|
|
63
58
|
* Mirrors the web `renderNode` contract: unsupported/dangerous tags are
|
|
64
59
|
* skipped with a warning, never a crash.
|
|
60
|
+
* @internal
|
|
65
61
|
*/
|
|
66
62
|
export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?: string | number): ReactElement | null {
|
|
67
63
|
if (!node) return null;
|
|
@@ -76,7 +72,7 @@ export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?:
|
|
|
76
72
|
const domType: string | undefined = props.domType;
|
|
77
73
|
if (domType !== undefined) delete props.domType;
|
|
78
74
|
|
|
79
|
-
if (
|
|
75
|
+
if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {
|
|
80
76
|
opts.warnings?.push('tag blocked (dangerous): ' + tag);
|
|
81
77
|
return null;
|
|
82
78
|
}
|
|
@@ -91,11 +87,10 @@ export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?:
|
|
|
91
87
|
const rnProps = toRnProps(props, opts.warnings, tag);
|
|
92
88
|
if (domType !== undefined) rnProps.type = domType;
|
|
93
89
|
|
|
94
|
-
// `node.style` —
|
|
95
|
-
//
|
|
96
|
-
// applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).
|
|
90
|
+
// `node.style` — an inline record of declarations. react-native-svg has no CSS, so
|
|
91
|
+
// they are applied as ordinary props (the same names, e.g. `fill`, `strokeWidth`).
|
|
97
92
|
// Explicit attributes on the node win over the style block.
|
|
98
|
-
const resolved =
|
|
93
|
+
const resolved = style;
|
|
99
94
|
if (resolved) {
|
|
100
95
|
for (const [k, v] of Object.entries(resolved)) {
|
|
101
96
|
const rnKey = toRnPropName(k);
|
|
@@ -107,7 +102,7 @@ export function renderRnNode(node: PxNode, opts: RenderRnNodeOptions = {}, key?:
|
|
|
107
102
|
}
|
|
108
103
|
|
|
109
104
|
// Text content: wire nodes carry it in `textContent` — the one key.
|
|
110
|
-
const textContent: string | undefined = props[
|
|
105
|
+
const textContent: string | undefined = props[PX_TEXT_CONTENT_ATTR];
|
|
111
106
|
|
|
112
107
|
let childElements: ReactNode = undefined;
|
|
113
108
|
if (Array.isArray(children) && children.length > 0) {
|
package/src/PxRnSafety.ts
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { type PxNode } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { deepClone, generateUniqueId } from '@pixodesk/svg-animator-core/internal';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Workarounds for defects in react-native-svg's NATIVE renderer that would
|
|
@@ -57,6 +58,7 @@ function forEachNode(node: PxNode | undefined, visit: (n: PxNode, parent?: PxNod
|
|
|
57
58
|
* has zero length and nothing changes visually at all.
|
|
58
59
|
*
|
|
59
60
|
* Returns the document unchanged — the same object — when nothing matches.
|
|
61
|
+
* @internal
|
|
60
62
|
*/
|
|
61
63
|
export function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode {
|
|
62
64
|
// Cheap pre-check: the overwhelming majority of documents have no textPath.
|
package/src/PxRnTracks.ts
CHANGED
|
@@ -3,15 +3,8 @@
|
|
|
3
3
|
* Licensed under the MIT License. See the LICENSE file in the project root for details.
|
|
4
4
|
*---------------------------------------------------------------------------------------*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
getAnimatorConfig,
|
|
9
|
-
getNormalizedBindings,
|
|
10
|
-
DEFAULT_DURATION_MS,
|
|
11
|
-
PxTimelineEngine,
|
|
12
|
-
type PxAnimatedSvgDocument,
|
|
13
|
-
type PxAnimationDefinition,
|
|
14
|
-
} from '@pixodesk/svg-animator-core';
|
|
6
|
+
import { calcAnimationValues, getAnimatorConfig, normalizeBindings, PxTimelineEngine, type PxAnimatedSvgDocument, type PxAnimationDefinition } from '@pixodesk/svg-animator-core';
|
|
7
|
+
import { PX_DEFAULT_DURATION_MS } from '@pixodesk/svg-animator-core/internal';
|
|
15
8
|
import { toRnPropName, toRnPropValue } from './PxRnPropNames';
|
|
16
9
|
|
|
17
10
|
/**
|
|
@@ -22,6 +15,7 @@ import { toRnPropName, toRnPropValue } from './PxRnPropNames';
|
|
|
22
15
|
* with — so RN playback is value-identical to the web player. Easing, loops,
|
|
23
16
|
* transform composition, color interpolation and path morphing are all baked
|
|
24
17
|
* into the samples at compile time; the UI-thread worklet only indexes arrays.
|
|
18
|
+
* @internal
|
|
25
19
|
*/
|
|
26
20
|
export interface PxElementTracks {
|
|
27
21
|
/** Element id (after id regeneration). */
|
|
@@ -30,6 +24,7 @@ export interface PxElementTracks {
|
|
|
30
24
|
props: Record<string, Array<string | number | Array<number>>>;
|
|
31
25
|
}
|
|
32
26
|
|
|
27
|
+
/** @internal */
|
|
33
28
|
export interface PxCompiledTracks {
|
|
34
29
|
/** Per-iteration duration, ms. */
|
|
35
30
|
duration: number;
|
|
@@ -51,6 +46,7 @@ export interface PxCompiledTracks {
|
|
|
51
46
|
elements: Array<PxElementTracks>;
|
|
52
47
|
}
|
|
53
48
|
|
|
49
|
+
/** @internal */
|
|
54
50
|
export interface CompileTracksOptions {
|
|
55
51
|
/** Target sample rate, samples/second. Default 60 (one per frame). */
|
|
56
52
|
sampleRate?: number;
|
|
@@ -72,11 +68,12 @@ export interface CompileTracksOptions {
|
|
|
72
68
|
/**
|
|
73
69
|
* Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`
|
|
74
70
|
* + `generateNewIds` first) into densely sampled per-element tracks.
|
|
71
|
+
* @internal
|
|
75
72
|
*/
|
|
76
73
|
export function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks {
|
|
77
74
|
const config = getAnimatorConfig(doc) || {};
|
|
78
75
|
|
|
79
|
-
const duration = +(config.duration ||
|
|
76
|
+
const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
|
|
80
77
|
const _iterations = config.iterations;
|
|
81
78
|
let iterations = 1;
|
|
82
79
|
if (typeof _iterations === 'number') iterations = _iterations || 1;
|
|
@@ -99,7 +96,7 @@ export function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOp
|
|
|
99
96
|
};
|
|
100
97
|
indexTags(doc);
|
|
101
98
|
|
|
102
|
-
const bindings =
|
|
99
|
+
const bindings = normalizeBindings(doc, PxTimelineEngine.js) || [];
|
|
103
100
|
|
|
104
101
|
const elements: Array<PxElementTracks> = [];
|
|
105
102
|
for (const binding of bindings) {
|
|
@@ -173,6 +170,7 @@ export const NATIVE_PROP_NAME: Record<string, string> = {
|
|
|
173
170
|
* reanimated animated-props path of a real device. Props that are applied by
|
|
174
171
|
* re-rendering through React (and therefore still pass through react-native-svg's
|
|
175
172
|
* JS layer), and every value on the web, must keep the wire name.
|
|
173
|
+
* @internal
|
|
176
174
|
*/
|
|
177
175
|
export function sampleProps(
|
|
178
176
|
tracks: PxElementTracks,
|
package/src/PxRnTypeMap.ts
CHANGED
|
@@ -63,6 +63,7 @@ import type { ComponentType } from 'react';
|
|
|
63
63
|
*
|
|
64
64
|
* Keys are the wire-format `node.type` values, which follow SVG's own casing
|
|
65
65
|
* (`clipPath`, `feGaussianBlur`, `linearGradient`, …).
|
|
66
|
+
* @internal
|
|
66
67
|
*/
|
|
67
68
|
export const RN_SVG_COMPONENTS: Record<string, ComponentType<any>> = {
|
|
68
69
|
// Root & containers
|
package/src/index.ts
CHANGED
|
@@ -6,12 +6,3 @@
|
|
|
6
6
|
export { PixodeskSvgAnimator, default } from './PixodeskSvgAnimator';
|
|
7
7
|
export type { PixodeskSvgAnimatorProps, RnAnimatorApi } from './PixodeskSvgAnimator';
|
|
8
8
|
|
|
9
|
-
export { renderRnNode, toRnProps } from './PxRnRender';
|
|
10
|
-
export { PxRnErrorBoundary, type PxRnErrorBoundaryProps } from './PxRnErrorBoundary';
|
|
11
|
-
export { openClosedTextPathTargets } from './PxRnSafety';
|
|
12
|
-
export type { RenderRnNodeOptions } from './PxRnRender';
|
|
13
|
-
|
|
14
|
-
export { compileTracks, sampleProps } from './PxRnTracks';
|
|
15
|
-
export type { CompileTracksOptions, PxCompiledTracks, PxElementTracks } from './PxRnTracks';
|
|
16
|
-
|
|
17
|
-
export { RN_SVG_COMPONENTS, toRnPropName } from './PxRnTypeMap';
|