@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/dist/index.d.cts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { PxPlaybackOverrideProps, PxControlProps,
|
|
2
|
-
import React, { ReactElement
|
|
1
|
+
import { PxPlaybackOverrideProps, PxControlProps, PxAnimatorCallbacks, PxAnimatedSvgDocument, PxTimelinePatch, PxAnimatorHandle } from '@pixodesk/svg-animator-core';
|
|
2
|
+
import React, { ReactElement } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's
|
|
6
6
|
* name (review §9). It no longer "mirrors" the React one by hand: the local copy had already
|
|
7
7
|
* drifted (its `setPlaybackRate` comment lost "negative plays backwards"). One definition.
|
|
8
|
+
* @public
|
|
8
9
|
*/
|
|
9
10
|
type RnAnimatorApi = PxAnimatorHandle;
|
|
10
11
|
/**
|
|
11
12
|
* The component's props. The playback override, the control props and the callbacks are core's
|
|
12
13
|
* shared shapes (review §9) — `PxPlaybackOverrideProps`, `PxControlProps` and
|
|
13
|
-
* `
|
|
14
|
-
* on this platform is declared here: `
|
|
15
|
-
*
|
|
14
|
+
* `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs
|
|
15
|
+
* on this platform is declared here: `fallback`, which has no web counterpart.
|
|
16
|
+
* @public
|
|
16
17
|
*/
|
|
17
|
-
interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlProps,
|
|
18
|
+
interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlProps, PxAnimatorCallbacks {
|
|
18
19
|
/** The animation document to render. */
|
|
19
20
|
doc: PxAnimatedSvgDocument;
|
|
20
21
|
/**
|
|
@@ -30,17 +31,6 @@ interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlPro
|
|
|
30
31
|
* (review §1): `autoplay` next to it still autoplays.
|
|
31
32
|
*/
|
|
32
33
|
apiRef?: React.RefObject<RnAnimatorApi | null>;
|
|
33
|
-
/**
|
|
34
|
-
* Called when a document cannot be compiled or rendered. The component
|
|
35
|
-
* renders {@link fallback} instead of throwing, so a single broken
|
|
36
|
-
* animation never takes down the screen around it.
|
|
37
|
-
*
|
|
38
|
-
* Only JavaScript failures reach this — a crash inside react-native-svg's
|
|
39
|
-
* native renderer bypasses JavaScript entirely. Richer than the web's
|
|
40
|
-
* `onError(diagnostic)` because the error boundary hands it a component stack; it is
|
|
41
|
-
* adapted into the shared diagnostics channel rather than narrowed to match it.
|
|
42
|
-
*/
|
|
43
|
-
onError?: (error: Error, componentStack?: string) => void;
|
|
44
34
|
/** Rendered in place of the animation after a failure. Default: nothing. */
|
|
45
35
|
fallback?: (error: Error) => ReactElement | null;
|
|
46
36
|
}
|
|
@@ -54,179 +44,8 @@ interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlPro
|
|
|
54
44
|
* played back natively: a single reanimated progress value driven by
|
|
55
45
|
* `withTiming`/`withRepeat` on the UI thread, with per-element worklets
|
|
56
46
|
* indexing the precompiled tracks. No JS-thread frame loop.
|
|
47
|
+
* @public
|
|
57
48
|
*/
|
|
58
|
-
declare function PixodeskSvgAnimator({ doc, timeline, resetTimeline, duration, delay, iterations, startOn, autoplay, play, pause, apiRef, progress: progressProp, time, onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn,
|
|
59
|
-
|
|
60
|
-
interface RenderRnNodeOptions {
|
|
61
|
-
/** Collects non-fatal issues (unsupported tags, dropped attrs). */
|
|
62
|
-
warnings?: Array<string>;
|
|
63
|
-
/** `definitions` from the document, used to resolve named `style` presets. */
|
|
64
|
-
defs?: PxDefs;
|
|
65
|
-
/**
|
|
66
|
-
* Wraps the created element for animated nodes: receives the resolved
|
|
67
|
-
* component + static props and returns the element to mount (the animator
|
|
68
|
-
* substitutes an Animated component wired to its tracks). Return undefined
|
|
69
|
-
* to keep the plain static element.
|
|
70
|
-
*
|
|
71
|
-
* `key` is handed over SEPARATELY and is deliberately absent from `props`:
|
|
72
|
-
* React 19 warns when a props object containing `key` is spread into JSX,
|
|
73
|
-
* and implementations of this hook do exactly that.
|
|
74
|
-
*/
|
|
75
|
-
decorate?: (node: PxNode, Component: ComponentType<any>, props: Record<string, any>, children: ReactNode, key: string | number | undefined) => ReactElement | undefined;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Converts core-normalized wire props into react-native-svg props: RN prop
|
|
79
|
-
* naming, sanitization (same security rules as the web renderer), numeric
|
|
80
|
-
* coercion where possible.
|
|
81
|
-
*/
|
|
82
|
-
declare function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any>;
|
|
83
|
-
/**
|
|
84
|
-
* Renders a (materialized) PxNode tree to react-native-svg elements.
|
|
85
|
-
* Mirrors the web `renderNode` contract: unsupported/dangerous tags are
|
|
86
|
-
* skipped with a warning, never a crash.
|
|
87
|
-
*/
|
|
88
|
-
declare function renderRnNode(node: PxNode, opts?: RenderRnNodeOptions, key?: string | number): ReactElement | null;
|
|
89
|
-
|
|
90
|
-
interface PxRnErrorBoundaryProps {
|
|
91
|
-
children: ReactNode;
|
|
92
|
-
/** Rendered instead of the children once something has thrown. */
|
|
93
|
-
fallback?: (error: Error) => ReactNode;
|
|
94
|
-
onError?: (error: Error, info?: string) => void;
|
|
95
|
-
/** Where to report the failure (API review §5). Defaults to the console. */
|
|
96
|
-
diag?: PxDiagnostics;
|
|
97
|
-
}
|
|
98
|
-
interface State {
|
|
99
|
-
error: Error | null;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Keeps one bad animation from taking down the screen around it.
|
|
103
|
-
*
|
|
104
|
-
* A throw anywhere in the rendered SVG tree — an unsupported prop shape, a
|
|
105
|
-
* react-native-svg internal, a reanimated attachment failure — otherwise
|
|
106
|
-
* unmounts the whole React tree above it. Here it is contained to this one
|
|
107
|
-
* animation, reported through `onError`, and replaced by `fallback`.
|
|
108
|
-
*
|
|
109
|
-
* NOTE the limit: this catches JavaScript errors only. A crash INSIDE the
|
|
110
|
-
* native renderer (see `openClosedTextPathTargets` for a real example) never
|
|
111
|
-
* reaches JavaScript and cannot be caught here — those have to be avoided
|
|
112
|
-
* rather than handled.
|
|
113
|
-
*/
|
|
114
|
-
declare class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {
|
|
115
|
-
state: State;
|
|
116
|
-
static getDerivedStateFromError(error: Error): State;
|
|
117
|
-
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
118
|
-
componentDidUpdate(prev: PxRnErrorBoundaryProps): void;
|
|
119
|
-
render(): ReactNode;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.
|
|
124
|
-
*
|
|
125
|
-
* WHY: react-native-svg's native text-on-path layout crashes the app —
|
|
126
|
-
* an uncatchable `NSRangeException` on iOS — for this combination.
|
|
127
|
-
* `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,
|
|
128
|
-
* but for a closed path it sets those bounds to `startOffset … startOffset +
|
|
129
|
-
* pathLength` instead of `0 … pathLength`. Any glyph past the end of the path
|
|
130
|
-
* therefore survives the bounds check and reaches `getPosAndTan`, whose
|
|
131
|
-
* `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths
|
|
132
|
-
* array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is
|
|
133
|
-
* all it takes, and animating `startOffset` guarantees hitting it.
|
|
134
|
-
*
|
|
135
|
-
* Opening the path restores the `0 … pathLength` bounds, so out-of-range
|
|
136
|
-
* glyphs are skipped as intended. The copy is private to the `<textPath>`, so
|
|
137
|
-
* anything else drawing the same path still gets the closed original. For a
|
|
138
|
-
* shape whose ends already meet (a circle, the usual case) the removed segment
|
|
139
|
-
* has zero length and nothing changes visually at all.
|
|
140
|
-
*
|
|
141
|
-
* Returns the document unchanged — the same object — when nothing matches.
|
|
142
|
-
*/
|
|
143
|
-
declare function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Sampled animation tracks for ONE element: prop name → per-sample values.
|
|
147
|
-
*
|
|
148
|
-
* The compiler densely samples every animated property through core's
|
|
149
|
-
* `calcAnimationValues` — the exact function the web frames engine renders
|
|
150
|
-
* with — so RN playback is value-identical to the web player. Easing, loops,
|
|
151
|
-
* transform composition, color interpolation and path morphing are all baked
|
|
152
|
-
* into the samples at compile time; the UI-thread worklet only indexes arrays.
|
|
153
|
-
*/
|
|
154
|
-
interface PxElementTracks {
|
|
155
|
-
/** Element id (after id regeneration). */
|
|
156
|
-
id: string;
|
|
157
|
-
/** react-native-svg prop name → one value per sample. */
|
|
158
|
-
props: Record<string, Array<string | number | Array<number>>>;
|
|
159
|
-
}
|
|
160
|
-
interface PxCompiledTracks {
|
|
161
|
-
/** Per-iteration duration, ms. */
|
|
162
|
-
duration: number;
|
|
163
|
-
/** Iteration count (Infinity for 'infinite'). */
|
|
164
|
-
iterations: number;
|
|
165
|
-
/** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */
|
|
166
|
-
direction: string;
|
|
167
|
-
/** Delay before start, ms (positive = wait). */
|
|
168
|
-
delay: number;
|
|
169
|
-
/** WAAPI-style fill mode (default 'forwards'). */
|
|
170
|
-
fill: string;
|
|
171
|
-
/** When true, snap back to the start after a natural finish. */
|
|
172
|
-
resetOnFinish: boolean;
|
|
173
|
-
/** Sample step, ms. */
|
|
174
|
-
stepMs: number;
|
|
175
|
-
/** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */
|
|
176
|
-
sampleCount: number;
|
|
177
|
-
/** Tracks for every animated element. */
|
|
178
|
-
elements: Array<PxElementTracks>;
|
|
179
|
-
}
|
|
180
|
-
interface CompileTracksOptions {
|
|
181
|
-
/** Target sample rate, samples/second. Default 60 (one per frame). */
|
|
182
|
-
sampleRate?: number;
|
|
183
|
-
/** Hard cap on samples per iteration (memory guard). Default 600. */
|
|
184
|
-
maxSamples?: number;
|
|
185
|
-
/**
|
|
186
|
-
* Sample values in the form the NATIVE react-native-svg views expect
|
|
187
|
-
* (currently: `transform` as a 6-number matrix rather than an SVG string).
|
|
188
|
-
*
|
|
189
|
-
* Defaults to `false` — the plain SVG form, which is what react-native-web
|
|
190
|
-
* hands straight to the DOM. Only the component knows the platform, so it
|
|
191
|
-
* decides; every consumer that does not opt in keeps DOM-compatible values.
|
|
192
|
-
*/
|
|
193
|
-
native?: boolean;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`
|
|
197
|
-
* + `generateNewIds` first) into densely sampled per-element tracks.
|
|
198
|
-
*/
|
|
199
|
-
declare function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks;
|
|
200
|
-
/**
|
|
201
|
-
* Worklet-safe sample lookup: returns the per-prop values at time `tMs`
|
|
202
|
-
* (already mapped into a single iteration by the caller). Kept deliberately
|
|
203
|
-
* trivial — runs on the UI thread every frame.
|
|
204
|
-
*
|
|
205
|
-
* `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the
|
|
206
|
-
* reanimated animated-props path of a real device. Props that are applied by
|
|
207
|
-
* re-rendering through React (and therefore still pass through react-native-svg's
|
|
208
|
-
* JS layer), and every value on the web, must keep the wire name.
|
|
209
|
-
*/
|
|
210
|
-
declare function sampleProps(tracks: PxElementTracks, tMs: number, stepMs: number, sampleCount: number, native?: boolean): Record<string, string | number | Array<number>>;
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Converts one normalized wire attribute name (camelCase after core's
|
|
214
|
-
* `getNormalizedProps`, or kebab-case raw) to a react-native-svg prop name.
|
|
215
|
-
* Returns undefined for props that must be dropped.
|
|
216
|
-
*
|
|
217
|
-
* Pure (no react-native-svg import) so the track compiler and its tests
|
|
218
|
-
* don't need a React Native environment.
|
|
219
|
-
*/
|
|
220
|
-
declare function toRnPropName(attrName: string): string | undefined;
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* SVG tag → react-native-svg component. Tags not in this map are skipped at
|
|
224
|
-
* render time (with a warning collected by the renderer) — they go on the
|
|
225
|
-
* feature-gap list rather than crashing the tree.
|
|
226
|
-
*
|
|
227
|
-
* Keys are the wire-format `node.type` values, which follow SVG's own casing
|
|
228
|
-
* (`clipPath`, `feGaussianBlur`, `linearGradient`, …).
|
|
229
|
-
*/
|
|
230
|
-
declare const RN_SVG_COMPONENTS: Record<string, ComponentType<any>>;
|
|
49
|
+
declare function PixodeskSvgAnimator({ doc, timeline, resetTimeline, duration, delay, iterations, startOn, autoplay, play, pause, apiRef, progress: progressProp, time, onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError, }: PixodeskSvgAnimatorProps): ReactElement | null;
|
|
231
50
|
|
|
232
|
-
export {
|
|
51
|
+
export { PixodeskSvgAnimator, type PixodeskSvgAnimatorProps, type RnAnimatorApi, PixodeskSvgAnimator as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
-
import { PxPlaybackOverrideProps, PxControlProps,
|
|
2
|
-
import React, { ReactElement
|
|
1
|
+
import { PxPlaybackOverrideProps, PxControlProps, PxAnimatorCallbacks, PxAnimatedSvgDocument, PxTimelinePatch, PxAnimatorHandle } from '@pixodesk/svg-animator-core';
|
|
2
|
+
import React, { ReactElement } from 'react';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* The imperative handle `apiRef` is filled with — core's `PxAnimatorHandle` under this package's
|
|
6
6
|
* name (review §9). It no longer "mirrors" the React one by hand: the local copy had already
|
|
7
7
|
* drifted (its `setPlaybackRate` comment lost "negative plays backwards"). One definition.
|
|
8
|
+
* @public
|
|
8
9
|
*/
|
|
9
10
|
type RnAnimatorApi = PxAnimatorHandle;
|
|
10
11
|
/**
|
|
11
12
|
* The component's props. The playback override, the control props and the callbacks are core's
|
|
12
13
|
* shared shapes (review §9) — `PxPlaybackOverrideProps`, `PxControlProps` and
|
|
13
|
-
* `
|
|
14
|
-
* on this platform is declared here: `
|
|
15
|
-
*
|
|
14
|
+
* `PxAnimatorCallbacks` — so React, Vue and React Native cannot drift apart. Only what differs
|
|
15
|
+
* on this platform is declared here: `fallback`, which has no web counterpart.
|
|
16
|
+
* @public
|
|
16
17
|
*/
|
|
17
|
-
interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlProps,
|
|
18
|
+
interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlProps, PxAnimatorCallbacks {
|
|
18
19
|
/** The animation document to render. */
|
|
19
20
|
doc: PxAnimatedSvgDocument;
|
|
20
21
|
/**
|
|
@@ -30,17 +31,6 @@ interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlPro
|
|
|
30
31
|
* (review §1): `autoplay` next to it still autoplays.
|
|
31
32
|
*/
|
|
32
33
|
apiRef?: React.RefObject<RnAnimatorApi | null>;
|
|
33
|
-
/**
|
|
34
|
-
* Called when a document cannot be compiled or rendered. The component
|
|
35
|
-
* renders {@link fallback} instead of throwing, so a single broken
|
|
36
|
-
* animation never takes down the screen around it.
|
|
37
|
-
*
|
|
38
|
-
* Only JavaScript failures reach this — a crash inside react-native-svg's
|
|
39
|
-
* native renderer bypasses JavaScript entirely. Richer than the web's
|
|
40
|
-
* `onError(diagnostic)` because the error boundary hands it a component stack; it is
|
|
41
|
-
* adapted into the shared diagnostics channel rather than narrowed to match it.
|
|
42
|
-
*/
|
|
43
|
-
onError?: (error: Error, componentStack?: string) => void;
|
|
44
34
|
/** Rendered in place of the animation after a failure. Default: nothing. */
|
|
45
35
|
fallback?: (error: Error) => ReactElement | null;
|
|
46
36
|
}
|
|
@@ -54,179 +44,8 @@ interface PixodeskSvgAnimatorProps extends PxPlaybackOverrideProps, PxControlPro
|
|
|
54
44
|
* played back natively: a single reanimated progress value driven by
|
|
55
45
|
* `withTiming`/`withRepeat` on the UI thread, with per-element worklets
|
|
56
46
|
* indexing the precompiled tracks. No JS-thread frame loop.
|
|
47
|
+
* @public
|
|
57
48
|
*/
|
|
58
|
-
declare function PixodeskSvgAnimator({ doc, timeline, resetTimeline, duration, delay, iterations, startOn, autoplay, play, pause, apiRef, progress: progressProp, time, onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn,
|
|
59
|
-
|
|
60
|
-
interface RenderRnNodeOptions {
|
|
61
|
-
/** Collects non-fatal issues (unsupported tags, dropped attrs). */
|
|
62
|
-
warnings?: Array<string>;
|
|
63
|
-
/** `definitions` from the document, used to resolve named `style` presets. */
|
|
64
|
-
defs?: PxDefs;
|
|
65
|
-
/**
|
|
66
|
-
* Wraps the created element for animated nodes: receives the resolved
|
|
67
|
-
* component + static props and returns the element to mount (the animator
|
|
68
|
-
* substitutes an Animated component wired to its tracks). Return undefined
|
|
69
|
-
* to keep the plain static element.
|
|
70
|
-
*
|
|
71
|
-
* `key` is handed over SEPARATELY and is deliberately absent from `props`:
|
|
72
|
-
* React 19 warns when a props object containing `key` is spread into JSX,
|
|
73
|
-
* and implementations of this hook do exactly that.
|
|
74
|
-
*/
|
|
75
|
-
decorate?: (node: PxNode, Component: ComponentType<any>, props: Record<string, any>, children: ReactNode, key: string | number | undefined) => ReactElement | undefined;
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Converts core-normalized wire props into react-native-svg props: RN prop
|
|
79
|
-
* naming, sanitization (same security rules as the web renderer), numeric
|
|
80
|
-
* coercion where possible.
|
|
81
|
-
*/
|
|
82
|
-
declare function toRnProps(props: Record<string, any>, warnings?: Array<string>, tag?: string): Record<string, any>;
|
|
83
|
-
/**
|
|
84
|
-
* Renders a (materialized) PxNode tree to react-native-svg elements.
|
|
85
|
-
* Mirrors the web `renderNode` contract: unsupported/dangerous tags are
|
|
86
|
-
* skipped with a warning, never a crash.
|
|
87
|
-
*/
|
|
88
|
-
declare function renderRnNode(node: PxNode, opts?: RenderRnNodeOptions, key?: string | number): ReactElement | null;
|
|
89
|
-
|
|
90
|
-
interface PxRnErrorBoundaryProps {
|
|
91
|
-
children: ReactNode;
|
|
92
|
-
/** Rendered instead of the children once something has thrown. */
|
|
93
|
-
fallback?: (error: Error) => ReactNode;
|
|
94
|
-
onError?: (error: Error, info?: string) => void;
|
|
95
|
-
/** Where to report the failure (API review §5). Defaults to the console. */
|
|
96
|
-
diag?: PxDiagnostics;
|
|
97
|
-
}
|
|
98
|
-
interface State {
|
|
99
|
-
error: Error | null;
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Keeps one bad animation from taking down the screen around it.
|
|
103
|
-
*
|
|
104
|
-
* A throw anywhere in the rendered SVG tree — an unsupported prop shape, a
|
|
105
|
-
* react-native-svg internal, a reanimated attachment failure — otherwise
|
|
106
|
-
* unmounts the whole React tree above it. Here it is contained to this one
|
|
107
|
-
* animation, reported through `onError`, and replaced by `fallback`.
|
|
108
|
-
*
|
|
109
|
-
* NOTE the limit: this catches JavaScript errors only. A crash INSIDE the
|
|
110
|
-
* native renderer (see `openClosedTextPathTargets` for a real example) never
|
|
111
|
-
* reaches JavaScript and cannot be caught here — those have to be avoided
|
|
112
|
-
* rather than handled.
|
|
113
|
-
*/
|
|
114
|
-
declare class PxRnErrorBoundary extends Component<PxRnErrorBoundaryProps, State> {
|
|
115
|
-
state: State;
|
|
116
|
-
static getDerivedStateFromError(error: Error): State;
|
|
117
|
-
componentDidCatch(error: Error, info: ErrorInfo): void;
|
|
118
|
-
componentDidUpdate(prev: PxRnErrorBoundaryProps): void;
|
|
119
|
-
render(): ReactNode;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Gives every `<textPath>` that follows a CLOSED path its own OPEN copy of it.
|
|
124
|
-
*
|
|
125
|
-
* WHY: react-native-svg's native text-on-path layout crashes the app —
|
|
126
|
-
* an uncatchable `NSRangeException` on iOS — for this combination.
|
|
127
|
-
* `RNSVGTSpan.mm` skips glyphs outside `[startOfRendering, endOfRendering]`,
|
|
128
|
-
* but for a closed path it sets those bounds to `startOffset … startOffset +
|
|
129
|
-
* pathLength` instead of `0 … pathLength`. Any glyph past the end of the path
|
|
130
|
-
* therefore survives the bounds check and reaches `getPosAndTan`, whose
|
|
131
|
-
* `indexOfObjectPassingTest` returns `NSNotFound` — and indexing the lengths
|
|
132
|
-
* array with `NSNotFound` throws. A non-zero `startOffset` on a closed path is
|
|
133
|
-
* all it takes, and animating `startOffset` guarantees hitting it.
|
|
134
|
-
*
|
|
135
|
-
* Opening the path restores the `0 … pathLength` bounds, so out-of-range
|
|
136
|
-
* glyphs are skipped as intended. The copy is private to the `<textPath>`, so
|
|
137
|
-
* anything else drawing the same path still gets the closed original. For a
|
|
138
|
-
* shape whose ends already meet (a circle, the usual case) the removed segment
|
|
139
|
-
* has zero length and nothing changes visually at all.
|
|
140
|
-
*
|
|
141
|
-
* Returns the document unchanged — the same object — when nothing matches.
|
|
142
|
-
*/
|
|
143
|
-
declare function openClosedTextPathTargets(doc: PxNode, warnings?: Array<string>): PxNode;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Sampled animation tracks for ONE element: prop name → per-sample values.
|
|
147
|
-
*
|
|
148
|
-
* The compiler densely samples every animated property through core's
|
|
149
|
-
* `calcAnimationValues` — the exact function the web frames engine renders
|
|
150
|
-
* with — so RN playback is value-identical to the web player. Easing, loops,
|
|
151
|
-
* transform composition, color interpolation and path morphing are all baked
|
|
152
|
-
* into the samples at compile time; the UI-thread worklet only indexes arrays.
|
|
153
|
-
*/
|
|
154
|
-
interface PxElementTracks {
|
|
155
|
-
/** Element id (after id regeneration). */
|
|
156
|
-
id: string;
|
|
157
|
-
/** react-native-svg prop name → one value per sample. */
|
|
158
|
-
props: Record<string, Array<string | number | Array<number>>>;
|
|
159
|
-
}
|
|
160
|
-
interface PxCompiledTracks {
|
|
161
|
-
/** Per-iteration duration, ms. */
|
|
162
|
-
duration: number;
|
|
163
|
-
/** Iteration count (Infinity for 'infinite'). */
|
|
164
|
-
iterations: number;
|
|
165
|
-
/** 'normal' | 'reverse' | 'alternate' | 'alternate-reverse' */
|
|
166
|
-
direction: string;
|
|
167
|
-
/** Delay before start, ms (positive = wait). */
|
|
168
|
-
delay: number;
|
|
169
|
-
/** WAAPI-style fill mode (default 'forwards'). */
|
|
170
|
-
fill: string;
|
|
171
|
-
/** When true, snap back to the start after a natural finish. */
|
|
172
|
-
resetOnFinish: boolean;
|
|
173
|
-
/** Sample step, ms. */
|
|
174
|
-
stepMs: number;
|
|
175
|
-
/** Number of samples per iteration (>= 2; sample i is at time i*stepMs). */
|
|
176
|
-
sampleCount: number;
|
|
177
|
-
/** Tracks for every animated element. */
|
|
178
|
-
elements: Array<PxElementTracks>;
|
|
179
|
-
}
|
|
180
|
-
interface CompileTracksOptions {
|
|
181
|
-
/** Target sample rate, samples/second. Default 60 (one per frame). */
|
|
182
|
-
sampleRate?: number;
|
|
183
|
-
/** Hard cap on samples per iteration (memory guard). Default 600. */
|
|
184
|
-
maxSamples?: number;
|
|
185
|
-
/**
|
|
186
|
-
* Sample values in the form the NATIVE react-native-svg views expect
|
|
187
|
-
* (currently: `transform` as a 6-number matrix rather than an SVG string).
|
|
188
|
-
*
|
|
189
|
-
* Defaults to `false` — the plain SVG form, which is what react-native-web
|
|
190
|
-
* hands straight to the DOM. Only the component knows the platform, so it
|
|
191
|
-
* decides; every consumer that does not opt in keeps DOM-compatible values.
|
|
192
|
-
*/
|
|
193
|
-
native?: boolean;
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Compiles a MATERIALIZED document (run `materializeAllInTree(doc, 'frames')`
|
|
197
|
-
* + `generateNewIds` first) into densely sampled per-element tracks.
|
|
198
|
-
*/
|
|
199
|
-
declare function compileTracks(doc: PxAnimatedSvgDocument, opts?: CompileTracksOptions): PxCompiledTracks;
|
|
200
|
-
/**
|
|
201
|
-
* Worklet-safe sample lookup: returns the per-prop values at time `tMs`
|
|
202
|
-
* (already mapped into a single iteration by the caller). Kept deliberately
|
|
203
|
-
* trivial — runs on the UI thread every frame.
|
|
204
|
-
*
|
|
205
|
-
* `native = true` applies {@link NATIVE_PROP_NAME} — pass it only on the
|
|
206
|
-
* reanimated animated-props path of a real device. Props that are applied by
|
|
207
|
-
* re-rendering through React (and therefore still pass through react-native-svg's
|
|
208
|
-
* JS layer), and every value on the web, must keep the wire name.
|
|
209
|
-
*/
|
|
210
|
-
declare function sampleProps(tracks: PxElementTracks, tMs: number, stepMs: number, sampleCount: number, native?: boolean): Record<string, string | number | Array<number>>;
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Converts one normalized wire attribute name (camelCase after core's
|
|
214
|
-
* `getNormalizedProps`, or kebab-case raw) to a react-native-svg prop name.
|
|
215
|
-
* Returns undefined for props that must be dropped.
|
|
216
|
-
*
|
|
217
|
-
* Pure (no react-native-svg import) so the track compiler and its tests
|
|
218
|
-
* don't need a React Native environment.
|
|
219
|
-
*/
|
|
220
|
-
declare function toRnPropName(attrName: string): string | undefined;
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* SVG tag → react-native-svg component. Tags not in this map are skipped at
|
|
224
|
-
* render time (with a warning collected by the renderer) — they go on the
|
|
225
|
-
* feature-gap list rather than crashing the tree.
|
|
226
|
-
*
|
|
227
|
-
* Keys are the wire-format `node.type` values, which follow SVG's own casing
|
|
228
|
-
* (`clipPath`, `feGaussianBlur`, `linearGradient`, …).
|
|
229
|
-
*/
|
|
230
|
-
declare const RN_SVG_COMPONENTS: Record<string, ComponentType<any>>;
|
|
49
|
+
declare function PixodeskSvgAnimator({ doc, timeline, resetTimeline, duration, delay, iterations, startOn, autoplay, play, pause, apiRef, progress: progressProp, time, onPlay, onStop, onPause, onCancel, onFinish, onRemove, onError, fallback, onWarn, muteWarn, muteError, }: PixodeskSvgAnimatorProps): ReactElement | null;
|
|
231
50
|
|
|
232
|
-
export {
|
|
51
|
+
export { PixodeskSvgAnimator, type PixodeskSvgAnimatorProps, type RnAnimatorApi, PixodeskSvgAnimator as default };
|
package/dist/index.js
CHANGED
|
@@ -31,30 +31,8 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// src/PixodeskSvgAnimator.tsx
|
|
34
|
-
import {
|
|
35
|
-
|
|
36
|
-
createDiagnostics as createDiagnostics2,
|
|
37
|
-
createRunClock,
|
|
38
|
-
isValidPlaybackRate,
|
|
39
|
-
progressSpanMs,
|
|
40
|
-
progressToTimeMs,
|
|
41
|
-
PX_RATE_REJECTED,
|
|
42
|
-
PxDiagnosticKind as PxDiagnosticKind2,
|
|
43
|
-
seekCeilingMs,
|
|
44
|
-
timeToProgress,
|
|
45
|
-
reportDocumentDiagnostics,
|
|
46
|
-
generateNewIds,
|
|
47
|
-
getAnimatorConfig as getAnimatorConfig2,
|
|
48
|
-
getDefs,
|
|
49
|
-
materializeAllInTree,
|
|
50
|
-
resolveTrigger,
|
|
51
|
-
validateNodeEffects,
|
|
52
|
-
PxTimelineEngine as PxTimelineEngine2,
|
|
53
|
-
PxControlMode,
|
|
54
|
-
resolveControlMode,
|
|
55
|
-
applyAnimatorConfig,
|
|
56
|
-
foldTimelineOverride
|
|
57
|
-
} from "@pixodesk/svg-animator-core";
|
|
34
|
+
import { clampSeekMs, createRunClock, isValidPlaybackRate, progressSpanMs, progressToTimeMs, PX_RATE_REJECTED, PxDiagnosticKind as PxDiagnosticKind2, seekCeilingMs, timeToProgress, generateNewIds, getAnimatorConfig as getAnimatorConfig2, getDefs, materializeAllInTree, resolveTrigger, validateNodeEffects, PxTimelineEngine as PxTimelineEngine2, PxControlMode, resolveControlMode, applyAnimatorConfig, foldTimelineOverride } from "@pixodesk/svg-animator-core";
|
|
35
|
+
import { createDiagnostics as createDiagnostics2, reportDocumentDiagnostics } from "@pixodesk/svg-animator-core/internal";
|
|
58
36
|
import { createElement as createElement2, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
59
37
|
import { Dimensions, Platform, Pressable, View } from "react-native";
|
|
60
38
|
import Animated, {
|
|
@@ -70,16 +48,11 @@ import Animated, {
|
|
|
70
48
|
} from "react-native-reanimated";
|
|
71
49
|
|
|
72
50
|
// src/PxRnTracks.ts
|
|
73
|
-
import {
|
|
74
|
-
|
|
75
|
-
getAnimatorConfig,
|
|
76
|
-
getNormalizedBindings,
|
|
77
|
-
DEFAULT_DURATION_MS,
|
|
78
|
-
PxTimelineEngine
|
|
79
|
-
} from "@pixodesk/svg-animator-core";
|
|
51
|
+
import { calcAnimationValues, getAnimatorConfig, getNormalizedBindings, PxTimelineEngine } from "@pixodesk/svg-animator-core";
|
|
52
|
+
import { DEFAULT_DURATION_MS } from "@pixodesk/svg-animator-core/internal";
|
|
80
53
|
|
|
81
54
|
// src/PxRnPropNames.ts
|
|
82
|
-
import { kebabToCamelCaseWord } from "@pixodesk/svg-animator-core";
|
|
55
|
+
import { kebabToCamelCaseWord } from "@pixodesk/svg-animator-core/internal";
|
|
83
56
|
|
|
84
57
|
// src/PxRnMatrix.ts
|
|
85
58
|
var DEG = Math.PI / 180;
|
|
@@ -256,13 +229,8 @@ function sampleProps(tracks, tMs, stepMs, sampleCount, native = false) {
|
|
|
256
229
|
}
|
|
257
230
|
|
|
258
231
|
// src/PxRnRender.tsx
|
|
259
|
-
import {
|
|
260
|
-
|
|
261
|
-
resolveStyle,
|
|
262
|
-
sanitizeAttributeValue,
|
|
263
|
-
DISALLOWED_SVG_TAGS_LOWER,
|
|
264
|
-
TEXT_CONTENT_ATTR
|
|
265
|
-
} from "@pixodesk/svg-animator-core";
|
|
232
|
+
import { getNormalizedProps } from "@pixodesk/svg-animator-core";
|
|
233
|
+
import { sanitizeAttributeValue, DISALLOWED_SVG_TAGS_LOWER, TEXT_CONTENT_ATTR } from "@pixodesk/svg-animator-core/internal";
|
|
266
234
|
import { createElement } from "react";
|
|
267
235
|
|
|
268
236
|
// src/PxRnTypeMap.ts
|
|
@@ -408,7 +376,7 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
408
376
|
}
|
|
409
377
|
const rnProps = toRnProps(props, opts.warnings, tag);
|
|
410
378
|
if (domType !== void 0) rnProps.type = domType;
|
|
411
|
-
const resolved =
|
|
379
|
+
const resolved = style;
|
|
412
380
|
if (resolved) {
|
|
413
381
|
for (const [k, v] of Object.entries(resolved)) {
|
|
414
382
|
const rnKey = toRnPropName(k);
|
|
@@ -444,7 +412,8 @@ function renderRnNode(node, opts = {}, key) {
|
|
|
444
412
|
|
|
445
413
|
// src/PxRnErrorBoundary.tsx
|
|
446
414
|
import { Component } from "react";
|
|
447
|
-
import {
|
|
415
|
+
import { PxDiagnosticKind } from "@pixodesk/svg-animator-core";
|
|
416
|
+
import { createDiagnostics } from "@pixodesk/svg-animator-core/internal";
|
|
448
417
|
var PxRnErrorBoundary = class extends Component {
|
|
449
418
|
constructor() {
|
|
450
419
|
super(...arguments);
|
|
@@ -454,9 +423,8 @@ var PxRnErrorBoundary = class extends Component {
|
|
|
454
423
|
return { error };
|
|
455
424
|
}
|
|
456
425
|
componentDidCatch(error, info) {
|
|
457
|
-
var _a, _b
|
|
458
|
-
(
|
|
459
|
-
((_d = this.props.diag) != null ? _d : createDiagnostics(void 0, "[PixodeskSvgAnimator]")).warn(PxDiagnosticKind.internal, "render failed: " + ((_e = error == null ? void 0 : error.message) != null ? _e : String(error)));
|
|
426
|
+
var _a, _b;
|
|
427
|
+
((_a = this.props.diag) != null ? _a : createDiagnostics(void 0, "[PixodeskSvgAnimator]")).error(PxDiagnosticKind.internal, error, { componentStack: (_b = info == null ? void 0 : info.componentStack) != null ? _b : void 0 });
|
|
460
428
|
}
|
|
461
429
|
componentDidUpdate(prev) {
|
|
462
430
|
if (this.state.error && prev.children !== this.props.children) {
|
|
@@ -471,7 +439,7 @@ var PxRnErrorBoundary = class extends Component {
|
|
|
471
439
|
};
|
|
472
440
|
|
|
473
441
|
// src/PxRnSafety.ts
|
|
474
|
-
import { deepClone, generateUniqueId } from "@pixodesk/svg-animator-core";
|
|
442
|
+
import { deepClone, generateUniqueId } from "@pixodesk/svg-animator-core/internal";
|
|
475
443
|
function isClosedPath(d) {
|
|
476
444
|
return typeof d === "string" && /[zZ]/.test(d);
|
|
477
445
|
}
|
|
@@ -658,21 +626,15 @@ function PixodeskSvgAnimator({
|
|
|
658
626
|
onError,
|
|
659
627
|
fallback,
|
|
660
628
|
onWarn,
|
|
661
|
-
|
|
629
|
+
muteWarn,
|
|
630
|
+
muteError
|
|
662
631
|
}) {
|
|
663
632
|
var _a, _b;
|
|
664
633
|
const timelineKey = typeof timeline === "string" ? timeline : JSON.stringify(timeline != null ? timeline : null);
|
|
665
|
-
const makeDiag = () => createDiagnostics2(
|
|
666
|
-
onWarn,
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
// keeps "not given" as undefined, so the console fallback still fires.
|
|
670
|
-
onError: onError ? (d) => {
|
|
671
|
-
var _a2;
|
|
672
|
-
return onError((_a2 = d.error) != null ? _a2 : new Error(d.message));
|
|
673
|
-
} : void 0,
|
|
674
|
-
silent
|
|
675
|
-
}, "[PixodeskSvgAnimator]");
|
|
634
|
+
const makeDiag = () => createDiagnostics2(
|
|
635
|
+
{ onWarn, onError, muteWarn, muteError },
|
|
636
|
+
"[PixodeskSvgAnimator]"
|
|
637
|
+
);
|
|
676
638
|
const compiled = useMemo(() => {
|
|
677
639
|
try {
|
|
678
640
|
return compileDocument(
|
|
@@ -682,7 +644,7 @@ function PixodeskSvgAnimator({
|
|
|
682
644
|
);
|
|
683
645
|
} catch (e) {
|
|
684
646
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
685
|
-
makeDiag().
|
|
647
|
+
makeDiag().error(PxDiagnosticKind2.internal, error, { phase: "compile" });
|
|
686
648
|
return { doc: null, tracks: EMPTY_TRACKS, error };
|
|
687
649
|
}
|
|
688
650
|
}, [doc, timelineKey, resetTimeline, duration, delay, iterations, startOn]);
|
|
@@ -918,7 +880,7 @@ function PixodeskSvgAnimator({
|
|
|
918
880
|
} catch (e) {
|
|
919
881
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
920
882
|
renderErrorRef.current = error;
|
|
921
|
-
makeDiag().
|
|
883
|
+
makeDiag().error(PxDiagnosticKind2.internal, error, { phase: "render" });
|
|
922
884
|
return null;
|
|
923
885
|
}
|
|
924
886
|
}, [compiled, trackById]);
|
|
@@ -927,9 +889,6 @@ function PixodeskSvgAnimator({
|
|
|
927
889
|
for (const w of warningsRef.current) diag.warn(PxDiagnosticKind2.platform, w);
|
|
928
890
|
}, [root]);
|
|
929
891
|
const failure = (_b = compiled.error) != null ? _b : renderErrorRef.current;
|
|
930
|
-
useEffect(() => {
|
|
931
|
-
if (failure) onError == null ? void 0 : onError(failure);
|
|
932
|
-
}, [failure]);
|
|
933
892
|
if (failure) return fallback ? fallback(failure) : null;
|
|
934
893
|
let content = root;
|
|
935
894
|
if (autoplay && effectiveStartOn === "scrollIntoView" && root) {
|
|
@@ -954,19 +913,11 @@ function PixodeskSvgAnimator({
|
|
|
954
913
|
}
|
|
955
914
|
);
|
|
956
915
|
}
|
|
957
|
-
return /* @__PURE__ */ jsx(PxRnErrorBoundary, {
|
|
916
|
+
return /* @__PURE__ */ jsx(PxRnErrorBoundary, { fallback, diag: makeDiag(), children: content });
|
|
958
917
|
}
|
|
959
918
|
var PixodeskSvgAnimator_default = PixodeskSvgAnimator;
|
|
960
919
|
export {
|
|
961
920
|
PixodeskSvgAnimator,
|
|
962
|
-
|
|
963
|
-
RN_SVG_COMPONENTS,
|
|
964
|
-
compileTracks,
|
|
965
|
-
PixodeskSvgAnimator_default as default,
|
|
966
|
-
openClosedTextPathTargets,
|
|
967
|
-
renderRnNode,
|
|
968
|
-
sampleProps,
|
|
969
|
-
toRnPropName,
|
|
970
|
-
toRnProps
|
|
921
|
+
PixodeskSvgAnimator_default as default
|
|
971
922
|
};
|
|
972
923
|
//# sourceMappingURL=index.js.map
|