@pixodesk/svg-animator-core 1.0.44 → 1.0.45

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/dist/index.cjs CHANGED
@@ -2341,6 +2341,38 @@ function toDomProps(props) {
2341
2341
  return propsCopy;
2342
2342
  }
2343
2343
 
2344
+ // src/animation/PxStaticTransformMerge.ts
2345
+ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
2346
+ if (!animDef) return animDef;
2347
+ const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
2348
+ if (!staticParts || !Object.keys(staticParts).length) return animDef;
2349
+ const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
2350
+ const transformAnim = animDef[TRANSFORM_ATTR];
2351
+ if (transformAnim && typeof transformAnim === "object") {
2352
+ const anim = transformAnim;
2353
+ if (Array.isArray(anim.keyframes)) {
2354
+ const out = __spreadProps(__spreadValues({}, anim), {
2355
+ keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
2356
+ });
2357
+ if (out.value !== void 0) out.value = mergeKfValue(out.value);
2358
+ return __spreadProps(__spreadValues({}, animDef), { transform: out });
2359
+ }
2360
+ return animDef;
2361
+ }
2362
+ const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
2363
+ if (channels.length !== 1) return animDef;
2364
+ const ch = channels[0];
2365
+ const chAnim = animDef[ch];
2366
+ if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
2367
+ const lifted = __spreadProps(__spreadValues({}, chAnim), {
2368
+ keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
2369
+ });
2370
+ if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
2371
+ const rest = __spreadValues({}, animDef);
2372
+ delete rest[ch];
2373
+ return __spreadProps(__spreadValues({}, rest), { transform: lifted });
2374
+ }
2375
+
2344
2376
  // src/materialize/PxMotionPath.ts
2345
2377
  function getKfTranslate(kf) {
2346
2378
  const v = keyframeValue(kf);
@@ -2710,7 +2742,7 @@ function walkAndMaterialize(node, opts) {
2710
2742
  let newAnimate;
2711
2743
  const animBucket = node.animate;
2712
2744
  if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
2713
- const animDef = animBucket;
2745
+ const animDef = mergeStaticTransformIntoAnimDef(animBucket, node.transform);
2714
2746
  const transformAnim = animDef.transform;
2715
2747
  if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
2716
2748
  const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
@@ -3224,36 +3256,6 @@ var _elementIdCounter = 0;
3224
3256
  function generateElementId() {
3225
3257
  return "_px_el_" + ++_elementIdCounter;
3226
3258
  }
3227
- function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
3228
- if (!animDef) return animDef;
3229
- const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
3230
- if (!staticParts || !Object.keys(staticParts).length) return animDef;
3231
- const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
3232
- const transformAnim = animDef[TRANSFORM_ATTR];
3233
- if (transformAnim && typeof transformAnim === "object") {
3234
- const anim = transformAnim;
3235
- if (Array.isArray(anim.keyframes)) {
3236
- const out = __spreadProps(__spreadValues({}, anim), {
3237
- keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
3238
- });
3239
- if (out.value !== void 0) out.value = mergeKfValue(out.value);
3240
- return __spreadProps(__spreadValues({}, animDef), { transform: out });
3241
- }
3242
- return animDef;
3243
- }
3244
- const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
3245
- if (channels.length !== 1) return animDef;
3246
- const ch = channels[0];
3247
- const chAnim = animDef[ch];
3248
- if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
3249
- const lifted = __spreadProps(__spreadValues({}, chAnim), {
3250
- keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
3251
- });
3252
- if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
3253
- const rest = __spreadValues({}, animDef);
3254
- delete rest[ch];
3255
- return __spreadProps(__spreadValues({}, rest), { transform: lifted });
3256
- }
3257
3259
  function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
3258
3260
  const normalized = {};
3259
3261
  for (const [propName, propAnim] of Object.entries(animDef)) {
@@ -3336,7 +3338,7 @@ function getKeyframesPair(keyframes, progress) {
3336
3338
  return { prevKf, nextKf };
3337
3339
  }
3338
3340
  function calcPropertyValue(propName, propAnim, progress) {
3339
- var _a2, _b, _c, _d;
3341
+ var _a2, _b, _c, _d, _e;
3340
3342
  const keyframes = propAnim.keyframes || [];
3341
3343
  if (keyframes.length === 0) return null;
3342
3344
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
@@ -3405,7 +3407,7 @@ function calcPropertyValue(propName, propAnim, progress) {
3405
3407
  !!propAnim.autoOrient
3406
3408
  );
3407
3409
  partsResult.translate = [sample.translate[0], sample.translate[1]];
3408
- if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
3410
+ if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg + ((_e = partsResult.rotate) != null ? _e : 0);
3409
3411
  }
3410
3412
  }
3411
3413
  cssValue = composeTransformParts(partsResult, { withUnits: false });
@@ -5888,12 +5890,17 @@ function buildOffsetPath(propAnim) {
5888
5890
  const first = keyframeValue(kfs[0]);
5889
5891
  const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
5890
5892
  const points = [];
5893
+ let keyframesCarryRotate = false;
5891
5894
  for (const kf of kfs) {
5892
5895
  const v = keyframeValue(kf);
5893
5896
  const tr = v == null ? void 0 : v.translate;
5894
5897
  if (!tr || tr.length < 2) return void 0;
5895
5898
  const parts = Object.keys(v);
5896
- if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
5899
+ if (parts.some((p) => p !== TRANSFORM_PART.translate && p !== TRANSFORM_PART.origin && p !== TRANSFORM_PART.rotate)) return void 0;
5900
+ if ((v == null ? void 0 : v.rotate) !== void 0) {
5901
+ if (v.rotate !== 0) return void 0;
5902
+ keyframesCarryRotate = true;
5903
+ }
5897
5904
  const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
5898
5905
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
5899
5906
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
@@ -5921,7 +5928,7 @@ function buildOffsetPath(propAnim) {
5921
5928
  if (e !== void 0) out.e = e;
5922
5929
  distanceKfs.push(out);
5923
5930
  }
5924
- return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
5931
+ return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor, keyframesCarryRotate };
5925
5932
  }
5926
5933
  function materializeOffsetPathsInTree(root) {
5927
5934
  const walk = (node) => {
@@ -5943,6 +5950,7 @@ function materializeOffsetPathsInTree(root) {
5943
5950
  const t = __spreadValues({}, staticTr);
5944
5951
  delete t[TRANSFORM_PART.translate];
5945
5952
  delete t[TRANSFORM_PART.origin];
5953
+ if (built.keyframesCarryRotate) delete t[TRANSFORM_PART.rotate];
5946
5954
  newTransform = Object.keys(t).length ? t : void 0;
5947
5955
  }
5948
5956
  out = __spreadProps(__spreadValues({}, node), {
@@ -6115,6 +6123,78 @@ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, ro
6115
6123
  return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
6116
6124
  }
6117
6125
 
6126
+ // src/materialize/PxRestPose.ts
6127
+ var TRANSFORM_CHANNEL = "transform";
6128
+ var REVERSED_DIRECTIONS = /* @__PURE__ */ new Set(["reverse", "alternate-reverse"]);
6129
+ var SCRATCH_ID_PREFIX = "__px_rest_";
6130
+ function materializeRestPosesInTree(root, engine) {
6131
+ var _a2;
6132
+ const out = deepClone(root);
6133
+ const config = getAnimatorConfig(out) || {};
6134
+ const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
6135
+ const firstFrameTime = REVERSED_DIRECTIONS.has(String(config.direction)) ? duration : 0;
6136
+ const nodes = animatedNodes(out);
6137
+ if (!nodes.size) return out;
6138
+ const before = bindingsOf(out, engine);
6139
+ const added = /* @__PURE__ */ new Map();
6140
+ for (const [key, animate] of before) {
6141
+ const node = nodes.get(key);
6142
+ if (!node) continue;
6143
+ for (const channel of Object.keys(animate)) {
6144
+ if (!mayCarryRestPose(node, channel)) continue;
6145
+ const value = firstFrameValue(animate, channel, firstFrameTime);
6146
+ if (value === void 0) continue;
6147
+ node[channel] = value;
6148
+ added.set(key, [...(_a2 = added.get(key)) != null ? _a2 : [], channel]);
6149
+ }
6150
+ }
6151
+ if (added.size) {
6152
+ const after = bindingsOf(out, engine);
6153
+ for (const [key, channels] of added) {
6154
+ if (JSON.stringify(after.get(key)) === JSON.stringify(before.get(key))) continue;
6155
+ const node = nodes.get(key);
6156
+ if (node) for (const channel of channels) delete node[channel];
6157
+ }
6158
+ }
6159
+ return out;
6160
+ }
6161
+ function mayCarryRestPose(node, channel) {
6162
+ if (node[channel] !== void 0) return false;
6163
+ if (PX_TRANSFORM_FN_NAMES.has(channel)) return false;
6164
+ if (channel === TRANSFORM_CHANNEL) {
6165
+ for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
6166
+ }
6167
+ return true;
6168
+ }
6169
+ function firstFrameValue(animate, channel, timeMs) {
6170
+ const values = Object.values(calcAnimationValues({ [channel]: animate[channel] }, timeMs));
6171
+ return values.length === 1 && values[0] !== "" ? values[0] : void 0;
6172
+ }
6173
+ function bindingsOf(tree, engine) {
6174
+ const scratch = deepClone(tree);
6175
+ const keyById = /* @__PURE__ */ new Map();
6176
+ for (const [key, node] of animatedNodes(scratch)) {
6177
+ if (node.id === void 0) node.id = SCRATCH_ID_PREFIX + key;
6178
+ keyById.set(String(node.id), key);
6179
+ }
6180
+ const out = /* @__PURE__ */ new Map();
6181
+ for (const binding of normalizeBindings(scratch, engine)) {
6182
+ const key = keyById.get(binding.id);
6183
+ if (key !== void 0) out.set(key, binding.animate);
6184
+ }
6185
+ return out;
6186
+ }
6187
+ function animatedNodes(tree) {
6188
+ const out = /* @__PURE__ */ new Map();
6189
+ let counter = 0;
6190
+ const visit = (node) => {
6191
+ if (node.animate) out.set(String(counter++), node);
6192
+ if (node.children) for (const child of node.children) visit(child);
6193
+ };
6194
+ if (tree.children) for (const child of tree.children) visit(child);
6195
+ return out;
6196
+ }
6197
+
6118
6198
  // src/materialize/PxAnimatorMaterializeAll.ts
6119
6199
  function materializeAllInTree(doc, engine, options) {
6120
6200
  var _a2, _b;
@@ -6127,6 +6207,7 @@ function materializeAllInTree(doc, engine, options) {
6127
6207
  root = materializeAnimatedUseInstances(root);
6128
6208
  root = pruneUnreferencedDefs(root);
6129
6209
  }
6210
+ root = materializeRestPosesInTree(root, engine);
6130
6211
  return root;
6131
6212
  }
6132
6213
  function pruneUnreferencedDefs(root) {