@onlynative/inertia-svg 0.0.1-alpha.3
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 +96 -0
- package/dist/index.d.mts +188 -0
- package/dist/index.d.ts +188 -0
- package/dist/index.js +370 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +358 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +83 -0
- package/src/MotionPath.tsx +340 -0
- package/src/index.ts +47 -0
- package/src/path.ts +254 -0
- package/src/types.ts +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# @onlynative/inertia-svg
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@onlynative/inertia-svg)
|
|
4
|
+
[](./LICENSE)
|
|
5
|
+
|
|
6
|
+
Animatable SVG primitives for [`@onlynative/inertia`](../core), built on [`react-native-svg`](https://github.com/software-mansion/react-native-svg).
|
|
7
|
+
|
|
8
|
+
`MotionPath` accepts the same `initial` / `animate` / `transition` shape as the core `Motion.*` primitives, with animatable keys for the path data (`d`), color paint (`fill`, `stroke`), and numeric paint (`strokeWidth`, opacities, `strokeDashoffset`).
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```sh
|
|
13
|
+
pnpm add @onlynative/inertia-svg react-native-svg
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
`react-native-svg` works in bare React Native projects as well as Expo.
|
|
17
|
+
|
|
18
|
+
**Peer dependencies:** `@onlynative/inertia` (workspace or installed), `react >=19.0.0`, `react-native >=0.81.0`, `react-native-reanimated >=4.0.0`, `react-native-svg >=15.0.0`.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import Svg from 'react-native-svg'
|
|
24
|
+
import { MotionPath } from '@onlynative/inertia-svg'
|
|
25
|
+
|
|
26
|
+
export function Heart({ beating }) {
|
|
27
|
+
return (
|
|
28
|
+
<Svg viewBox="0 0 100 100" width={120} height={120}>
|
|
29
|
+
<MotionPath
|
|
30
|
+
d="M 50 30 L 70 12 L 90 30 L 50 88 L 10 30 L 30 12 Z"
|
|
31
|
+
fill="#ef4444"
|
|
32
|
+
stroke="#991b1b"
|
|
33
|
+
strokeWidth={3}
|
|
34
|
+
animate={{
|
|
35
|
+
d: beating
|
|
36
|
+
? 'M 50 28 L 71 10 L 92 28 L 50 92 L 8 28 L 29 10 Z'
|
|
37
|
+
: 'M 50 30 L 70 12 L 90 30 L 50 88 L 10 30 L 30 12 Z',
|
|
38
|
+
}}
|
|
39
|
+
transition={{ type: 'spring', tension: 200, friction: 10 }}
|
|
40
|
+
/>
|
|
41
|
+
</Svg>
|
|
42
|
+
)
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The static `d` prop sets the visual on first render and **locks the command sequence** for the component's lifetime. Every target `d` (via `initial` or `animate`) must produce the same command letters in the same order after implicit-repeat expansion. To switch between structurally different shapes, remount with a new `key`.
|
|
47
|
+
|
|
48
|
+
## Animatable props
|
|
49
|
+
|
|
50
|
+
| Key | Type | Notes |
|
|
51
|
+
| ------------------ | -------- | ------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| `d` | `string` | Path morph via element-wise scalar interpolation. Source and target must share the same template. |
|
|
53
|
+
| `fill` | `string` | Color, interpolated by Reanimated's color setter. |
|
|
54
|
+
| `stroke` | `string` | Color. |
|
|
55
|
+
| `strokeWidth` | `number` | Numeric. |
|
|
56
|
+
| `strokeOpacity` | `number` | 0–1. |
|
|
57
|
+
| `fillOpacity` | `number` | 0–1. |
|
|
58
|
+
| `opacity` | `number` | 0–1. |
|
|
59
|
+
| `strokeDashoffset` | `number` | Useful for "draw-in" animations on a dashed stroke. |
|
|
60
|
+
|
|
61
|
+
Per-property transitions are supported — pass a `{ [key]: TransitionConfig }` shape to `transition` instead of a single config, e.g.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
transition={{
|
|
65
|
+
d: { type: 'spring', tension: 160, friction: 14 },
|
|
66
|
+
fill: { type: 'timing', duration: 300 },
|
|
67
|
+
}}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Structural compatibility
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
✅ M 0 0 L 10 10 Z ↔ M 50 50 L 80 80 Z same template: M L Z
|
|
74
|
+
✅ M 0 0 10 10 20 20 ↔ M 0 0 L 30 30 L 40 40 same after implicit-repeat expansion (M → L)
|
|
75
|
+
❌ M 0 0 L 10 10 Z ↔ M 0 0 L 10 10 segment count differs
|
|
76
|
+
❌ M 0 0 L 10 10 ↔ M 0 0 l 10 10 absolute vs relative are distinct templates
|
|
77
|
+
❌ M 0 0 L 10 10 ↔ M 0 0 C 1 1 2 2 3 3 command letters differ
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
In dev, the component throws on template mismatches at mount, when `animate.d` changes shape, or when the static `d` prop itself changes shape between renders. In production those errors degrade to a no-op snap so a single bad target doesn't crash the screen.
|
|
81
|
+
|
|
82
|
+
Path resampling between structurally different shapes (flubber-style) is out of scope for v0.2. For arbitrary shape swaps, remount with `key={...}`.
|
|
83
|
+
|
|
84
|
+
## Reduced motion
|
|
85
|
+
|
|
86
|
+
`MotionPath` participates in `<MotionConfig reducedMotion>` just like the core primitives — when the OS reduce-motion setting is on (or you pass `reducedMotion="always"`), every animated property snaps directly to its target.
|
|
87
|
+
|
|
88
|
+
## What this package doesn't do (v0.2)
|
|
89
|
+
|
|
90
|
+
- Other SVG shapes (`Circle`, `Rect`, `Line`, `Ellipse`) — land in a follow-up once the `MotionPath` API is validated.
|
|
91
|
+
- Path resampling between arbitrary shapes.
|
|
92
|
+
- Morphing an `L` into a `C` (or other across-command interpolation). Element-wise scalar interpolation is intentional.
|
|
93
|
+
|
|
94
|
+
## License
|
|
95
|
+
|
|
96
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { PathProps } from 'react-native-svg';
|
|
3
|
+
import { TransitionConfig } from '@onlynative/inertia';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Animatable target snapshot for a `MotionSvg.Path`. Every field is optional
|
|
7
|
+
* — include only the dimensions you want to animate; the rest fall back to
|
|
8
|
+
* the static props on the component.
|
|
9
|
+
*
|
|
10
|
+
* `d` morphs the path geometry. The target path **must produce the same
|
|
11
|
+
* command sequence** as the source after implicit-repeat expansion (same
|
|
12
|
+
* letters in the same order, e.g. `M L L L Z`). Element-wise numeric
|
|
13
|
+
* interpolation is the morphing model — see `parsePathD` for the
|
|
14
|
+
* normalization rules.
|
|
15
|
+
*/
|
|
16
|
+
interface PathAnimate {
|
|
17
|
+
d?: string;
|
|
18
|
+
fill?: string;
|
|
19
|
+
stroke?: string;
|
|
20
|
+
strokeWidth?: number;
|
|
21
|
+
strokeOpacity?: number;
|
|
22
|
+
fillOpacity?: number;
|
|
23
|
+
opacity?: number;
|
|
24
|
+
strokeDashoffset?: number;
|
|
25
|
+
}
|
|
26
|
+
/** The animatable dimensions of a `MotionSvg.Path`. */
|
|
27
|
+
type PathStateShape = {
|
|
28
|
+
[K in keyof Required<PathAnimate>]: PathAnimate[K];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Per-property transition map. Top-level entries on `transition` apply to all
|
|
32
|
+
* properties unless overridden by a per-key entry here.
|
|
33
|
+
*/
|
|
34
|
+
type PathPerPropertyTransition = {
|
|
35
|
+
[K in keyof PathStateShape]?: TransitionConfig;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Transition shape accepted by `MotionSvg.Path`. Either a single top-level
|
|
39
|
+
* transition applied to every animated dimension, or a per-property map.
|
|
40
|
+
*/
|
|
41
|
+
type PathTransition = TransitionConfig | PathPerPropertyTransition;
|
|
42
|
+
|
|
43
|
+
interface MotionPathProps extends Omit<PathProps, 'd' | 'fill' | 'stroke' | 'strokeWidth' | 'strokeOpacity' | 'fillOpacity' | 'opacity' | 'strokeDashoffset'> {
|
|
44
|
+
/**
|
|
45
|
+
* Initial path data. **The command sequence is locked at first render** —
|
|
46
|
+
* every target `d` passed via `animate` / `initial` must produce the same
|
|
47
|
+
* command letters in the same order after implicit-repeat expansion. To
|
|
48
|
+
* morph between structurally different paths, remount with a new `key`.
|
|
49
|
+
*/
|
|
50
|
+
d: string;
|
|
51
|
+
fill?: string;
|
|
52
|
+
stroke?: string;
|
|
53
|
+
strokeWidth?: number;
|
|
54
|
+
strokeOpacity?: number;
|
|
55
|
+
fillOpacity?: number;
|
|
56
|
+
opacity?: number;
|
|
57
|
+
strokeDashoffset?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Initial frame override. When present, the component mounts displaying
|
|
60
|
+
* these values, then animates to `animate` on the next effect. Pass `false`
|
|
61
|
+
* to skip the initial-mount animation entirely.
|
|
62
|
+
*/
|
|
63
|
+
initial?: PathAnimate | false;
|
|
64
|
+
/** Target animation state. */
|
|
65
|
+
animate?: PathAnimate;
|
|
66
|
+
/**
|
|
67
|
+
* Transition config — either a single `TransitionConfig` applied to every
|
|
68
|
+
* animated dimension, or a per-property map. Per-property entries win over
|
|
69
|
+
* the top-level transition.
|
|
70
|
+
*/
|
|
71
|
+
transition?: PathTransition;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Animatable `<Path>` from `react-native-svg`. Wraps `Path` with declarative
|
|
75
|
+
* `initial` / `animate` / `transition` props.
|
|
76
|
+
*
|
|
77
|
+
* Animatable dimensions:
|
|
78
|
+
* - `d` — path morph via element-wise scalar interpolation. Source and target
|
|
79
|
+
* must share the same command sequence (e.g. both `M L L L Z`).
|
|
80
|
+
* - `fill`, `stroke` — color strings, interpolated via Reanimated's native
|
|
81
|
+
* color animation.
|
|
82
|
+
* - `strokeWidth`, `strokeOpacity`, `fillOpacity`, `opacity`,
|
|
83
|
+
* `strokeDashoffset` — numeric, spring or timing-driven.
|
|
84
|
+
*
|
|
85
|
+
* Example:
|
|
86
|
+
* ```tsx
|
|
87
|
+
* <Svg viewBox="0 0 100 100">
|
|
88
|
+
* <MotionPath
|
|
89
|
+
* d="M 50 20 L 80 80 L 20 80 Z"
|
|
90
|
+
* animate={{ d: "M 50 80 L 80 20 L 20 20 Z", fill: '#7c3aed' }}
|
|
91
|
+
* transition={{ type: 'spring', tension: 140, friction: 12 }}
|
|
92
|
+
* fill="#0ea5e9"
|
|
93
|
+
* />
|
|
94
|
+
* </Svg>
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare function MotionPath(props: MotionPathProps): react.JSX.Element;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* SVG path-string utilities used by `MotionSvg.Path`. Everything here runs on
|
|
101
|
+
* the JS thread — paths are tokenized into a normalized command list at mount
|
|
102
|
+
* and when `animate.d` changes; the worklet only ever consumes flat number
|
|
103
|
+
* arrays + a frozen command template.
|
|
104
|
+
*
|
|
105
|
+
* Path morphing in v0.2 requires **structural compatibility**: the source and
|
|
106
|
+
* every target `d` must produce the same command sequence (same command
|
|
107
|
+
* letters, in the same order, after implicit-repeat expansion). Element-wise
|
|
108
|
+
* numeric interpolation is the entire morphing model — we do not resample
|
|
109
|
+
* paths or insert/remove commands. Same-shape morphs (e.g. a heart breathing,
|
|
110
|
+
* a chevron flipping, a check mark tracing in) are the supported use case.
|
|
111
|
+
*/
|
|
112
|
+
/**
|
|
113
|
+
* A single normalized path command after implicit-repeat expansion. The cmd
|
|
114
|
+
* letter is preserved (absolute vs relative — case is meaningful to the SVG
|
|
115
|
+
* renderer). `args` always has exactly `CMD_ARGS[cmd]` entries.
|
|
116
|
+
*/
|
|
117
|
+
interface PathSegment {
|
|
118
|
+
cmd: string;
|
|
119
|
+
args: number[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parse a path `d` string into a flat list of normalized segments. Implicit
|
|
123
|
+
* repeats are expanded — `M 0 0 10 10 20 20` becomes three segments
|
|
124
|
+
* (`M 0 0`, `L 10 10`, `L 20 20`) so the segment list can be compared and
|
|
125
|
+
* interpolated 1:1 against another path.
|
|
126
|
+
*/
|
|
127
|
+
declare function parsePathD(d: string): PathSegment[];
|
|
128
|
+
/**
|
|
129
|
+
* The frozen "shape" of a path — just command letters and arg widths. Two
|
|
130
|
+
* paths are morphable iff their templates are equal.
|
|
131
|
+
*/
|
|
132
|
+
interface PathTemplate {
|
|
133
|
+
cmds: ReadonlyArray<string>;
|
|
134
|
+
/** Flat width per segment, indexed parallel to `cmds`. */
|
|
135
|
+
widths: ReadonlyArray<number>;
|
|
136
|
+
/** Total scalar count across all segments — `widths.reduce((a,b)=>a+b,0)`. */
|
|
137
|
+
size: number;
|
|
138
|
+
}
|
|
139
|
+
declare function templateOf(segments: ReadonlyArray<PathSegment>): PathTemplate;
|
|
140
|
+
/** Flatten a parsed segment list into a single number array (length === size). */
|
|
141
|
+
declare function flattenParams(segments: ReadonlyArray<PathSegment>): number[];
|
|
142
|
+
/**
|
|
143
|
+
* Verify a target template matches the source. Returns `null` on match or a
|
|
144
|
+
* descriptive error string on mismatch — callers throw in `__DEV__` and
|
|
145
|
+
* silently snap to the target in production.
|
|
146
|
+
*/
|
|
147
|
+
declare function diffTemplate(source: PathTemplate, target: PathTemplate): string | null;
|
|
148
|
+
/**
|
|
149
|
+
* Build a path `d` string from a template + flat param array. Runs inside the
|
|
150
|
+
* worklet on the UI thread, so it must not capture any JS-thread closures or
|
|
151
|
+
* use Array.prototype helpers that allocate intermediates the Hermes runtime
|
|
152
|
+
* boxes into JS objects. Manual loops + `+=` string concat keep the worklet
|
|
153
|
+
* cheap.
|
|
154
|
+
*
|
|
155
|
+
* MUST be a worklet — call sites in `MotionPath` wrap it with `'worklet'` via
|
|
156
|
+
* `useAnimatedProps`.
|
|
157
|
+
*/
|
|
158
|
+
declare function serializePath(template: PathTemplate, params: ReadonlyArray<number>): string;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* `@onlynative/inertia-svg` — animatable SVG primitives for
|
|
162
|
+
* `@onlynative/inertia`.
|
|
163
|
+
*
|
|
164
|
+
* v0.2 surface:
|
|
165
|
+
* - `MotionPath` / `MotionSvg.Path` — animatable `<Path>` over
|
|
166
|
+
* `react-native-svg`. Supports path morphing on the `d` attribute (source
|
|
167
|
+
* and target must share the same command sequence) plus animatable
|
|
168
|
+
* `fill`, `stroke`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
|
|
169
|
+
* `opacity`, and `strokeDashoffset` with the same `initial` /
|
|
170
|
+
* `animate` / `transition` shape as the core `Motion.*` primitives.
|
|
171
|
+
*
|
|
172
|
+
* Additional shape primitives (`Circle`, `Rect`, `Line`, `Ellipse`) land in
|
|
173
|
+
* a follow-up once the path morphing API is validated. Path normalization
|
|
174
|
+
* (resampling between structurally different paths) is out of scope for
|
|
175
|
+
* v0.2 — use structurally-compatible source/target paths and remount with
|
|
176
|
+
* `key={...}` to switch shape.
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` for
|
|
181
|
+
* autocomplete-friendly grouping or import `MotionPath` directly — both
|
|
182
|
+
* point at the same component.
|
|
183
|
+
*/
|
|
184
|
+
declare const MotionSvg: {
|
|
185
|
+
readonly Path: typeof MotionPath;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export { MotionPath, type MotionPathProps, MotionSvg, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { PathProps } from 'react-native-svg';
|
|
3
|
+
import { TransitionConfig } from '@onlynative/inertia';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Animatable target snapshot for a `MotionSvg.Path`. Every field is optional
|
|
7
|
+
* — include only the dimensions you want to animate; the rest fall back to
|
|
8
|
+
* the static props on the component.
|
|
9
|
+
*
|
|
10
|
+
* `d` morphs the path geometry. The target path **must produce the same
|
|
11
|
+
* command sequence** as the source after implicit-repeat expansion (same
|
|
12
|
+
* letters in the same order, e.g. `M L L L Z`). Element-wise numeric
|
|
13
|
+
* interpolation is the morphing model — see `parsePathD` for the
|
|
14
|
+
* normalization rules.
|
|
15
|
+
*/
|
|
16
|
+
interface PathAnimate {
|
|
17
|
+
d?: string;
|
|
18
|
+
fill?: string;
|
|
19
|
+
stroke?: string;
|
|
20
|
+
strokeWidth?: number;
|
|
21
|
+
strokeOpacity?: number;
|
|
22
|
+
fillOpacity?: number;
|
|
23
|
+
opacity?: number;
|
|
24
|
+
strokeDashoffset?: number;
|
|
25
|
+
}
|
|
26
|
+
/** The animatable dimensions of a `MotionSvg.Path`. */
|
|
27
|
+
type PathStateShape = {
|
|
28
|
+
[K in keyof Required<PathAnimate>]: PathAnimate[K];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Per-property transition map. Top-level entries on `transition` apply to all
|
|
32
|
+
* properties unless overridden by a per-key entry here.
|
|
33
|
+
*/
|
|
34
|
+
type PathPerPropertyTransition = {
|
|
35
|
+
[K in keyof PathStateShape]?: TransitionConfig;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Transition shape accepted by `MotionSvg.Path`. Either a single top-level
|
|
39
|
+
* transition applied to every animated dimension, or a per-property map.
|
|
40
|
+
*/
|
|
41
|
+
type PathTransition = TransitionConfig | PathPerPropertyTransition;
|
|
42
|
+
|
|
43
|
+
interface MotionPathProps extends Omit<PathProps, 'd' | 'fill' | 'stroke' | 'strokeWidth' | 'strokeOpacity' | 'fillOpacity' | 'opacity' | 'strokeDashoffset'> {
|
|
44
|
+
/**
|
|
45
|
+
* Initial path data. **The command sequence is locked at first render** —
|
|
46
|
+
* every target `d` passed via `animate` / `initial` must produce the same
|
|
47
|
+
* command letters in the same order after implicit-repeat expansion. To
|
|
48
|
+
* morph between structurally different paths, remount with a new `key`.
|
|
49
|
+
*/
|
|
50
|
+
d: string;
|
|
51
|
+
fill?: string;
|
|
52
|
+
stroke?: string;
|
|
53
|
+
strokeWidth?: number;
|
|
54
|
+
strokeOpacity?: number;
|
|
55
|
+
fillOpacity?: number;
|
|
56
|
+
opacity?: number;
|
|
57
|
+
strokeDashoffset?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Initial frame override. When present, the component mounts displaying
|
|
60
|
+
* these values, then animates to `animate` on the next effect. Pass `false`
|
|
61
|
+
* to skip the initial-mount animation entirely.
|
|
62
|
+
*/
|
|
63
|
+
initial?: PathAnimate | false;
|
|
64
|
+
/** Target animation state. */
|
|
65
|
+
animate?: PathAnimate;
|
|
66
|
+
/**
|
|
67
|
+
* Transition config — either a single `TransitionConfig` applied to every
|
|
68
|
+
* animated dimension, or a per-property map. Per-property entries win over
|
|
69
|
+
* the top-level transition.
|
|
70
|
+
*/
|
|
71
|
+
transition?: PathTransition;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Animatable `<Path>` from `react-native-svg`. Wraps `Path` with declarative
|
|
75
|
+
* `initial` / `animate` / `transition` props.
|
|
76
|
+
*
|
|
77
|
+
* Animatable dimensions:
|
|
78
|
+
* - `d` — path morph via element-wise scalar interpolation. Source and target
|
|
79
|
+
* must share the same command sequence (e.g. both `M L L L Z`).
|
|
80
|
+
* - `fill`, `stroke` — color strings, interpolated via Reanimated's native
|
|
81
|
+
* color animation.
|
|
82
|
+
* - `strokeWidth`, `strokeOpacity`, `fillOpacity`, `opacity`,
|
|
83
|
+
* `strokeDashoffset` — numeric, spring or timing-driven.
|
|
84
|
+
*
|
|
85
|
+
* Example:
|
|
86
|
+
* ```tsx
|
|
87
|
+
* <Svg viewBox="0 0 100 100">
|
|
88
|
+
* <MotionPath
|
|
89
|
+
* d="M 50 20 L 80 80 L 20 80 Z"
|
|
90
|
+
* animate={{ d: "M 50 80 L 80 20 L 20 20 Z", fill: '#7c3aed' }}
|
|
91
|
+
* transition={{ type: 'spring', tension: 140, friction: 12 }}
|
|
92
|
+
* fill="#0ea5e9"
|
|
93
|
+
* />
|
|
94
|
+
* </Svg>
|
|
95
|
+
* ```
|
|
96
|
+
*/
|
|
97
|
+
declare function MotionPath(props: MotionPathProps): react.JSX.Element;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* SVG path-string utilities used by `MotionSvg.Path`. Everything here runs on
|
|
101
|
+
* the JS thread — paths are tokenized into a normalized command list at mount
|
|
102
|
+
* and when `animate.d` changes; the worklet only ever consumes flat number
|
|
103
|
+
* arrays + a frozen command template.
|
|
104
|
+
*
|
|
105
|
+
* Path morphing in v0.2 requires **structural compatibility**: the source and
|
|
106
|
+
* every target `d` must produce the same command sequence (same command
|
|
107
|
+
* letters, in the same order, after implicit-repeat expansion). Element-wise
|
|
108
|
+
* numeric interpolation is the entire morphing model — we do not resample
|
|
109
|
+
* paths or insert/remove commands. Same-shape morphs (e.g. a heart breathing,
|
|
110
|
+
* a chevron flipping, a check mark tracing in) are the supported use case.
|
|
111
|
+
*/
|
|
112
|
+
/**
|
|
113
|
+
* A single normalized path command after implicit-repeat expansion. The cmd
|
|
114
|
+
* letter is preserved (absolute vs relative — case is meaningful to the SVG
|
|
115
|
+
* renderer). `args` always has exactly `CMD_ARGS[cmd]` entries.
|
|
116
|
+
*/
|
|
117
|
+
interface PathSegment {
|
|
118
|
+
cmd: string;
|
|
119
|
+
args: number[];
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Parse a path `d` string into a flat list of normalized segments. Implicit
|
|
123
|
+
* repeats are expanded — `M 0 0 10 10 20 20` becomes three segments
|
|
124
|
+
* (`M 0 0`, `L 10 10`, `L 20 20`) so the segment list can be compared and
|
|
125
|
+
* interpolated 1:1 against another path.
|
|
126
|
+
*/
|
|
127
|
+
declare function parsePathD(d: string): PathSegment[];
|
|
128
|
+
/**
|
|
129
|
+
* The frozen "shape" of a path — just command letters and arg widths. Two
|
|
130
|
+
* paths are morphable iff their templates are equal.
|
|
131
|
+
*/
|
|
132
|
+
interface PathTemplate {
|
|
133
|
+
cmds: ReadonlyArray<string>;
|
|
134
|
+
/** Flat width per segment, indexed parallel to `cmds`. */
|
|
135
|
+
widths: ReadonlyArray<number>;
|
|
136
|
+
/** Total scalar count across all segments — `widths.reduce((a,b)=>a+b,0)`. */
|
|
137
|
+
size: number;
|
|
138
|
+
}
|
|
139
|
+
declare function templateOf(segments: ReadonlyArray<PathSegment>): PathTemplate;
|
|
140
|
+
/** Flatten a parsed segment list into a single number array (length === size). */
|
|
141
|
+
declare function flattenParams(segments: ReadonlyArray<PathSegment>): number[];
|
|
142
|
+
/**
|
|
143
|
+
* Verify a target template matches the source. Returns `null` on match or a
|
|
144
|
+
* descriptive error string on mismatch — callers throw in `__DEV__` and
|
|
145
|
+
* silently snap to the target in production.
|
|
146
|
+
*/
|
|
147
|
+
declare function diffTemplate(source: PathTemplate, target: PathTemplate): string | null;
|
|
148
|
+
/**
|
|
149
|
+
* Build a path `d` string from a template + flat param array. Runs inside the
|
|
150
|
+
* worklet on the UI thread, so it must not capture any JS-thread closures or
|
|
151
|
+
* use Array.prototype helpers that allocate intermediates the Hermes runtime
|
|
152
|
+
* boxes into JS objects. Manual loops + `+=` string concat keep the worklet
|
|
153
|
+
* cheap.
|
|
154
|
+
*
|
|
155
|
+
* MUST be a worklet — call sites in `MotionPath` wrap it with `'worklet'` via
|
|
156
|
+
* `useAnimatedProps`.
|
|
157
|
+
*/
|
|
158
|
+
declare function serializePath(template: PathTemplate, params: ReadonlyArray<number>): string;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* `@onlynative/inertia-svg` — animatable SVG primitives for
|
|
162
|
+
* `@onlynative/inertia`.
|
|
163
|
+
*
|
|
164
|
+
* v0.2 surface:
|
|
165
|
+
* - `MotionPath` / `MotionSvg.Path` — animatable `<Path>` over
|
|
166
|
+
* `react-native-svg`. Supports path morphing on the `d` attribute (source
|
|
167
|
+
* and target must share the same command sequence) plus animatable
|
|
168
|
+
* `fill`, `stroke`, `strokeWidth`, `strokeOpacity`, `fillOpacity`,
|
|
169
|
+
* `opacity`, and `strokeDashoffset` with the same `initial` /
|
|
170
|
+
* `animate` / `transition` shape as the core `Motion.*` primitives.
|
|
171
|
+
*
|
|
172
|
+
* Additional shape primitives (`Circle`, `Rect`, `Line`, `Ellipse`) land in
|
|
173
|
+
* a follow-up once the path morphing API is validated. Path normalization
|
|
174
|
+
* (resampling between structurally different paths) is out of scope for
|
|
175
|
+
* v0.2 — use structurally-compatible source/target paths and remount with
|
|
176
|
+
* `key={...}` to switch shape.
|
|
177
|
+
*/
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Namespace bundling every animatable SVG primitive. Use `MotionSvg.Path` for
|
|
181
|
+
* autocomplete-friendly grouping or import `MotionPath` directly — both
|
|
182
|
+
* point at the same component.
|
|
183
|
+
*/
|
|
184
|
+
declare const MotionSvg: {
|
|
185
|
+
readonly Path: typeof MotionPath;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export { MotionPath, type MotionPathProps, MotionSvg, type PathAnimate, type PathPerPropertyTransition, type PathSegment, type PathStateShape, type PathTemplate, type PathTransition, diffTemplate, flattenParams, parsePathD, serializePath, templateOf };
|