@pixodesk/svg-animator-core 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 CHANGED
@@ -53,19 +53,19 @@ runtime crash on a non-browser platform.
53
53
  | Area | Exports |
54
54
  |---|---|
55
55
  | **Schema & types** | `PxAnimatedSvgDocumentSchema`, `PxNodeSchema`, `PxEffectsSchema`, … plus every `Px*` TypeScript type and the `px` schema builder |
56
- | **Validation** | `validateDocument` (the whole document, strict), `isPxElementFileFormat`, `isPxElementFileFormatDeep`, `validateNodeEffects` |
57
- | **Materializers** | `materializeAllInTree`, `applyPlayerEffects`, `materializeInternalLoopsInTree`, `materializeMotionPathsInTree`, `materializeAnimatedUseInstances` |
58
- | **Interpolation** | `calcAnimationValues`, `interpolateValue`, `getNormalizedBindings` |
59
- | **Sampling / geometry** | `createPathSampler`, `evaluateMotionPathSegment`, bezier helpers, `cubicBezier`, `splitEasing` |
56
+ | **Validation** | `validateDocument` (the whole document, strict), `isPxDocument`, `isValidPxDocument`, `validateNodeEffects` |
57
+ | **Materializers** | `materializeAllInTree`, `materializeNodeEffects` |
58
+ | **Interpolation** | `calcAnimationValues`, `interpolateValue`, `normalizeBindings` |
59
+ | **Sampling / geometry** | `createPathSampler`, bezier helpers, `cubicBezier`, `splitEasing` |
60
60
  | **Text** | `materializeGlyphText`, `layoutGlyphTextChars`, `extendedPathForBrowser` |
61
- | **Node helpers** | `getNormalizedProps`, `sanitizeAttributeValue`, `resolveStyle`, `generateNewIds` |
62
- | **Playback engine** | `createBasicFrameLoopAnimator` + the `PxPlatformAdapter` interface |
63
- | **Wire enums** | `PxTimelineEngine` / `PxTimelineEngineExtra`, `PxStartOn`, `PxOutAction`, `PxFinishAction`, `PxFillMode`, `PxPlaybackDirection`, `PxScrollKind`, `PxScrollAxis`, `PxScrollSource`, `PxScrollPhase`, `PxPinAlign`, `PxAlongPathMode`, `PxLoopRepeatAt`, `PxLoopDirection`, `PxStrokeTrimSubPaths`, `PxMaskType`, `PxCloneWithout`, `PxUnits`, `PxGradientType`, `PxGradientSpreadMethod`, `PxPathOverflow`, `PxLengthAdjust`, `PxTextPathMethod`, `PxTextPathSpacing` — every two-or-more-way wire selector is a named enum, not a bare string. Each is a const namespace AND the string type derived from it under the same name, so `PxStartOn.click` and `startOn?: PxStartOn` come from one import |
61
+ | **Node helpers** | `toDomProps`, `sanitizeAttributeValue`, `generateNewIds` |
62
+ | **Playback engine** | `createAdapterAnimator` + the `PxPlatformAdapter` interface |
63
+ | **Wire enums** | `PxTimelineEngine` / `PxTimelineEngineSetting`, `PxStartOn`, `PxOutAction`, `PxFinishAction`, `PxFillMode`, `PxPlaybackDirection`, `PxScrollKind`, `PxScrollAxis`, `PxScrollSource`, `PxScrollPhase`, `PxPinAlign`, `PxAlongPathMode`, `PxLoopRepeatAt`, `PxLoopDirection`, `PxStrokeTrimSubPaths`, `PxMaskType`, `PxCloneWithout`, `PxUnits`, `PxGradientType`, `PxGradientSpreadMethod`, `PxPathOverflow`, `PxLengthAdjust`, `PxTextPathMethod`, `PxTextPathSpacing` — every two-or-more-way wire selector is a named enum, not a bare string. Each is a const namespace AND the string type derived from it under the same name, so `PxStartOn.click` and `startOn?: PxStartOn` come from one import |
64
64
 
65
65
  ### Validating a document
66
66
 
67
- `isPxElementFileFormat(json)` is the cheap shallow gate (is this a Px document at all?);
68
- `isPxElementFileFormatDeep(json)` runs the full schema. For per-field diagnostics, call a schema's
67
+ `isPxDocument(json)` is the cheap shallow gate (is this a Px document at all?);
68
+ `isValidPxDocument(json)` runs the full schema. For per-field diagnostics, call a schema's
69
69
  `isValid` with a context:
70
70
 
71
71
  ```ts
@@ -90,6 +90,34 @@ per-branch errors are not reported unless every branch fails), and it **ignores
90
90
  `undefined`** — those cannot survive `JSON.stringify`, so strict judges the document rather than the
91
91
  in-memory object that produced it.
92
92
 
93
+ ### The schema the format is written in
94
+
95
+ Nothing above is validated by hand. Every block of the format has a runtime schema built with the
96
+ `px` schema builder, and `validateDocument` walks those. You can walk them too: `describeSchema`
97
+ turns any schema into a plain description — keys, types, and whether each is optional — which is
98
+ how this repo generates its published `SCHEMA.json`, and `schemaKeys` lists just the keys.
99
+
100
+ There is one schema value per block, named after it: `PxTriggerSchema`, `PxElementAnimationSchema`,
101
+ `PxKeyframeValueSchema`, `PxAttrValueSchema`, `PxTransformValueSchema`, `PxBezierPathSchema`,
102
+ `PxScrollSchema`, `PxScrollRangeSchema`, `PxScrollRangePointSchema`, `PxRetimeEffectSchema` and
103
+ `PxGradientStopSchema` among them. Two hold a node's shared halves rather than a block of their
104
+ own — `PxNodeBaseSchema` is what every node has, `PxSvgNodeRootSchema` what only the root `<svg>` adds.
105
+
106
+ To type a schema, or build one of your own: `PxSchema` is the schema type itself, `PxSchemaDesc`
107
+ what `describeSchema` hands back, `PxInfer` the document type a schema describes, and `PxRemoveIndex`
108
+ strips the index signature that SVG pass-through keys bring with them.
109
+
110
+ ### Reading and reshaping a document
111
+
112
+ `diagnoseDocument` is the load-time check every player runs before it builds anything: it hands
113
+ back the problems it found instead of throwing, and `validateDocument` above is the fuller form of
114
+ the same question.
115
+
116
+ A document's timeline has two shapes — the nested object the file stores, and the flat view the
117
+ engines read. `flattenAnimatorTimeline` and `nestAnimatorTimeline` convert between them, so an
118
+ editor can hold one and a player the other with neither having to guess.
119
+ `PX_TRANSFORM_PART_KEYS` lists the parts a transform is written in, in the order they compose.
120
+
93
121
  ## The materialization pipeline
94
122
 
95
123
  `materializeAllInTree(doc, engine)` is the single entry point that turns a
@@ -109,14 +137,14 @@ without live `<use>` propagation** — that includes `react-native-svg` — and
109
137
  ```ts
110
138
  import {
111
139
  materializeAllInTree, generateNewIds, calcAnimationValues,
112
- getNormalizedBindings, PxTimelineEngine,
140
+ normalizeBindings, PxTimelineEngine,
113
141
  } from '@pixodesk/svg-animator-core';
114
142
 
115
143
  // Flatten once …
116
144
  const flat = generateNewIds(materializeAllInTree(doc, PxTimelineEngine.native));
117
145
 
118
146
  // … then ask for values at any time, with no renderer involved.
119
- for (const binding of getNormalizedBindings(flat, PxTimelineEngine.js) ?? []) {
147
+ for (const binding of normalizeBindings(flat, PxTimelineEngine.js) ?? []) {
120
148
  const values = calcAnimationValues(binding.animate, 500); // t = 500 ms
121
149
  console.log(binding.id, values); // → { opacity: '0.5', transform: 'translate(…)' }
122
150
  }
@@ -128,19 +156,19 @@ numbers.
128
156
 
129
157
  ## Writing your own player
130
158
 
131
- Implement `PxPlatformAdapter` and hand it to `createBasicFrameLoopAnimator`; the
159
+ Implement `PxPlatformAdapter` and hand it to `createAdapterAnimator`; the
132
160
  engine handles timing, delay, direction, iterations, fill, playback rate and the
133
161
  lifecycle callbacks, then calls you with plain attribute writes.
134
162
 
135
163
  ```ts
136
- import { createBasicFrameLoopAnimator, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';
164
+ import { createAdapterAnimator, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';
137
165
 
138
166
  const adapter: PxPlatformAdapter = {
139
167
  isConnected: () => true,
140
168
  setAttribute: (id, attrName, value) => { /* apply to your element */ },
141
169
  };
142
170
 
143
- const api = createBasicFrameLoopAnimator(flatDoc, adapter, {
171
+ const api = createAdapterAnimator(flatDoc, adapter, {
144
172
  onFinish: () => console.log('done'),
145
173
  });
146
174
  api.play();
@@ -150,11 +178,28 @@ Frame scheduling resolves `requestAnimationFrame` from `globalThis` at call time
150
178
  and falls back to `setTimeout`, so the engine works in browsers, React Native and
151
179
  test environments with faked timers.
152
180
 
181
+ Every player agrees on one meaning of time, and the helpers that define it are exported so a player
182
+ of your own cannot drift from it. `seekCeilingMs` is the highest time you can seek to and
183
+ `progressSpanMs` the span a `0`–`1` progress maps onto; `clampSeekMs` holds a seek inside that span,
184
+ and `timeToProgress` / `progressToTimeMs` convert between the two. `isValidPlaybackRate` says
185
+ whether a rate can be used, and `PX_RATE_REJECTED` is what a setter reports when it cannot.
186
+ `createRunClock` is the clock the frame loop itself runs on. The callbacks that engine accepts are
187
+ `PxEngineCallbacks` — the playback lifecycle plus the diagnostics channel, and the shape each
188
+ player's own callback type is built on.
189
+
153
190
  ## Versioning
154
191
 
155
192
  Every package in this repo is released in lockstep. A player depends on the
156
193
  matching core version (`^x.y.z`), so upgrading a player upgrades the core with it.
157
194
 
195
+ A **document** carries its own version, which moves independently of the package's: `animator.version`,
196
+ stored under the key `PX_WIRE_VERSION_KEY` and parsed into a `PxWireVersion`. `PX_WIRE_VERSION` is
197
+ the version this build writes and `PX_WIRE_BASELINE_VERSION` the oldest it still reads;
198
+ `PX_WIRE_STEPS` is the ordered list of conversions between them, each a `PxWireVersionStep` of
199
+ some `PxWireStepKind`. `convertWireDocument` brings a document up to this build and reports what it
200
+ did in a `PxWireConversionResult`. `applyWireSteps` runs a chosen subset of those steps instead,
201
+ taking a `PxWireConversionOptions` — which is what the release tooling uses.
202
+
158
203
  ## License
159
204
 
160
205
  [MIT](../../LICENSE) © [Pixodesk](https://pixodesk.com)