@pixodesk/svg-animator-react 1.0.24 → 1.0.26

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.umd.js CHANGED
@@ -2643,8 +2643,10 @@ var PixodeskAnimatorReact = (() => {
2643
2643
  children: px.lazy(() => px.array(PxNodeSchema), []).optional()
2644
2644
  }), PxAttrValueSchema);
2645
2645
  var PxSvgNodeExtra = px.object({
2646
- width: px.number().optional(),
2647
- height: px.number().optional(),
2646
+ // `"100%"` and other SVG length strings are legal here — a number-only slot rejected
2647
+ // real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
2648
+ width: px.union([px.number(), px.string()]).optional(),
2649
+ height: px.union([px.number(), px.string()]).optional(),
2648
2650
  viewBox: px.string().optional(),
2649
2651
  animator: PxAnimatorConfigSchema.optional()
2650
2652
  });
@@ -3673,7 +3675,7 @@ var PixodeskAnimatorReact = (() => {
3673
3675
  if (newAnimate) cloned.animate = newAnimate;
3674
3676
  return cloned;
3675
3677
  }
3676
- var LOOP_JUMP_SHIFT_MS = 10;
3678
+ var LOOP_JUMP_SHIFT_MS = 1;
3677
3679
  function deepEqualValue(a, b) {
3678
3680
  if (a === b) return true;
3679
3681
  if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
@@ -3922,6 +3924,8 @@ var PixodeskAnimatorReact = (() => {
3922
3924
  const looped = [];
3923
3925
  const separateBoundary = loop.extend !== PxLoopExtend.before;
3924
3926
  const originalTerminalKf = keyframes[keyframes.length - 1];
3927
+ let terminalEasingOverride;
3928
+ let hasTerminalEasingOverride = false;
3925
3929
  function appendRep(repStart, isReversed, partial) {
3926
3930
  var _a2;
3927
3931
  let entries;
@@ -3962,7 +3966,16 @@ var PixodeskAnimatorReact = (() => {
3962
3966
  const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
3963
3967
  const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a2 = prevKf.t) != null ? _a2 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
3964
3968
  if (isBoundary) {
3965
- if (deepEqualValue(prevKf.v, entry.v)) continue;
3969
+ if (deepEqualValue(prevKf.v, entry.v)) {
3970
+ if (looped.length > 0) {
3971
+ prevKf.e = entry.e;
3972
+ prevKf.tangentOut = entry.tangentOut;
3973
+ } else {
3974
+ terminalEasingOverride = entry.e;
3975
+ hasTerminalEasingOverride = true;
3976
+ }
3977
+ continue;
3978
+ }
3966
3979
  if (looped.length > 0) {
3967
3980
  delete prevKf.tangentIn;
3968
3981
  delete prevKf.tangentOut;
@@ -4043,6 +4056,11 @@ var PixodeskAnimatorReact = (() => {
4043
4056
  if (loop.extend === PxLoopExtend.before) {
4044
4057
  return [...looped, ...keyframes];
4045
4058
  } else {
4059
+ if (hasTerminalEasingOverride && keyframes.length > 0) {
4060
+ const head = keyframes.slice(0, -1);
4061
+ const tail = __spreadProps2(__spreadValues2({}, keyframes[keyframes.length - 1]), { e: terminalEasingOverride });
4062
+ return [...head, tail, ...looped];
4063
+ }
4046
4064
  return [...keyframes, ...looped];
4047
4065
  }
4048
4066
  }
@@ -4159,6 +4177,9 @@ var PixodeskAnimatorReact = (() => {
4159
4177
  function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
4160
4178
  const normalized = {};
4161
4179
  for (const [propName, propAnim] of Object.entries(animDef)) {
4180
+ if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
4181
+ continue;
4182
+ }
4162
4183
  const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
4163
4184
  if (normalizedKfs.length > 0) {
4164
4185
  const out = { kfs: normalizedKfs };
@@ -6838,9 +6859,138 @@ var PixodeskAnimatorReact = (() => {
6838
6859
  applyAllRetimeEffects(node, ctx);
6839
6860
  return node;
6840
6861
  }
6862
+ var kfTime = (kf) => {
6863
+ var _a, _b;
6864
+ return (_b = (_a = kf.t) != null ? _a : kf.time) != null ? _b : 0;
6865
+ };
6866
+ var kfValue = (kf) => {
6867
+ var _a;
6868
+ return (_a = kf.v) != null ? _a : kf.value;
6869
+ };
6870
+ var kfEasing = (kf) => {
6871
+ var _a;
6872
+ return (_a = kf.e) != null ? _a : kf.easing;
6873
+ };
6874
+ var kfTangentIn = (kf) => {
6875
+ var _a;
6876
+ return (_a = kf.tangentIn) != null ? _a : kf.ti;
6877
+ };
6878
+ var kfTangentOut = (kf) => {
6879
+ var _a;
6880
+ return (_a = kf.tangentOut) != null ? _a : kf.to;
6881
+ };
6882
+ function cubicAt(p0, c1, c2, p1, t) {
6883
+ const u = 1 - t;
6884
+ const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
6885
+ return [
6886
+ a * p0[0] + b * c1[0] + c * c2[0] + d * p1[0],
6887
+ a * p0[1] + b * c1[1] + c * c2[1] + d * p1[1]
6888
+ ];
6889
+ }
6890
+ function cubicLength(p0, c1, c2, p1, steps = 64) {
6891
+ let len = 0;
6892
+ let prev = p0;
6893
+ for (let i = 1; i <= steps; i++) {
6894
+ const pt = cubicAt(p0, c1, c2, p1, i / steps);
6895
+ len += Math.hypot(pt[0] - prev[0], pt[1] - prev[1]);
6896
+ prev = pt;
6897
+ }
6898
+ return len;
6899
+ }
6900
+ var fmt2 = (n) => {
6901
+ const r = Math.round(n * 1e4) / 1e4;
6902
+ return Object.is(r, -0) ? "0" : String(r);
6903
+ };
6904
+ function buildOffsetPath(propAnim) {
6905
+ var _a, _b, _c, _d;
6906
+ if (propAnim.alongPathMode !== "offsetPath") return void 0;
6907
+ const kfs = (_a = propAnim.keyframes) != null ? _a : propAnim.kfs;
6908
+ if (!kfs || kfs.length < 2) return void 0;
6909
+ const first = kfValue(kfs[0]);
6910
+ const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
6911
+ const points = [];
6912
+ for (const kf of kfs) {
6913
+ const v = kfValue(kf);
6914
+ const tr = v == null ? void 0 : v.translate;
6915
+ if (!tr || tr.length < 2) return void 0;
6916
+ const parts = Object.keys(v);
6917
+ if (parts.some((p) => p !== "translate" && p !== "origin")) return void 0;
6918
+ const o = (_b = v == null ? void 0 : v.origin) != null ? _b : [0, 0];
6919
+ if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
6920
+ points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
6921
+ }
6922
+ if (!kfs.some((kf) => kfTangentIn(kf) || kfTangentOut(kf))) return void 0;
6923
+ let d = "M" + fmt2(points[0][0]) + "," + fmt2(points[0][1]);
6924
+ const segLens = [];
6925
+ for (let i = 0; i < points.length - 1; i++) {
6926
+ const p0 = points[i], p1 = points[i + 1];
6927
+ const to = (_c = kfTangentOut(kfs[i])) != null ? _c : [0, 0];
6928
+ const ti = (_d = kfTangentIn(kfs[i + 1])) != null ? _d : [0, 0];
6929
+ const c1 = [p0[0] + to[0], p0[1] + to[1]];
6930
+ const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
6931
+ d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
6932
+ segLens.push(cubicLength(p0, c1, c2, p1));
6933
+ }
6934
+ const total = segLens.reduce((a, b) => a + b, 0);
6935
+ if (!(total > 0)) return void 0;
6936
+ const distanceKfs = [];
6937
+ let cum = 0;
6938
+ for (let i = 0; i < kfs.length; i++) {
6939
+ if (i > 0) cum += segLens[i - 1];
6940
+ const out = { t: kfTime(kfs[i]), v: cum / total };
6941
+ const e = kfEasing(kfs[i]);
6942
+ if (e !== void 0) out.e = e;
6943
+ distanceKfs.push(out);
6944
+ }
6945
+ return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor };
6946
+ }
6947
+ function materialiseOffsetPathsInTree(root) {
6948
+ const walk = (node) => {
6949
+ var _a;
6950
+ let out = node;
6951
+ const anim = node.animate;
6952
+ const transform = anim == null ? void 0 : anim["transform"];
6953
+ if (transform) {
6954
+ const built = buildOffsetPath(transform);
6955
+ if (built) {
6956
+ const newAnimate = __spreadValues2({}, anim);
6957
+ delete newAnimate["transform"];
6958
+ const distance = { keyframes: built.distanceKfs };
6959
+ if (transform.loop !== void 0) distance.loop = transform.loop;
6960
+ newAnimate["offsetDistance"] = distance;
6961
+ const staticTr = node.transform;
6962
+ let newTransform = staticTr;
6963
+ if (staticTr && typeof staticTr === "object") {
6964
+ const t = __spreadValues2({}, staticTr);
6965
+ delete t["translate"];
6966
+ delete t["origin"];
6967
+ newTransform = Object.keys(t).length ? t : void 0;
6968
+ }
6969
+ out = __spreadProps2(__spreadValues2({}, node), {
6970
+ animate: newAnimate,
6971
+ style: __spreadProps2(__spreadValues2({}, node.style), {
6972
+ offsetPath: "path('" + built.pathStr + "')",
6973
+ offsetAnchor: fmt2(built.anchor[0]) + "px " + fmt2(built.anchor[1]) + "px",
6974
+ offsetRotate: built.autoOrient ? "auto" : "0deg",
6975
+ offsetDistance: "0%"
6976
+ })
6977
+ });
6978
+ if (newTransform !== void 0) out.transform = newTransform;
6979
+ else delete out.transform;
6980
+ }
6981
+ }
6982
+ if ((_a = out.children) == null ? void 0 : _a.length) {
6983
+ const children = out.children.map(walk);
6984
+ if (children.some((c, i) => c !== out.children[i])) out = __spreadProps2(__spreadValues2({}, out), { children });
6985
+ }
6986
+ return out;
6987
+ };
6988
+ return walk(root);
6989
+ }
6841
6990
  function materialiseAllInTree(doc, engine, opts) {
6842
6991
  var _a, _b;
6843
6992
  let root = applyPlayerEffects(doc).root;
6993
+ root = materialiseOffsetPathsInTree(root);
6844
6994
  const duration = (_b = (_a = getAnimatorConfig(root)) == null ? void 0 : _a.duration) != null ? _b : DEFAULT_DURATION_MS;
6845
6995
  root = materialiseInternalLoopsInTree(root, duration);
6846
6996
  if (engine === PxAnimatorEngine.waapi) {
@@ -7336,6 +7486,8 @@ var PixodeskAnimatorReact = (() => {
7336
7486
  } else if (propName === "d") {
7337
7487
  const paths = value && typeof value === "object" && Array.isArray(value.paths) ? value.paths : [];
7338
7488
  cssValue = 'path("' + paths.map((bz) => bezierToSvgPath(bz, true)).join("") + '")';
7489
+ } else if (PCT_BASED_ATTR_NAMES.has(propName) && typeof value === "number") {
7490
+ cssValue = value * 100 + "%";
7339
7491
  } else {
7340
7492
  cssValue = "" + value;
7341
7493
  }