@pixodesk/svg-animator-core 1.0.44 → 1.0.46
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 +12 -0
- package/dist/{PxDocumentDiagnostic-n8yiyL0k.d.cts → PxDocumentDiagnostic-DX8w42-I.d.cts} +385 -228
- package/dist/{PxDocumentDiagnostic-n8yiyL0k.d.ts → PxDocumentDiagnostic-DX8w42-I.d.ts} +385 -228
- package/dist/{chunk-EFQLDGFY.js → chunk-37OFJ3RX.js} +2100 -134
- package/dist/chunk-37OFJ3RX.js.map +1 -0
- package/dist/chunk-K2732IVS.min.js +1 -0
- package/dist/index.cjs +250 -108
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +12 -1877
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/internal.cjs +3344 -213
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.cts +61 -5
- package/dist/internal.d.ts +61 -5
- package/dist/internal.js +55 -1
- package/dist/internal.js.map +1 -1
- package/dist/internal.min.cjs +1 -1
- package/dist/internal.min.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-EFQLDGFY.js.map +0 -1
- package/dist/chunk-YWBPS6E4.min.js +0 -1
package/dist/internal.cjs
CHANGED
|
@@ -55,6 +55,7 @@ __export(internal_exports, {
|
|
|
55
55
|
PX_COLOR_ATTR_NAMES: () => PX_COLOR_ATTR_NAMES,
|
|
56
56
|
PX_CSS_ONLY_STYLE_PROPS: () => PX_CSS_ONLY_STYLE_PROPS,
|
|
57
57
|
PX_DEFAULT_DURATION_MS: () => PX_DEFAULT_DURATION_MS,
|
|
58
|
+
PX_DEFAULT_ITERATIONS: () => PX_DEFAULT_ITERATIONS,
|
|
58
59
|
PX_DISALLOWED_SVG_TAGS_LOWER: () => PX_DISALLOWED_SVG_TAGS_LOWER,
|
|
59
60
|
PX_LOOP_JUMP_SHIFT_MS: () => PX_LOOP_JUMP_SHIFT_MS,
|
|
60
61
|
PX_PCT_BASED_ATTR_NAMES: () => PX_PCT_BASED_ATTR_NAMES,
|
|
@@ -85,7 +86,9 @@ __export(internal_exports, {
|
|
|
85
86
|
materializeMotionPathInPropAnim: () => materializeMotionPathInPropAnim,
|
|
86
87
|
mergeStaticTransformIntoAnimDef: () => mergeStaticTransformIntoAnimDef,
|
|
87
88
|
planSchemaRelease: () => planSchemaRelease,
|
|
89
|
+
prepareDocumentForRender: () => prepareDocumentForRender,
|
|
88
90
|
releaseLogProblems: () => releaseLogProblems,
|
|
91
|
+
renderPxTree: () => renderPxTree,
|
|
89
92
|
reportDocumentDiagnostics: () => reportDocumentDiagnostics,
|
|
90
93
|
reverseEasing: () => reverseEasing,
|
|
91
94
|
sanitizeAttributeValue: () => sanitizeAttributeValue,
|
|
@@ -113,19 +116,31 @@ function pathStr(path) {
|
|
|
113
116
|
return result;
|
|
114
117
|
}
|
|
115
118
|
var Base = class {
|
|
119
|
+
/** Structural schemas (objects, arrays, unions of objects…) pass `false`: they state no scalar default. */
|
|
120
|
+
constructor(_statesDefault) {
|
|
121
|
+
this._statesDefault = _statesDefault;
|
|
122
|
+
}
|
|
116
123
|
_canSanitize(raw) {
|
|
117
124
|
return this.isValid(raw);
|
|
118
125
|
}
|
|
126
|
+
/** A REQUIRED field is never absent; its default is the repair value. */
|
|
127
|
+
absentDefault() {
|
|
128
|
+
return this._default;
|
|
129
|
+
}
|
|
119
130
|
optional() {
|
|
120
131
|
return new Optional(this);
|
|
121
132
|
}
|
|
122
133
|
};
|
|
123
134
|
var Optional = class extends Base {
|
|
124
135
|
constructor(inner) {
|
|
125
|
-
super();
|
|
136
|
+
super(inner._statesDefault);
|
|
126
137
|
this.inner = inner;
|
|
127
138
|
this._default = void 0;
|
|
128
139
|
}
|
|
140
|
+
/** Absent means the inner schema's STATED default — or nothing at all when it states none. */
|
|
141
|
+
absentDefault() {
|
|
142
|
+
return this.inner._statesDefault ? this.inner._default : void 0;
|
|
143
|
+
}
|
|
129
144
|
sanitize(raw) {
|
|
130
145
|
if (raw === void 0 || raw === null) return void 0;
|
|
131
146
|
return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
|
|
@@ -139,8 +154,8 @@ var Optional = class extends Base {
|
|
|
139
154
|
}
|
|
140
155
|
};
|
|
141
156
|
var Str = class extends Base {
|
|
142
|
-
constructor(_default
|
|
143
|
-
super();
|
|
157
|
+
constructor(_default, statesDefault) {
|
|
158
|
+
super(statesDefault);
|
|
144
159
|
this._default = _default;
|
|
145
160
|
}
|
|
146
161
|
sanitize(raw) {
|
|
@@ -153,8 +168,8 @@ var Str = class extends Base {
|
|
|
153
168
|
}
|
|
154
169
|
};
|
|
155
170
|
var Num = class extends Base {
|
|
156
|
-
constructor(_default
|
|
157
|
-
super();
|
|
171
|
+
constructor(_default, statesDefault) {
|
|
172
|
+
super(statesDefault);
|
|
158
173
|
this._default = _default;
|
|
159
174
|
}
|
|
160
175
|
sanitize(raw) {
|
|
@@ -167,8 +182,8 @@ var Num = class extends Base {
|
|
|
167
182
|
}
|
|
168
183
|
};
|
|
169
184
|
var Bool = class extends Base {
|
|
170
|
-
constructor(_default
|
|
171
|
-
super();
|
|
185
|
+
constructor(_default, statesDefault) {
|
|
186
|
+
super(statesDefault);
|
|
172
187
|
this._default = _default;
|
|
173
188
|
}
|
|
174
189
|
sanitize(raw) {
|
|
@@ -181,8 +196,9 @@ var Bool = class extends Base {
|
|
|
181
196
|
}
|
|
182
197
|
};
|
|
183
198
|
var Literal = class extends Base {
|
|
199
|
+
/** A literal IS its own value: absent means it. */
|
|
184
200
|
constructor(value) {
|
|
185
|
-
super();
|
|
201
|
+
super(true);
|
|
186
202
|
this.value = value;
|
|
187
203
|
this._default = value;
|
|
188
204
|
}
|
|
@@ -196,8 +212,8 @@ var Literal = class extends Base {
|
|
|
196
212
|
}
|
|
197
213
|
};
|
|
198
214
|
var Enum = class extends Base {
|
|
199
|
-
constructor(values, defaultVal) {
|
|
200
|
-
super();
|
|
215
|
+
constructor(values, defaultVal, statesDefault) {
|
|
216
|
+
super(statesDefault);
|
|
201
217
|
this.values = values;
|
|
202
218
|
this._default = defaultVal != null ? defaultVal : values[0];
|
|
203
219
|
}
|
|
@@ -212,8 +228,8 @@ var Enum = class extends Base {
|
|
|
212
228
|
};
|
|
213
229
|
var UNION_MEMBER_ERROR_LIMIT = 4;
|
|
214
230
|
var Union = class extends Base {
|
|
215
|
-
constructor(schemas, defaultVal) {
|
|
216
|
-
super();
|
|
231
|
+
constructor(schemas, defaultVal, statesDefault) {
|
|
232
|
+
super(statesDefault);
|
|
217
233
|
this.schemas = schemas;
|
|
218
234
|
/** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Union from Tuple. */
|
|
219
235
|
this._kind = "union";
|
|
@@ -267,7 +283,7 @@ var Union = class extends Base {
|
|
|
267
283
|
var DiscriminatedUnion = class extends Base {
|
|
268
284
|
constructor(_key, _schemas, defaultVal) {
|
|
269
285
|
var _a2;
|
|
270
|
-
super();
|
|
286
|
+
super(false);
|
|
271
287
|
this._key = _key;
|
|
272
288
|
this._schemas = _schemas;
|
|
273
289
|
/** Structural tag read by {@link describeSchema}. */
|
|
@@ -307,13 +323,19 @@ var DiscriminatedUnion = class extends Base {
|
|
|
307
323
|
return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
|
|
308
324
|
}
|
|
309
325
|
};
|
|
326
|
+
function statedDefaults(shape) {
|
|
327
|
+
const out = {};
|
|
328
|
+
for (const key of Object.keys(shape)) if (shape[key]._statesDefault) out[key] = shape[key].absentDefault();
|
|
329
|
+
return Object.freeze(out);
|
|
330
|
+
}
|
|
310
331
|
var Obj = class extends Base {
|
|
311
332
|
constructor(_shape) {
|
|
312
|
-
super();
|
|
333
|
+
super(false);
|
|
313
334
|
this._shape = _shape;
|
|
314
335
|
const d = {};
|
|
315
336
|
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
316
337
|
this._default = d;
|
|
338
|
+
this.defaults = statedDefaults(_shape);
|
|
317
339
|
}
|
|
318
340
|
sanitize(raw) {
|
|
319
341
|
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
@@ -355,12 +377,13 @@ var Obj = class extends Base {
|
|
|
355
377
|
};
|
|
356
378
|
var OpenObj = class extends Base {
|
|
357
379
|
constructor(_shape, _openSchema) {
|
|
358
|
-
super();
|
|
380
|
+
super(false);
|
|
359
381
|
this._shape = _shape;
|
|
360
382
|
this._openSchema = _openSchema;
|
|
361
383
|
const d = {};
|
|
362
384
|
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
363
385
|
this._default = d;
|
|
386
|
+
this.defaults = statedDefaults(_shape);
|
|
364
387
|
}
|
|
365
388
|
sanitize(raw) {
|
|
366
389
|
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
@@ -405,7 +428,7 @@ var OpenObj = class extends Base {
|
|
|
405
428
|
};
|
|
406
429
|
var Arr = class extends Base {
|
|
407
430
|
constructor(item) {
|
|
408
|
-
super();
|
|
431
|
+
super(false);
|
|
409
432
|
this.item = item;
|
|
410
433
|
this._default = [];
|
|
411
434
|
}
|
|
@@ -437,7 +460,7 @@ var Arr = class extends Base {
|
|
|
437
460
|
};
|
|
438
461
|
var Rec = class extends Base {
|
|
439
462
|
constructor(value) {
|
|
440
|
-
super();
|
|
463
|
+
super(false);
|
|
441
464
|
this.value = value;
|
|
442
465
|
/** Structural tag read by {@link describeSchema}. */
|
|
443
466
|
this._kind = "record";
|
|
@@ -471,7 +494,7 @@ var Rec = class extends Base {
|
|
|
471
494
|
};
|
|
472
495
|
var Any = class extends Base {
|
|
473
496
|
constructor() {
|
|
474
|
-
super(
|
|
497
|
+
super(false);
|
|
475
498
|
this._default = void 0;
|
|
476
499
|
}
|
|
477
500
|
sanitize(raw) {
|
|
@@ -486,7 +509,7 @@ var Any = class extends Base {
|
|
|
486
509
|
};
|
|
487
510
|
var Defined = class extends Base {
|
|
488
511
|
constructor() {
|
|
489
|
-
super(
|
|
512
|
+
super(false);
|
|
490
513
|
this._default = void 0;
|
|
491
514
|
}
|
|
492
515
|
sanitize(raw) {
|
|
@@ -503,7 +526,7 @@ var Defined = class extends Base {
|
|
|
503
526
|
};
|
|
504
527
|
var Lazy = class extends Base {
|
|
505
528
|
constructor(fn, _default) {
|
|
506
|
-
super();
|
|
529
|
+
super(false);
|
|
507
530
|
this.fn = fn;
|
|
508
531
|
this._default = _default;
|
|
509
532
|
this.resolved = null;
|
|
@@ -524,7 +547,7 @@ var Lazy = class extends Base {
|
|
|
524
547
|
};
|
|
525
548
|
var Tuple = class extends Base {
|
|
526
549
|
constructor(schemas) {
|
|
527
|
-
super();
|
|
550
|
+
super(false);
|
|
528
551
|
this.schemas = schemas;
|
|
529
552
|
/** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Tuple from Union. */
|
|
530
553
|
this._kind = "tuple";
|
|
@@ -575,22 +598,29 @@ function describeSchema(schema) {
|
|
|
575
598
|
if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
|
|
576
599
|
return { kind: "leaf" };
|
|
577
600
|
}
|
|
601
|
+
function string(defaultVal) {
|
|
602
|
+
return defaultVal === void 0 ? new Str("", false) : new Str(defaultVal, true);
|
|
603
|
+
}
|
|
604
|
+
function number(defaultVal) {
|
|
605
|
+
return defaultVal === void 0 ? new Num(0, false) : new Num(defaultVal, true);
|
|
606
|
+
}
|
|
607
|
+
function boolean(defaultVal) {
|
|
608
|
+
return defaultVal === void 0 ? new Bool(false, false) : new Bool(defaultVal, true);
|
|
609
|
+
}
|
|
610
|
+
function oneOf(values, defaultVal) {
|
|
611
|
+
return defaultVal === void 0 ? new Enum(values, void 0, false) : new Enum(values, defaultVal, true);
|
|
612
|
+
}
|
|
613
|
+
function unionOf(schemas, defaultVal) {
|
|
614
|
+
return defaultVal === void 0 ? new Union(schemas, void 0, false) : new Union(schemas, defaultVal, true);
|
|
615
|
+
}
|
|
578
616
|
var px = {
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
/** Matches a boolean. Default: false or provided value. */
|
|
584
|
-
boolean: (defaultVal = false) => new Bool(defaultVal),
|
|
585
|
-
/** Matches one exact primitive value; its default is the value itself. */
|
|
617
|
+
string,
|
|
618
|
+
number,
|
|
619
|
+
boolean,
|
|
620
|
+
/** Matches one exact primitive value; absent means the value itself. */
|
|
586
621
|
literal: (value) => new Literal(value),
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
/**
|
|
590
|
-
* Returns the first schema whose isValid passes.
|
|
591
|
-
* TypeScript infers the union of all member types automatically.
|
|
592
|
-
*/
|
|
593
|
-
union: (schemas, defaultVal) => new Union(schemas, defaultVal),
|
|
622
|
+
enum: oneOf,
|
|
623
|
+
union: unionOf,
|
|
594
624
|
/**
|
|
595
625
|
* Discriminated union — reads `raw[key]`, finds the member schema whose
|
|
596
626
|
* literal at `key` matches, then delegates sanitize/isValid to that member.
|
|
@@ -598,7 +628,8 @@ var px = {
|
|
|
598
628
|
* TypeScript infers the union of all member types automatically.
|
|
599
629
|
*/
|
|
600
630
|
discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
|
|
601
|
-
/** Typed object — unknown keys are stripped. Required fields fall back to their default.
|
|
631
|
+
/** Typed object — unknown keys are stripped. Required fields fall back to their default.
|
|
632
|
+
* Its `defaults` say what each stated field means when a document leaves it out. */
|
|
602
633
|
object: (shape) => new Obj(shape),
|
|
603
634
|
/**
|
|
604
635
|
* Open object — validates known keys; passes unknown keys through as-is,
|
|
@@ -711,13 +742,19 @@ var PxTimelineEngine = {
|
|
|
711
742
|
var PxTimelineEngineSetting = __spreadProps(__spreadValues({}, PxTimelineEngine), {
|
|
712
743
|
auto: "auto"
|
|
713
744
|
});
|
|
745
|
+
function resolveTimelineEngine(engine) {
|
|
746
|
+
return engine === PxTimelineEngineSetting.js ? PxTimelineEngine.js : PxTimelineEngine.native;
|
|
747
|
+
}
|
|
714
748
|
var PX_TRIGGER_DEFAULTS = {
|
|
715
749
|
start: "load",
|
|
716
750
|
offScreen: "pause",
|
|
717
751
|
mouseOut: "continue",
|
|
718
752
|
visibilityThreshold: 0.5,
|
|
719
|
-
visibilityDebounce: 150
|
|
753
|
+
visibilityDebounce: 150,
|
|
754
|
+
finish: "hold"
|
|
720
755
|
};
|
|
756
|
+
var PX_DEFAULT_DURATION_MS = 1e3;
|
|
757
|
+
var PX_DEFAULT_ITERATIONS = 1;
|
|
721
758
|
var PxLoopRepeatAt = {
|
|
722
759
|
/** Segment from the START; the repetition runs BEFORE the first keyframe
|
|
723
760
|
* (intro loops that play until the main timeline begins). */
|
|
@@ -767,6 +804,16 @@ var PxStrokeTrimSubPaths = {
|
|
|
767
804
|
var PX_TEXT_CONTENT_ATTR = "textContent";
|
|
768
805
|
var CLASS_ATTR = "class";
|
|
769
806
|
var TRANSFORM_ATTR = "transform";
|
|
807
|
+
var OFFSET_DISTANCE_ATTR = "offsetDistance";
|
|
808
|
+
var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
|
|
809
|
+
"type",
|
|
810
|
+
"children",
|
|
811
|
+
"animator",
|
|
812
|
+
"meta",
|
|
813
|
+
"animate",
|
|
814
|
+
"effects",
|
|
815
|
+
PX_TEXT_CONTENT_ATTR
|
|
816
|
+
]);
|
|
770
817
|
var TRANSFORM_PART = {
|
|
771
818
|
translate: "translate",
|
|
772
819
|
rotate: "rotate",
|
|
@@ -847,6 +894,16 @@ function flattenAnimatorTimeline(cfg) {
|
|
|
847
894
|
flattenMemo.set(cfg, flat);
|
|
848
895
|
return flat;
|
|
849
896
|
}
|
|
897
|
+
function getDefinitions(doc) {
|
|
898
|
+
var _a2;
|
|
899
|
+
if (!doc) return void 0;
|
|
900
|
+
return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
|
|
901
|
+
}
|
|
902
|
+
function getBindings(doc) {
|
|
903
|
+
var _a2;
|
|
904
|
+
if (!doc) return void 0;
|
|
905
|
+
return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.bindings;
|
|
906
|
+
}
|
|
850
907
|
|
|
851
908
|
// src/version/PxSchemaVersion.ts
|
|
852
909
|
var PX_WIRE_SCHEMA_VERSION = "1.2";
|
|
@@ -910,15 +967,15 @@ var keyframeTangentIn = (kf) => anyKf(kf).tangentIn;
|
|
|
910
967
|
var keyframeTangentOut = (kf) => anyKf(kf).tangentOut;
|
|
911
968
|
var PxLoopSchema = implementsInterface()(px.object({
|
|
912
969
|
segmentCount: px.number().optional(),
|
|
913
|
-
repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
|
|
914
|
-
direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
|
|
970
|
+
repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end], PxLoopRepeatAt.end).optional(),
|
|
971
|
+
direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate], PxLoopDirection.normal).optional()
|
|
915
972
|
}));
|
|
916
973
|
var PxPropertyAnimationSchema = implementsInterface()(px.object({
|
|
917
974
|
value: PxKeyframeValueSchema.optional(),
|
|
918
975
|
keyframes: px.array(PxKeyframeSchema).optional(),
|
|
919
976
|
loop: px.union([PxLoopSchema, px.boolean()]).optional(),
|
|
920
977
|
autoOrient: px.boolean().optional(),
|
|
921
|
-
alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
|
|
978
|
+
alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath], PxAlongPathMode.sampled).optional()
|
|
922
979
|
}));
|
|
923
980
|
var PxTransformPartsSchema = implementsInterface()(px.object({
|
|
924
981
|
translate: px.tuple([px.number(), px.number()]).optional(),
|
|
@@ -948,9 +1005,9 @@ var PxTriggerSchema = implementsInterface()(px.object({
|
|
|
948
1005
|
// What happens after a NATURAL finish — `'hold'` (default: keep the end state per
|
|
949
1006
|
// `fill`) or `'reset'` (snap back to the start state). One of four occasion keys
|
|
950
1007
|
// (`start`, `offScreen`, `mouseOut`, `finish`), all named the same way.
|
|
951
|
-
finish: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
|
|
952
|
-
visibilityThreshold: px.number().optional(),
|
|
953
|
-
visibilityDebounce: px.number().optional()
|
|
1008
|
+
finish: px.enum([PxFinishAction.hold, PxFinishAction.reset], PX_TRIGGER_DEFAULTS.finish).optional(),
|
|
1009
|
+
visibilityThreshold: px.number(PX_TRIGGER_DEFAULTS.visibilityThreshold).optional(),
|
|
1010
|
+
visibilityDebounce: px.number(PX_TRIGGER_DEFAULTS.visibilityDebounce).optional()
|
|
954
1011
|
}));
|
|
955
1012
|
var PxGlyphSchema = implementsInterface()(px.object({
|
|
956
1013
|
width: px.number(),
|
|
@@ -976,7 +1033,7 @@ var PxScrollRangePointSchema = implementsInterface()(px.object({
|
|
|
976
1033
|
PxScrollPhase.exit,
|
|
977
1034
|
PxScrollPhase.entryCrossing,
|
|
978
1035
|
PxScrollPhase.exitCrossing
|
|
979
|
-
]).optional(),
|
|
1036
|
+
], PxScrollPhase.cover).optional(),
|
|
980
1037
|
fraction: px.number().optional()
|
|
981
1038
|
}));
|
|
982
1039
|
var PxScrollRangeSchema = px.object({
|
|
@@ -984,37 +1041,37 @@ var PxScrollRangeSchema = px.object({
|
|
|
984
1041
|
end: PxScrollRangePointSchema.optional()
|
|
985
1042
|
});
|
|
986
1043
|
var PxScrollSchema = implementsInterface()(px.object({
|
|
987
|
-
kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
|
|
988
|
-
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
|
|
989
|
-
source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
|
|
1044
|
+
kind: px.enum([PxScrollKind.view, PxScrollKind.scroll], PxScrollKind.view).optional(),
|
|
1045
|
+
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
|
|
1046
|
+
source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
|
|
990
1047
|
// Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
|
|
991
1048
|
subject: px.string().optional(),
|
|
992
1049
|
smoothing: px.number().optional(),
|
|
993
|
-
pin: px.boolean().optional(),
|
|
994
|
-
pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
|
|
1050
|
+
pin: px.boolean(false).optional(),
|
|
1051
|
+
pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
|
|
995
1052
|
pinOffset: px.number().optional(),
|
|
996
1053
|
pinDistance: px.number().optional(),
|
|
997
1054
|
range: PxScrollRangeSchema.optional()
|
|
998
1055
|
}));
|
|
999
1056
|
var PxTimelinePinSchema = implementsInterface()(px.object({
|
|
1000
|
-
align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
|
|
1057
|
+
align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom], PxPinAlign.top).optional(),
|
|
1001
1058
|
offset: px.number().optional(),
|
|
1002
1059
|
distance: px.number().optional()
|
|
1003
1060
|
}));
|
|
1004
|
-
var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js]).optional();
|
|
1061
|
+
var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js], PxTimelineEngineSetting.auto).optional();
|
|
1005
1062
|
var PxTimeTimelineSchema = implementsInterface()(px.object({
|
|
1006
1063
|
type: px.literal("time").optional(),
|
|
1007
1064
|
engine: PxTimelineEngineSchema,
|
|
1008
1065
|
frameRate: px.number().optional(),
|
|
1009
1066
|
// §2.8: duration is a property of the TIMELINE — how long one pass takes.
|
|
1010
|
-
duration: px.number().optional(),
|
|
1067
|
+
duration: px.number(PX_DEFAULT_DURATION_MS).optional(),
|
|
1011
1068
|
trigger: PxTriggerSchema.optional(),
|
|
1012
|
-
delay: px.number().optional(),
|
|
1013
|
-
iterations: px.union([px.number(), px.literal("infinite")]).optional(),
|
|
1069
|
+
delay: px.number(0).optional(),
|
|
1070
|
+
iterations: px.union([px.number(PX_DEFAULT_ITERATIONS), px.literal("infinite")], PX_DEFAULT_ITERATIONS).optional(),
|
|
1014
1071
|
// `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
|
|
1015
1072
|
// — never `fill`, which is paint everywhere else in the format.
|
|
1016
|
-
fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
|
|
1017
|
-
direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
|
|
1073
|
+
fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none], PxFillMode.forwards).optional(),
|
|
1074
|
+
direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse], PxPlaybackDirection.normal).optional()
|
|
1018
1075
|
}));
|
|
1019
1076
|
var scrollishTimelineShape = {
|
|
1020
1077
|
// §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
|
|
@@ -1025,8 +1082,8 @@ var scrollishTimelineShape = {
|
|
|
1025
1082
|
iterations: px.number().optional(),
|
|
1026
1083
|
engine: PxTimelineEngineSchema,
|
|
1027
1084
|
frameRate: px.number().optional(),
|
|
1028
|
-
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
|
|
1029
|
-
source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
|
|
1085
|
+
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y], PxScrollAxis.block).optional(),
|
|
1086
|
+
source: px.enum([PxScrollSource.nearest, PxScrollSource.root], PxScrollSource.nearest).optional(),
|
|
1030
1087
|
subject: px.string().optional(),
|
|
1031
1088
|
// 'parent' | 'scroller' | any CSS selector
|
|
1032
1089
|
smoothing: px.number().optional(),
|
|
@@ -1106,9 +1163,10 @@ var PxRepeaterEffectSchema = implementsInterface()(px.object({
|
|
|
1106
1163
|
}));
|
|
1107
1164
|
var PxMaskedByEffectSchema = implementsInterface()(px.object({
|
|
1108
1165
|
source: px.string().optional(),
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1166
|
+
// SVG's own initial values — what a <mask> does when the attribute is not there.
|
|
1167
|
+
maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha], PxMaskType.luminance).optional(),
|
|
1168
|
+
maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
|
|
1169
|
+
maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.userSpaceOnUse).optional(),
|
|
1112
1170
|
x: px.number().optional(),
|
|
1113
1171
|
y: px.number().optional(),
|
|
1114
1172
|
width: px.number().optional(),
|
|
@@ -1120,7 +1178,7 @@ var PxClipPathEffectSchema = implementsInterface()(px.object({
|
|
|
1120
1178
|
var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
|
|
1121
1179
|
offset: PxAnimatableNumberSchema.optional(),
|
|
1122
1180
|
range: PxAnimatableVec2Schema.optional(),
|
|
1123
|
-
subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
|
|
1181
|
+
subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined], PxStrokeTrimSubPaths.separate).optional()
|
|
1124
1182
|
}));
|
|
1125
1183
|
var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
1126
1184
|
start: px.number().optional(),
|
|
@@ -1152,17 +1210,20 @@ var PxFillGradientEffectSchema = implementsInterface()(px.object({
|
|
|
1152
1210
|
radius: PxAnimatableNumberSchema.optional(),
|
|
1153
1211
|
focal: PxAnimatableVec2Schema.optional(),
|
|
1154
1212
|
stops: PxAnimatableGradientStopsSchema.optional(),
|
|
1155
|
-
|
|
1156
|
-
|
|
1213
|
+
// SVG's own initial values — what a gradient does when the attribute is not there.
|
|
1214
|
+
gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox], PxUnits.objectBoundingBox).optional(),
|
|
1215
|
+
spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat], PxGradientSpreadMethod.pad).optional(),
|
|
1157
1216
|
gradientTransform: px.string().optional()
|
|
1158
1217
|
}));
|
|
1159
1218
|
var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
|
|
1160
1219
|
var PxTextPathEffectSchema = implementsInterface()(px.object({
|
|
1161
1220
|
pathData: px.string(),
|
|
1162
|
-
pathOverflow
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1221
|
+
// `extend` is what an omitted pathOverflow means (glyphs continue along the tangent); the
|
|
1222
|
+
// other three are SVG's own initial values for the native <textPath> attributes.
|
|
1223
|
+
pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend], PxPathOverflow.extend).optional(),
|
|
1224
|
+
lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs], PxLengthAdjust.spacing).optional(),
|
|
1225
|
+
method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch], PxTextPathMethod.align).optional(),
|
|
1226
|
+
spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact], PxTextPathSpacing.exact).optional(),
|
|
1166
1227
|
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1167
1228
|
textLength: PxAnimatableNumberSchema.optional()
|
|
1168
1229
|
}));
|
|
@@ -1407,6 +1468,11 @@ function interpolateBezier(path1, path2, progress) {
|
|
|
1407
1468
|
}
|
|
1408
1469
|
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
1409
1470
|
}
|
|
1471
|
+
function remap(value, inMin, inMax, outMin, outMax) {
|
|
1472
|
+
if (inMax === inMin) return outMin;
|
|
1473
|
+
const t = (value - inMin) / (inMax - inMin);
|
|
1474
|
+
return outMin + t * (outMax - outMin);
|
|
1475
|
+
}
|
|
1410
1476
|
function solveCubicBezierX(p1x, p2x, x) {
|
|
1411
1477
|
if (x <= 0) return 0;
|
|
1412
1478
|
if (x >= 1) return 1;
|
|
@@ -1511,6 +1577,43 @@ function toRGBA(color) {
|
|
|
1511
1577
|
const b = Math.round(color[2] * 255);
|
|
1512
1578
|
return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
|
|
1513
1579
|
}
|
|
1580
|
+
function parseRgba(s) {
|
|
1581
|
+
var _a2;
|
|
1582
|
+
const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
|
|
1583
|
+
if (!inner) throw new Error("Invalid rgb/rgba format");
|
|
1584
|
+
const parts = inner.split(",").map((v) => +v.trim());
|
|
1585
|
+
return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
|
|
1586
|
+
}
|
|
1587
|
+
function parseHex(s) {
|
|
1588
|
+
const hex = s.slice(1);
|
|
1589
|
+
const isShort = hex.length <= 4;
|
|
1590
|
+
const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
|
|
1591
|
+
const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
|
|
1592
|
+
const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
|
|
1593
|
+
const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
|
|
1594
|
+
const result = [
|
|
1595
|
+
parseInt(r, 16) / 255,
|
|
1596
|
+
parseInt(g, 16) / 255,
|
|
1597
|
+
parseInt(b, 16) / 255
|
|
1598
|
+
];
|
|
1599
|
+
if (a !== null) {
|
|
1600
|
+
result.push(parseInt(a, 16) / 255);
|
|
1601
|
+
}
|
|
1602
|
+
return result;
|
|
1603
|
+
}
|
|
1604
|
+
function parseColor(s) {
|
|
1605
|
+
if (!s) return void 0;
|
|
1606
|
+
if (Array.isArray(s)) return s;
|
|
1607
|
+
if (typeof s !== "string") return void 0;
|
|
1608
|
+
if (s.startsWith("#")) {
|
|
1609
|
+
return parseHex(s);
|
|
1610
|
+
} else if (s.startsWith("rgb")) {
|
|
1611
|
+
return parseRgba(s);
|
|
1612
|
+
} else {
|
|
1613
|
+
console.warn("Unsupported color format: " + s);
|
|
1614
|
+
}
|
|
1615
|
+
return void 0;
|
|
1616
|
+
}
|
|
1514
1617
|
var PX_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
1515
1618
|
var PX_TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
1516
1619
|
var PX_PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
@@ -1567,10 +1670,12 @@ function parseTransformParts(str2) {
|
|
|
1567
1670
|
return Object.keys(out).length ? out : void 0;
|
|
1568
1671
|
}
|
|
1569
1672
|
var PX_STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1570
|
-
var PX_DEFAULT_DURATION_MS = 1e3;
|
|
1571
1673
|
function kebabToCamelCaseWord(kebab) {
|
|
1572
1674
|
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
1573
1675
|
}
|
|
1676
|
+
function isCamelCaseWord(word) {
|
|
1677
|
+
return !word.includes("-") && /[a-z][A-Z]/.test(word);
|
|
1678
|
+
}
|
|
1574
1679
|
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
1575
1680
|
// Transform/positioning
|
|
1576
1681
|
"viewBox",
|
|
@@ -1726,6 +1831,38 @@ function invertEasing(easing) {
|
|
|
1726
1831
|
return cubicBezier(flipped);
|
|
1727
1832
|
}
|
|
1728
1833
|
|
|
1834
|
+
// src/animation/PxStaticTransformMerge.ts
|
|
1835
|
+
function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
|
|
1836
|
+
if (!animDef) return animDef;
|
|
1837
|
+
const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
|
|
1838
|
+
if (!staticParts || !Object.keys(staticParts).length) return animDef;
|
|
1839
|
+
const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
|
|
1840
|
+
const transformAnim = animDef[TRANSFORM_ATTR];
|
|
1841
|
+
if (transformAnim && typeof transformAnim === "object") {
|
|
1842
|
+
const anim = transformAnim;
|
|
1843
|
+
if (Array.isArray(anim.keyframes)) {
|
|
1844
|
+
const out = __spreadProps(__spreadValues({}, anim), {
|
|
1845
|
+
keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
|
|
1846
|
+
});
|
|
1847
|
+
if (out.value !== void 0) out.value = mergeKfValue(out.value);
|
|
1848
|
+
return __spreadProps(__spreadValues({}, animDef), { transform: out });
|
|
1849
|
+
}
|
|
1850
|
+
return animDef;
|
|
1851
|
+
}
|
|
1852
|
+
const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
|
|
1853
|
+
if (channels.length !== 1) return animDef;
|
|
1854
|
+
const ch = channels[0];
|
|
1855
|
+
const chAnim = animDef[ch];
|
|
1856
|
+
if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
|
|
1857
|
+
const lifted = __spreadProps(__spreadValues({}, chAnim), {
|
|
1858
|
+
keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
|
|
1859
|
+
});
|
|
1860
|
+
if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
|
|
1861
|
+
const rest = __spreadValues({}, animDef);
|
|
1862
|
+
delete rest[ch];
|
|
1863
|
+
return __spreadProps(__spreadValues({}, rest), { transform: lifted });
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1729
1866
|
// src/materialize/PxMotionPath.ts
|
|
1730
1867
|
function getKfTranslate(kf) {
|
|
1731
1868
|
const v = keyframeValue(kf);
|
|
@@ -1777,6 +1914,33 @@ function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
|
1777
1914
|
byNext.set(nextKf, entry);
|
|
1778
1915
|
return entry;
|
|
1779
1916
|
}
|
|
1917
|
+
function evaluateMotionPathSegment(prevKf, nextKf, prevPos, nextPos, localProgress, autoOrient) {
|
|
1918
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
1919
|
+
const t = seg.totalArc === 0 ? localProgress : tFromArcFraction(seg.lut, localProgress);
|
|
1920
|
+
const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1921
|
+
if (!autoOrient) return { translate: point };
|
|
1922
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1923
|
+
const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
1924
|
+
return { translate: point, rotateDeg };
|
|
1925
|
+
}
|
|
1926
|
+
function tFromArcFraction(lut, arcFrac) {
|
|
1927
|
+
const total = lut.ds[lut.ds.length - 1];
|
|
1928
|
+
const target = arcFrac * total;
|
|
1929
|
+
const { ts, ds } = lut;
|
|
1930
|
+
const last = ds.length - 1;
|
|
1931
|
+
if (target <= 0) return ts[0];
|
|
1932
|
+
if (target >= ds[last]) return ts[last];
|
|
1933
|
+
let lo = 1, hi = last;
|
|
1934
|
+
while (lo < hi) {
|
|
1935
|
+
const mid = lo + hi >>> 1;
|
|
1936
|
+
if (ds[mid] < target) lo = mid + 1;
|
|
1937
|
+
else hi = mid;
|
|
1938
|
+
}
|
|
1939
|
+
const dPrev = ds[hi - 1];
|
|
1940
|
+
const span = ds[hi] - dPrev;
|
|
1941
|
+
const frac = span > 0 ? (target - dPrev) / span : 0;
|
|
1942
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
1943
|
+
}
|
|
1780
1944
|
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
1781
1945
|
var DEFAULT_ROTATION_TOL = 5;
|
|
1782
1946
|
var DEFAULT_MAX_SAMPLES = 32;
|
|
@@ -2049,9 +2213,211 @@ function perpDist(q, pA, pB) {
|
|
|
2049
2213
|
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
2050
2214
|
return Math.abs(cross) / Math.sqrt(len2);
|
|
2051
2215
|
}
|
|
2216
|
+
function materializeMotionPathsInTree(root, opts) {
|
|
2217
|
+
const out = walkAndMaterialize(root, opts);
|
|
2218
|
+
return out != null ? out : root;
|
|
2219
|
+
}
|
|
2220
|
+
function walkAndMaterialize(node, opts) {
|
|
2221
|
+
let newChildren;
|
|
2222
|
+
if (node.children) {
|
|
2223
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2224
|
+
const ch = node.children[i];
|
|
2225
|
+
const ret = walkAndMaterialize(ch, opts);
|
|
2226
|
+
if (ret !== null) {
|
|
2227
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2228
|
+
newChildren[i] = ret;
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
let newAnimate;
|
|
2233
|
+
const animBucket = node.animate;
|
|
2234
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2235
|
+
const animDef = mergeStaticTransformIntoAnimDef(animBucket, node.transform);
|
|
2236
|
+
const transformAnim = animDef.transform;
|
|
2237
|
+
if (transformAnim && typeof transformAnim === "object" && propAnimIsMotionPath(transformAnim)) {
|
|
2238
|
+
const materialized = materializeMotionPathInPropAnim(transformAnim, opts);
|
|
2239
|
+
if (materialized !== transformAnim) {
|
|
2240
|
+
newAnimate = __spreadProps(__spreadValues({}, animDef), { transform: materialized });
|
|
2241
|
+
}
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
if (!newChildren && !newAnimate) return null;
|
|
2245
|
+
const cloned = __spreadValues({}, node);
|
|
2246
|
+
if (newChildren) cloned.children = newChildren;
|
|
2247
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2248
|
+
return cloned;
|
|
2249
|
+
}
|
|
2052
2250
|
|
|
2053
2251
|
// src/animation/PxDefinitions.ts
|
|
2054
2252
|
var PX_LOOP_JUMP_SHIFT_MS = 1;
|
|
2253
|
+
function deepEqualValue(a, b) {
|
|
2254
|
+
if (a === b) return true;
|
|
2255
|
+
if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
|
|
2256
|
+
if (Array.isArray(a) !== Array.isArray(b)) return false;
|
|
2257
|
+
const ka = Object.keys(a);
|
|
2258
|
+
const kb = Object.keys(b);
|
|
2259
|
+
if (ka.length !== kb.length) return false;
|
|
2260
|
+
return ka.every((k) => deepEqualValue(a[k], b[k]));
|
|
2261
|
+
}
|
|
2262
|
+
function parsePathCommands(d) {
|
|
2263
|
+
const tokens = d.split(/([MLCZmlcz]|[\s,]+)/).map((t) => t.trim()).filter((t) => t && t !== ",");
|
|
2264
|
+
const commands = [];
|
|
2265
|
+
let currentCommand = null;
|
|
2266
|
+
for (const token of tokens) {
|
|
2267
|
+
if (/[MLCZmlcz]/.test(token)) {
|
|
2268
|
+
currentCommand = { type: token, values: [] };
|
|
2269
|
+
commands.push(currentCommand);
|
|
2270
|
+
} else if (currentCommand) {
|
|
2271
|
+
const value = +token;
|
|
2272
|
+
currentCommand.values.push(Number.isNaN(value) ? 0 : value);
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
return commands;
|
|
2276
|
+
}
|
|
2277
|
+
function parseSvgPathToBezier(d) {
|
|
2278
|
+
const res = [];
|
|
2279
|
+
let currentPath;
|
|
2280
|
+
const commands = parsePathCommands(d);
|
|
2281
|
+
for (const command of commands) {
|
|
2282
|
+
const type = command.type;
|
|
2283
|
+
const values = command.values;
|
|
2284
|
+
if (type === "M" || type === "m") {
|
|
2285
|
+
const x = values[0] || 0;
|
|
2286
|
+
const y = values[1] || 0;
|
|
2287
|
+
currentPath = {
|
|
2288
|
+
v: [[x, y]],
|
|
2289
|
+
i: [[x, y]],
|
|
2290
|
+
o: [[x, y]],
|
|
2291
|
+
c: false
|
|
2292
|
+
};
|
|
2293
|
+
res.push(currentPath);
|
|
2294
|
+
continue;
|
|
2295
|
+
}
|
|
2296
|
+
if (!currentPath) {
|
|
2297
|
+
currentPath = {
|
|
2298
|
+
v: [[0, 0]],
|
|
2299
|
+
i: [[0, 0]],
|
|
2300
|
+
o: [[0, 0]],
|
|
2301
|
+
c: false
|
|
2302
|
+
};
|
|
2303
|
+
res.push(currentPath);
|
|
2304
|
+
}
|
|
2305
|
+
if (type === "L") {
|
|
2306
|
+
const x = values[0] || 0;
|
|
2307
|
+
const y = values[1] || 0;
|
|
2308
|
+
currentPath.v.push([x, y]);
|
|
2309
|
+
currentPath.i.push([x, y]);
|
|
2310
|
+
currentPath.o.push([x, y]);
|
|
2311
|
+
} else if (type === "C") {
|
|
2312
|
+
const outX = values[0] || 0;
|
|
2313
|
+
const outY = values[1] || 0;
|
|
2314
|
+
const inX2 = values[2] || 0;
|
|
2315
|
+
const inY2 = values[3] || 0;
|
|
2316
|
+
const x2 = values[4] || 0;
|
|
2317
|
+
const y2 = values[5] || 0;
|
|
2318
|
+
currentPath.o[currentPath.o.length - 1] = [outX, outY];
|
|
2319
|
+
currentPath.v.push([x2, y2]);
|
|
2320
|
+
currentPath.i.push([inX2, inY2]);
|
|
2321
|
+
currentPath.o.push([x2, y2]);
|
|
2322
|
+
} else if (type === "Z" || type === "z") {
|
|
2323
|
+
currentPath.c = true;
|
|
2324
|
+
} else {
|
|
2325
|
+
console.warn('Unsupported path command "' + type + '"');
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
return res;
|
|
2329
|
+
}
|
|
2330
|
+
function extractPathData(str2) {
|
|
2331
|
+
if (str2.startsWith("path(") && str2.endsWith(")")) {
|
|
2332
|
+
return str2.slice(5, -1);
|
|
2333
|
+
}
|
|
2334
|
+
if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str2)) {
|
|
2335
|
+
return str2;
|
|
2336
|
+
}
|
|
2337
|
+
return void 0;
|
|
2338
|
+
}
|
|
2339
|
+
function isPathString(value) {
|
|
2340
|
+
return typeof value === "string" && extractPathData(value) !== void 0;
|
|
2341
|
+
}
|
|
2342
|
+
function normalizePathValue(value) {
|
|
2343
|
+
if (value && typeof value === "object" && typeof value.pathData === "string") {
|
|
2344
|
+
const d = extractPathData(value.pathData);
|
|
2345
|
+
return d ? { paths: parseSvgPathToBezier(d) } : value;
|
|
2346
|
+
}
|
|
2347
|
+
if (value && typeof value === "object" && "paths" in value) {
|
|
2348
|
+
const pathsArray = value.paths;
|
|
2349
|
+
if (Array.isArray(pathsArray) && pathsArray.length > 0) {
|
|
2350
|
+
if (isPathString(pathsArray[0])) {
|
|
2351
|
+
const paths = [];
|
|
2352
|
+
for (const pathStr2 of pathsArray) {
|
|
2353
|
+
const d = extractPathData(pathStr2);
|
|
2354
|
+
if (d) {
|
|
2355
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
return { paths };
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2361
|
+
return value;
|
|
2362
|
+
}
|
|
2363
|
+
if (Array.isArray(value)) {
|
|
2364
|
+
if (value.length > 0 && isPathString(value[0])) {
|
|
2365
|
+
const paths = [];
|
|
2366
|
+
for (const pathStr2 of value) {
|
|
2367
|
+
const d = extractPathData(pathStr2);
|
|
2368
|
+
if (d) {
|
|
2369
|
+
paths.push(...parseSvgPathToBezier(d));
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
return { paths };
|
|
2373
|
+
}
|
|
2374
|
+
return { paths: value };
|
|
2375
|
+
}
|
|
2376
|
+
if (isPathString(value)) {
|
|
2377
|
+
const d = extractPathData(value);
|
|
2378
|
+
return { paths: parseSvgPathToBezier(d) };
|
|
2379
|
+
}
|
|
2380
|
+
return value;
|
|
2381
|
+
}
|
|
2382
|
+
function resolveEasing(easing, defs) {
|
|
2383
|
+
var _a2;
|
|
2384
|
+
if (!easing) return void 0;
|
|
2385
|
+
if (Array.isArray(easing)) {
|
|
2386
|
+
return easing;
|
|
2387
|
+
}
|
|
2388
|
+
if ((_a2 = defs == null ? void 0 : defs.easings) == null ? void 0 : _a2[easing]) {
|
|
2389
|
+
return defs.easings[easing];
|
|
2390
|
+
}
|
|
2391
|
+
console.warn("Unknown easing name: " + easing);
|
|
2392
|
+
return void 0;
|
|
2393
|
+
}
|
|
2394
|
+
function resolveAnimation(animRef, defs) {
|
|
2395
|
+
var _a2;
|
|
2396
|
+
if (typeof animRef === "string") {
|
|
2397
|
+
const resolved = (_a2 = defs == null ? void 0 : defs.animations) == null ? void 0 : _a2[animRef];
|
|
2398
|
+
if (!resolved) {
|
|
2399
|
+
console.warn("Unknown animation name: " + animRef);
|
|
2400
|
+
}
|
|
2401
|
+
return resolved;
|
|
2402
|
+
}
|
|
2403
|
+
return animRef;
|
|
2404
|
+
}
|
|
2405
|
+
function resolveElementAnimation(animate, defs) {
|
|
2406
|
+
if (!animate) return [];
|
|
2407
|
+
const results = [];
|
|
2408
|
+
if (typeof animate === "string") {
|
|
2409
|
+
const resolved = resolveAnimation(animate, defs);
|
|
2410
|
+
if (resolved) results.push(resolved);
|
|
2411
|
+
} else if (Array.isArray(animate)) {
|
|
2412
|
+
for (const item of animate) {
|
|
2413
|
+
const resolved = resolveAnimation(item, defs);
|
|
2414
|
+
if (resolved) results.push(resolved);
|
|
2415
|
+
}
|
|
2416
|
+
} else {
|
|
2417
|
+
results.push(animate);
|
|
2418
|
+
}
|
|
2419
|
+
return results;
|
|
2420
|
+
}
|
|
2055
2421
|
function interpolateValue(propName, a, b, t) {
|
|
2056
2422
|
var _a2, _b;
|
|
2057
2423
|
if (propName === "d") {
|
|
@@ -2090,35 +2456,498 @@ function interpolateTransformParts(a, b, t) {
|
|
|
2090
2456
|
}
|
|
2091
2457
|
return out;
|
|
2092
2458
|
}
|
|
2093
|
-
function
|
|
2094
|
-
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2459
|
+
function expandLoopKeyframes(propName, keyframes, loop, duration) {
|
|
2460
|
+
var _a2, _b, _c, _d, _e;
|
|
2461
|
+
const totalIntervals = keyframes.length - 1;
|
|
2462
|
+
const segCount = clamp((_a2 = loop.segmentCount) != null ? _a2 : totalIntervals, 1, totalIntervals);
|
|
2463
|
+
let segKfs;
|
|
2464
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2465
|
+
segKfs = keyframes.slice(0, segCount + 1);
|
|
2466
|
+
} else {
|
|
2467
|
+
segKfs = keyframes.slice(totalIntervals - segCount);
|
|
2468
|
+
}
|
|
2469
|
+
const firstT = (_b = keyframes[0].t) != null ? _b : 0;
|
|
2470
|
+
const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
|
|
2471
|
+
let fillStart, fillEnd;
|
|
2472
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2473
|
+
fillStart = 0;
|
|
2474
|
+
fillEnd = firstT;
|
|
2475
|
+
} else {
|
|
2476
|
+
fillStart = lastT;
|
|
2477
|
+
fillEnd = duration;
|
|
2478
|
+
}
|
|
2479
|
+
const fillDuration = fillEnd - fillStart;
|
|
2480
|
+
if (fillDuration <= 0) return keyframes;
|
|
2481
|
+
const segStartT = (_d = segKfs[0].t) != null ? _d : 0;
|
|
2482
|
+
const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
|
|
2483
|
+
const segDuration = segEndT - segStartT;
|
|
2484
|
+
if (segDuration <= 0) return keyframes;
|
|
2485
|
+
const template = segKfs.map((kf) => ({
|
|
2486
|
+
relT: (kf.t - segStartT) / segDuration,
|
|
2487
|
+
v: kf.v,
|
|
2488
|
+
e: kf.e,
|
|
2489
|
+
tangentIn: keyframeTangentIn(kf),
|
|
2490
|
+
tangentOut: keyframeTangentOut(kf)
|
|
2491
|
+
}));
|
|
2492
|
+
const fullReps = Math.floor(fillDuration / segDuration);
|
|
2493
|
+
const remainder = fillDuration - fullReps * segDuration;
|
|
2494
|
+
const partialFraction = remainder / segDuration;
|
|
2495
|
+
const looped = [];
|
|
2496
|
+
const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
|
|
2497
|
+
const originalTerminalKf = keyframes[keyframes.length - 1];
|
|
2498
|
+
let terminalEasingOverride;
|
|
2499
|
+
let hasTerminalEasingOverride = false;
|
|
2500
|
+
function appendRep(repStart, isReversed, partial) {
|
|
2501
|
+
var _a3;
|
|
2502
|
+
let entries;
|
|
2503
|
+
if (isReversed) {
|
|
2504
|
+
entries = [];
|
|
2505
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2506
|
+
entries.push({
|
|
2507
|
+
relT: 1 - template[i].relT,
|
|
2508
|
+
v: template[i].v,
|
|
2509
|
+
// Easing for reversed transition: use reversed easing from the forward "from" keyframe
|
|
2510
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
2511
|
+
// Reversed traversal swaps each vertex's in/out spatial tangents
|
|
2512
|
+
// (geometry is identical, walked backwards), so curvature and
|
|
2513
|
+
// auto-orientation survive the reversed rep.
|
|
2514
|
+
tangentIn: template[i].tangentOut,
|
|
2515
|
+
tangentOut: template[i].tangentIn
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
} else {
|
|
2519
|
+
entries = template;
|
|
2520
|
+
}
|
|
2521
|
+
const cutRelT = partial !== void 0 ? partial : 1;
|
|
2522
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2523
|
+
const entry = entries[i];
|
|
2524
|
+
if (entry.relT > cutRelT + 1e-9) {
|
|
2525
|
+
const prev = entries[i - 1];
|
|
2526
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2527
|
+
const localFrac = (cutRelT - prev.relT) / intervalSpan;
|
|
2528
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2529
|
+
const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2530
|
+
const { left: leftEasing } = splitEasing(prev.e, localFrac);
|
|
2531
|
+
if (looped.length > 0 && prev.relT <= cutRelT) {
|
|
2532
|
+
looped[looped.length - 1].e = leftEasing;
|
|
2533
|
+
}
|
|
2534
|
+
looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: void 0 });
|
|
2535
|
+
return;
|
|
2536
|
+
}
|
|
2537
|
+
const prevKf = looped.length > 0 ? looped[looped.length - 1] : originalTerminalKf;
|
|
2538
|
+
const isBoundary = separateBoundary && i === 0 && prevKf !== void 0 && Math.abs(((_a3 = prevKf.t) != null ? _a3 : 0) - (repStart + entry.relT * segDuration)) < 1e-9;
|
|
2539
|
+
if (isBoundary) {
|
|
2540
|
+
if (deepEqualValue(prevKf.v, entry.v)) {
|
|
2541
|
+
if (looped.length > 0) {
|
|
2542
|
+
prevKf.e = entry.e;
|
|
2543
|
+
prevKf.tangentOut = entry.tangentOut;
|
|
2544
|
+
} else {
|
|
2545
|
+
terminalEasingOverride = entry.e;
|
|
2546
|
+
hasTerminalEasingOverride = true;
|
|
2547
|
+
}
|
|
2548
|
+
continue;
|
|
2549
|
+
}
|
|
2550
|
+
if (looped.length > 0) {
|
|
2551
|
+
delete prevKf.tangentIn;
|
|
2552
|
+
delete prevKf.tangentOut;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
const pushed = {
|
|
2556
|
+
t: repStart + entry.relT * segDuration + (isBoundary ? PX_LOOP_JUMP_SHIFT_MS : 0),
|
|
2557
|
+
v: entry.v,
|
|
2558
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2559
|
+
};
|
|
2560
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
2561
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
2562
|
+
looped.push(pushed);
|
|
2107
2563
|
}
|
|
2108
|
-
return animDef;
|
|
2109
2564
|
}
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2565
|
+
function appendRepTail(repStart, isReversed, tailFraction) {
|
|
2566
|
+
let entries;
|
|
2567
|
+
if (isReversed) {
|
|
2568
|
+
entries = [];
|
|
2569
|
+
for (let i = template.length - 1; i >= 0; i--) {
|
|
2570
|
+
entries.push({
|
|
2571
|
+
relT: 1 - template[i].relT,
|
|
2572
|
+
v: template[i].v,
|
|
2573
|
+
e: i > 0 ? reverseEasing(template[i - 1].e) : void 0,
|
|
2574
|
+
tangentIn: template[i].tangentOut,
|
|
2575
|
+
tangentOut: template[i].tangentIn
|
|
2576
|
+
});
|
|
2577
|
+
}
|
|
2578
|
+
} else {
|
|
2579
|
+
entries = template;
|
|
2580
|
+
}
|
|
2581
|
+
const startRelT = 1 - tailFraction;
|
|
2582
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2583
|
+
const entry = entries[i];
|
|
2584
|
+
if (entry.relT < startRelT - 1e-9) continue;
|
|
2585
|
+
const prev = entries[i - 1];
|
|
2586
|
+
if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {
|
|
2587
|
+
const intervalSpan = entry.relT - prev.relT;
|
|
2588
|
+
const localFrac = (startRelT - prev.relT) / intervalSpan;
|
|
2589
|
+
const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;
|
|
2590
|
+
const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);
|
|
2591
|
+
const { right: rightEasing } = splitEasing(prev.e, localFrac);
|
|
2592
|
+
looped.push({ t: repStart, v: startValue, e: rightEasing });
|
|
2593
|
+
}
|
|
2594
|
+
const pushed = {
|
|
2595
|
+
t: repStart + (entry.relT - startRelT) * segDuration,
|
|
2596
|
+
v: entry.v,
|
|
2597
|
+
e: i < entries.length - 1 ? entry.e : void 0
|
|
2598
|
+
};
|
|
2599
|
+
if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;
|
|
2600
|
+
if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;
|
|
2601
|
+
looped.push(pushed);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2605
|
+
if (partialFraction > 1e-9) {
|
|
2606
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
|
|
2607
|
+
appendRepTail(fillStart, isReversed, partialFraction);
|
|
2608
|
+
}
|
|
2609
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2610
|
+
const distFromBoundary = fullReps - 1 - rep;
|
|
2611
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
|
|
2612
|
+
const repStart = fillStart + remainder + rep * segDuration;
|
|
2613
|
+
appendRep(repStart, isReversed);
|
|
2614
|
+
}
|
|
2615
|
+
} else {
|
|
2616
|
+
for (let rep = 0; rep < fullReps; rep++) {
|
|
2617
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
|
|
2618
|
+
const repStart = fillStart + rep * segDuration;
|
|
2619
|
+
appendRep(repStart, isReversed);
|
|
2620
|
+
}
|
|
2621
|
+
if (partialFraction > 1e-9) {
|
|
2622
|
+
const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
|
|
2623
|
+
const repStart = fillStart + fullReps * segDuration;
|
|
2624
|
+
appendRep(repStart, isReversed, partialFraction);
|
|
2625
|
+
}
|
|
2626
|
+
}
|
|
2627
|
+
if (loop.repeatAt === PxLoopRepeatAt.start) {
|
|
2628
|
+
return [...looped, ...keyframes];
|
|
2629
|
+
} else {
|
|
2630
|
+
if (hasTerminalEasingOverride && keyframes.length > 0) {
|
|
2631
|
+
const head = keyframes.slice(0, -1);
|
|
2632
|
+
const tail = __spreadProps(__spreadValues({}, keyframes[keyframes.length - 1]), { e: terminalEasingOverride });
|
|
2633
|
+
return [...head, tail, ...looped];
|
|
2634
|
+
}
|
|
2635
|
+
return [...keyframes, ...looped];
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
function normalizeKeyframes(propName, propAnim, duration, defs) {
|
|
2639
|
+
var _a2;
|
|
2640
|
+
const keyframes = propAnim.keyframes || [];
|
|
2641
|
+
const normalized = [];
|
|
2642
|
+
for (const kf of keyframes) {
|
|
2643
|
+
const timePct = keyframeTime(kf);
|
|
2644
|
+
let value = keyframeValue(kf);
|
|
2645
|
+
const easing = keyframeEasing(kf);
|
|
2646
|
+
if (propName === "d") {
|
|
2647
|
+
value = normalizePathValue(value);
|
|
2648
|
+
}
|
|
2649
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2650
|
+
if (PX_COLOR_ATTR_NAMES.has(propNameKebab)) {
|
|
2651
|
+
value = (_a2 = parseColor(value)) != null ? _a2 : value;
|
|
2652
|
+
}
|
|
2653
|
+
const normKf = {
|
|
2654
|
+
t: timePct,
|
|
2655
|
+
v: value,
|
|
2656
|
+
e: resolveEasing(easing, defs)
|
|
2657
|
+
};
|
|
2658
|
+
const tIn = keyframeTangentIn(kf);
|
|
2659
|
+
const tOut = keyframeTangentOut(kf);
|
|
2660
|
+
if (tIn) normKf.tangentIn = tIn;
|
|
2661
|
+
if (tOut) normKf.tangentOut = tOut;
|
|
2662
|
+
normalized.push(normKf);
|
|
2663
|
+
}
|
|
2664
|
+
normalized.sort((a, b) => {
|
|
2665
|
+
var _a3, _b;
|
|
2666
|
+
return ((_a3 = a.t) != null ? _a3 : 0) - ((_b = b.t) != null ? _b : 0);
|
|
2117
2667
|
});
|
|
2118
|
-
|
|
2119
|
-
const
|
|
2120
|
-
|
|
2121
|
-
|
|
2668
|
+
const loopRaw = propAnim.loop;
|
|
2669
|
+
const loop = loopRaw === true ? {} : loopRaw || void 0;
|
|
2670
|
+
if (loop && normalized.length >= 2) {
|
|
2671
|
+
return expandLoopKeyframes(propName, normalized, loop, duration);
|
|
2672
|
+
}
|
|
2673
|
+
return normalized;
|
|
2674
|
+
}
|
|
2675
|
+
function mergeAnimationDefinitions(animations) {
|
|
2676
|
+
const merged = {};
|
|
2677
|
+
for (const anim of animations) {
|
|
2678
|
+
for (const [prop, propAnim] of Object.entries(anim)) {
|
|
2679
|
+
merged[prop] = propAnim;
|
|
2680
|
+
}
|
|
2681
|
+
}
|
|
2682
|
+
return merged;
|
|
2683
|
+
}
|
|
2684
|
+
function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
|
|
2685
|
+
const loopRaw = propAnim.loop;
|
|
2686
|
+
if (loopRaw === void 0 || loopRaw === null || loopRaw === false) return propAnim;
|
|
2687
|
+
const loop = loopRaw === true ? {} : loopRaw;
|
|
2688
|
+
const rawKfs = propAnim.keyframes;
|
|
2689
|
+
if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
|
|
2690
|
+
const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2691
|
+
const isColor = PX_COLOR_ATTR_NAMES.has(propNameKebab);
|
|
2692
|
+
const kfs = rawKfs.map((kf) => {
|
|
2693
|
+
var _a2;
|
|
2694
|
+
const t = keyframeTime(kf);
|
|
2695
|
+
let v = keyframeValue(kf);
|
|
2696
|
+
if (propName === "d") v = normalizePathValue(v);
|
|
2697
|
+
if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
|
|
2698
|
+
const e = keyframeEasing(kf);
|
|
2699
|
+
const out2 = { t, v, e };
|
|
2700
|
+
const tIn = keyframeTangentIn(kf);
|
|
2701
|
+
const tOut = keyframeTangentOut(kf);
|
|
2702
|
+
if (tIn) out2.tangentIn = tIn;
|
|
2703
|
+
if (tOut) out2.tangentOut = tOut;
|
|
2704
|
+
return out2;
|
|
2705
|
+
});
|
|
2706
|
+
const expanded = expandLoopKeyframes(propName, kfs, loop, duration);
|
|
2707
|
+
const out = { keyframes: expanded };
|
|
2708
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
2709
|
+
return out;
|
|
2710
|
+
}
|
|
2711
|
+
function materializeInternalLoopsInTree(root, duration) {
|
|
2712
|
+
const ret = walkAndMaterializeLoops(root, duration);
|
|
2713
|
+
return ret != null ? ret : root;
|
|
2714
|
+
}
|
|
2715
|
+
function walkAndMaterializeLoops(node, duration) {
|
|
2716
|
+
let newChildren;
|
|
2717
|
+
if (node.children) {
|
|
2718
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2719
|
+
const ret = walkAndMaterializeLoops(node.children[i], duration);
|
|
2720
|
+
if (ret !== null) {
|
|
2721
|
+
if (!newChildren) newChildren = node.children.slice();
|
|
2722
|
+
newChildren[i] = ret;
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
let newAnimate;
|
|
2727
|
+
const animBucket = node.animate;
|
|
2728
|
+
if (animBucket && typeof animBucket === "object" && !Array.isArray(animBucket)) {
|
|
2729
|
+
const animDef = animBucket;
|
|
2730
|
+
for (const propName of Object.keys(animDef)) {
|
|
2731
|
+
const propAnim = animDef[propName];
|
|
2732
|
+
const materialized = materializeInternalLoopsInPropAnim(propName, propAnim, duration);
|
|
2733
|
+
if (materialized !== propAnim) {
|
|
2734
|
+
if (!newAnimate) newAnimate = __spreadValues({}, animDef);
|
|
2735
|
+
newAnimate[propName] = materialized;
|
|
2736
|
+
}
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
if (!newChildren && !newAnimate) return null;
|
|
2740
|
+
const cloned = __spreadValues({}, node);
|
|
2741
|
+
if (newChildren) cloned.children = newChildren;
|
|
2742
|
+
if (newAnimate) cloned.animate = newAnimate;
|
|
2743
|
+
return cloned;
|
|
2744
|
+
}
|
|
2745
|
+
var _elementIdCounter = 0;
|
|
2746
|
+
function generateElementId() {
|
|
2747
|
+
return "_px_el_" + ++_elementIdCounter;
|
|
2748
|
+
}
|
|
2749
|
+
function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
|
|
2750
|
+
const normalized = {};
|
|
2751
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
2752
|
+
if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
|
|
2753
|
+
continue;
|
|
2754
|
+
}
|
|
2755
|
+
const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);
|
|
2756
|
+
if (normalizedKfs.length > 0) {
|
|
2757
|
+
const out = { keyframes: normalizedKfs };
|
|
2758
|
+
if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
|
|
2759
|
+
if (propAnim.loop !== void 0) out.loop = propAnim.loop;
|
|
2760
|
+
normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materializeMotionPathInPropAnim(out) : out;
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
return normalized;
|
|
2764
|
+
}
|
|
2765
|
+
function normalizeBindings(doc, engine = PxTimelineEngine.native) {
|
|
2766
|
+
const animatorConfig = getAnimatorConfig(doc) || {};
|
|
2767
|
+
const defs = getDefinitions(doc);
|
|
2768
|
+
const duration = animatorConfig.duration || 1e3;
|
|
2769
|
+
const bindings = [];
|
|
2770
|
+
const processAnimation = (id, animDefs, staticTransform) => {
|
|
2771
|
+
if (animDefs.length === 0) return null;
|
|
2772
|
+
const merged = mergeStaticTransformIntoAnimDef(mergeAnimationDefinitions(animDefs), staticTransform);
|
|
2773
|
+
const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
|
|
2774
|
+
if (Object.keys(normalizedAnim).length === 0) return null;
|
|
2775
|
+
return {
|
|
2776
|
+
id,
|
|
2777
|
+
animate: normalizedAnim
|
|
2778
|
+
};
|
|
2779
|
+
};
|
|
2780
|
+
const docBindings = getBindings(doc);
|
|
2781
|
+
if (docBindings) {
|
|
2782
|
+
for (const binding of docBindings) {
|
|
2783
|
+
const id = binding.target.startsWith("#") ? binding.target.slice(1) : binding.target;
|
|
2784
|
+
const animDefs = binding.animateWith.map((name) => resolveAnimation(name, defs)).filter((d) => !!d);
|
|
2785
|
+
const normalized = processAnimation(id, animDefs);
|
|
2786
|
+
if (normalized) bindings.push(normalized);
|
|
2787
|
+
}
|
|
2788
|
+
}
|
|
2789
|
+
const processNode = (node) => {
|
|
2790
|
+
const inlineAnim = node.animate;
|
|
2791
|
+
if (inlineAnim && Object.keys(inlineAnim).length > 0) {
|
|
2792
|
+
const nodeId = node.id || generateElementId();
|
|
2793
|
+
node.id = nodeId;
|
|
2794
|
+
const normalized = processAnimation(nodeId, resolveElementAnimation(inlineAnim, defs), node.transform);
|
|
2795
|
+
if (normalized) bindings.push(normalized);
|
|
2796
|
+
}
|
|
2797
|
+
if (node.children) {
|
|
2798
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
2799
|
+
processNode(node.children[i]);
|
|
2800
|
+
}
|
|
2801
|
+
}
|
|
2802
|
+
};
|
|
2803
|
+
if (doc.children) {
|
|
2804
|
+
for (let i = 0; i < doc.children.length; i++) {
|
|
2805
|
+
processNode(doc.children[i]);
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
return bindings;
|
|
2809
|
+
}
|
|
2810
|
+
function getKeyframesPair(keyframes, progress) {
|
|
2811
|
+
var _a2, _b;
|
|
2812
|
+
const last = keyframes.length - 1;
|
|
2813
|
+
let prevKf = keyframes[0];
|
|
2814
|
+
let nextKf = keyframes[last > 0 ? 1 : 0];
|
|
2815
|
+
for (let j = 0; j < last; j++) {
|
|
2816
|
+
const aOff = (_a2 = keyframes[j].t) != null ? _a2 : 0;
|
|
2817
|
+
const bOff = (_b = keyframes[j + 1].t) != null ? _b : 0;
|
|
2818
|
+
if (aOff <= progress && progress <= bOff) {
|
|
2819
|
+
prevKf = keyframes[j];
|
|
2820
|
+
nextKf = keyframes[j + 1];
|
|
2821
|
+
break;
|
|
2822
|
+
}
|
|
2823
|
+
if (progress > bOff && j === last - 1) {
|
|
2824
|
+
prevKf = keyframes[last > 0 ? last - 1 : 0];
|
|
2825
|
+
nextKf = keyframes[last];
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
return { prevKf, nextKf };
|
|
2829
|
+
}
|
|
2830
|
+
function calcPropertyValue(propName, propAnim, progress) {
|
|
2831
|
+
var _a2, _b, _c, _d, _e;
|
|
2832
|
+
const keyframes = propAnim.keyframes || [];
|
|
2833
|
+
if (keyframes.length === 0) return null;
|
|
2834
|
+
const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
|
|
2835
|
+
let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
|
|
2836
|
+
localProgress = clamp(localProgress, 0, 1);
|
|
2837
|
+
const easing = keyframeEasing(prevKf);
|
|
2838
|
+
if (easing && Array.isArray(easing)) {
|
|
2839
|
+
try {
|
|
2840
|
+
localProgress = cubicBezier(easing)(localProgress);
|
|
2841
|
+
} catch (e) {
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
|
|
2845
|
+
let cssValue = null;
|
|
2846
|
+
const prevV = prevKf == null ? void 0 : prevKf.v;
|
|
2847
|
+
const nextV = nextKf == null ? void 0 : nextKf.v;
|
|
2848
|
+
if (cssAttrName === "d") {
|
|
2849
|
+
const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
|
|
2850
|
+
const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
|
|
2851
|
+
cssValue = interpolateBeziers(
|
|
2852
|
+
prevPaths,
|
|
2853
|
+
nextPaths,
|
|
2854
|
+
localProgress
|
|
2855
|
+
).map((bz) => bezierToSvgPath(bz)).join("");
|
|
2856
|
+
} else if (PX_COLOR_ATTR_NAMES.has(cssAttrName)) {
|
|
2857
|
+
cssValue = toRGBA(interpolateColor(
|
|
2858
|
+
prevV || [0, 0, 0, 1],
|
|
2859
|
+
nextV || [0, 0, 0, 1],
|
|
2860
|
+
localProgress
|
|
2861
|
+
));
|
|
2862
|
+
cssAttrName = propName;
|
|
2863
|
+
} else if (cssAttrName === "stroke-dasharray") {
|
|
2864
|
+
cssValue = interpolateVec(
|
|
2865
|
+
prevV || [],
|
|
2866
|
+
nextV || [],
|
|
2867
|
+
localProgress
|
|
2868
|
+
).join(" ");
|
|
2869
|
+
cssAttrName = propName;
|
|
2870
|
+
} else if (cssAttrName === "transform" && prevV !== null && typeof prevV === "object" && !Array.isArray(prevV)) {
|
|
2871
|
+
const partKeys = /* @__PURE__ */ new Set([
|
|
2872
|
+
...prevV ? Object.keys(prevV) : [],
|
|
2873
|
+
...nextV ? Object.keys(nextV) : []
|
|
2874
|
+
]);
|
|
2875
|
+
const partsResult = {};
|
|
2876
|
+
for (const partKey of partKeys) {
|
|
2877
|
+
const prevPart = prevV == null ? void 0 : prevV[partKey];
|
|
2878
|
+
const nextPart = nextV == null ? void 0 : nextV[partKey];
|
|
2879
|
+
if (partKey === "rotate" || partKey === "skew") {
|
|
2880
|
+
partsResult[partKey] = interpolateNum(+(prevPart != null ? prevPart : 0), +(nextPart != null ? nextPart : 0), localProgress);
|
|
2881
|
+
} else if (partKey === "translate" || partKey === "scale" || partKey === "origin") {
|
|
2882
|
+
const fallback = partKey === "scale" ? [1, 1] : [0, 0];
|
|
2883
|
+
const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);
|
|
2884
|
+
partsResult[partKey] = interp;
|
|
2885
|
+
}
|
|
2886
|
+
}
|
|
2887
|
+
if (propAnimIsMotionPath(propAnim)) {
|
|
2888
|
+
const prevTr = prevV.translate;
|
|
2889
|
+
const nextTr = nextV.translate;
|
|
2890
|
+
if (Array.isArray(prevTr) && Array.isArray(nextTr)) {
|
|
2891
|
+
const sample = evaluateMotionPathSegment(
|
|
2892
|
+
prevKf,
|
|
2893
|
+
nextKf,
|
|
2894
|
+
[+prevTr[0], +prevTr[1]],
|
|
2895
|
+
[+nextTr[0], +nextTr[1]],
|
|
2896
|
+
localProgress,
|
|
2897
|
+
!!propAnim.autoOrient
|
|
2898
|
+
);
|
|
2899
|
+
partsResult.translate = [sample.translate[0], sample.translate[1]];
|
|
2900
|
+
if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg + ((_e = partsResult.rotate) != null ? _e : 0);
|
|
2901
|
+
}
|
|
2902
|
+
}
|
|
2903
|
+
cssValue = composeTransformParts(partsResult, { withUnits: false });
|
|
2904
|
+
cssAttrName = "transform";
|
|
2905
|
+
} else if (cssAttrName === "translate") {
|
|
2906
|
+
const v = interpolateVec(
|
|
2907
|
+
prevV || [0, 0],
|
|
2908
|
+
nextV || [0, 0],
|
|
2909
|
+
localProgress
|
|
2910
|
+
);
|
|
2911
|
+
cssValue = "translate(" + v.join(",") + ")";
|
|
2912
|
+
cssAttrName = "transform";
|
|
2913
|
+
} else if (cssAttrName === "rotate") {
|
|
2914
|
+
const v = interpolateNum(
|
|
2915
|
+
+(prevV || 0),
|
|
2916
|
+
+(nextV || 0),
|
|
2917
|
+
localProgress
|
|
2918
|
+
);
|
|
2919
|
+
cssValue = "rotate(" + v + ")";
|
|
2920
|
+
cssAttrName = "transform";
|
|
2921
|
+
} else if (cssAttrName === "scale") {
|
|
2922
|
+
const v = interpolateVec(
|
|
2923
|
+
prevV || [1, 1],
|
|
2924
|
+
nextV || [1, 1],
|
|
2925
|
+
localProgress
|
|
2926
|
+
);
|
|
2927
|
+
cssValue = "scale(" + v.join(",") + ")";
|
|
2928
|
+
cssAttrName = "transform";
|
|
2929
|
+
} else {
|
|
2930
|
+
const num2 = interpolateNum(
|
|
2931
|
+
+(prevV || 0),
|
|
2932
|
+
+(nextV || 0),
|
|
2933
|
+
localProgress
|
|
2934
|
+
);
|
|
2935
|
+
cssValue = num2;
|
|
2936
|
+
}
|
|
2937
|
+
if (PX_PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
|
|
2938
|
+
cssValue = cssValue * 100 + "%";
|
|
2939
|
+
}
|
|
2940
|
+
return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
|
|
2941
|
+
}
|
|
2942
|
+
function calcAnimationValues(animDef, progress) {
|
|
2943
|
+
const result = {};
|
|
2944
|
+
for (const [propName, propAnim] of Object.entries(animDef)) {
|
|
2945
|
+
const computed = calcPropertyValue(propName, propAnim, progress);
|
|
2946
|
+
if (computed) {
|
|
2947
|
+
result[computed.k] = computed.v;
|
|
2948
|
+
}
|
|
2949
|
+
}
|
|
2950
|
+
return result;
|
|
2122
2951
|
}
|
|
2123
2952
|
|
|
2124
2953
|
// src/effects/PlayerEffectsUtil.visualModel.ts
|
|
@@ -2534,6 +3363,15 @@ function transformPathData(d, m, decimals = 2) {
|
|
|
2534
3363
|
}
|
|
2535
3364
|
|
|
2536
3365
|
// src/effects/shared/transformParts.ts
|
|
3366
|
+
function partsRecord(part, value, origin) {
|
|
3367
|
+
const rec = {};
|
|
3368
|
+
if (part === "translate" /* Translate */) rec.translate = value;
|
|
3369
|
+
else if (part === "rotate" /* Rotate */) rec.rotate = value;
|
|
3370
|
+
else if (part === "skew" /* Skew */) rec.skew = value;
|
|
3371
|
+
else rec.scale = value;
|
|
3372
|
+
if (origin && part !== "translate" /* Translate */) rec.origin = origin;
|
|
3373
|
+
return rec;
|
|
3374
|
+
}
|
|
2537
3375
|
function readAnimatable(raw) {
|
|
2538
3376
|
var _a2, _b;
|
|
2539
3377
|
if (raw === void 0) return { kind: "absent" /* Absent */ };
|
|
@@ -2552,6 +3390,24 @@ function readAnimatable(raw) {
|
|
|
2552
3390
|
}
|
|
2553
3391
|
return { kind: "static" /* Static */, value: raw };
|
|
2554
3392
|
}
|
|
3393
|
+
function writeAnimatableChannel(node, attrName, read, opts) {
|
|
3394
|
+
var _a2, _b, _c, _d;
|
|
3395
|
+
const toOut = (v) => (opts == null ? void 0 : opts.asString) && v !== void 0 && v !== null ? String(v) : v;
|
|
3396
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
3397
|
+
if (read.kind === "static" /* Static */) {
|
|
3398
|
+
node[attrName] = toOut(read.value);
|
|
3399
|
+
return;
|
|
3400
|
+
}
|
|
3401
|
+
const prevAnimate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
3402
|
+
const animate = __spreadValues({}, prevAnimate || {});
|
|
3403
|
+
const block = { keyframes: read.keyframes };
|
|
3404
|
+
if (read.loop !== void 0) block.loop = read.loop;
|
|
3405
|
+
if (read.autoOrient !== void 0) block.autoOrient = read.autoOrient;
|
|
3406
|
+
animate[attrName] = block;
|
|
3407
|
+
node.animate = animate;
|
|
3408
|
+
const baseline = (_d = (_b = read.base) != null ? _b : (_a2 = read.keyframes[0]) == null ? void 0 : _a2.value) != null ? _d : (_c = read.keyframes[0]) == null ? void 0 : _c.v;
|
|
3409
|
+
if (baseline !== void 0) node[attrName] = toOut(baseline);
|
|
3410
|
+
}
|
|
2555
3411
|
function normalizeKeyframe(kf) {
|
|
2556
3412
|
if (!kf || typeof kf !== "object") return kf;
|
|
2557
3413
|
const k = kf;
|
|
@@ -2566,6 +3422,22 @@ function normalizeKeyframe(kf) {
|
|
|
2566
3422
|
if (out.tangentIn === void 0 && k.ti !== void 0) out.tangentIn = k.ti;
|
|
2567
3423
|
return out;
|
|
2568
3424
|
}
|
|
3425
|
+
function readStaticOrigin(raw, ctx) {
|
|
3426
|
+
var _a2;
|
|
3427
|
+
const o = readAnimatable(raw);
|
|
3428
|
+
if (o.kind === "absent" /* Absent */) return void 0;
|
|
3429
|
+
if (o.kind === "static" /* Static */) return o.value;
|
|
3430
|
+
ctx.warnings.push("transformBy.origin: animated origin approximated by its first keyframe");
|
|
3431
|
+
return (_a2 = o.keyframes[0]) == null ? void 0 : _a2.value;
|
|
3432
|
+
}
|
|
3433
|
+
function keyframeWith(kf, value) {
|
|
3434
|
+
const out = { value };
|
|
3435
|
+
if (kf.time !== void 0) out.time = kf.time;
|
|
3436
|
+
if (kf.easing !== void 0) out.easing = kf.easing;
|
|
3437
|
+
if (kf.tangentOut !== void 0) out.tangentOut = kf.tangentOut;
|
|
3438
|
+
if (kf.tangentIn !== void 0) out.tangentIn = kf.tangentIn;
|
|
3439
|
+
return out;
|
|
3440
|
+
}
|
|
2569
3441
|
|
|
2570
3442
|
// src/effects/text/textGlyphsEffect.ts
|
|
2571
3443
|
var DEFAULT_FONT_SIZE = 16;
|
|
@@ -3114,8 +3986,109 @@ function materializeGlyphText(node, opts) {
|
|
|
3114
3986
|
if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
|
|
3115
3987
|
return materializeGlyphTextHorizontal(node, opts);
|
|
3116
3988
|
}
|
|
3117
|
-
|
|
3118
|
-
|
|
3989
|
+
function applyTextGlyphsEffect(node, fx, ctx) {
|
|
3990
|
+
if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
|
|
3991
|
+
if (!ctx.glyphs) {
|
|
3992
|
+
ctx.warnings.push("textGlyphs: no definitions.fonts \u2014 left as native <text>");
|
|
3993
|
+
return node;
|
|
3994
|
+
}
|
|
3995
|
+
return materializeGlyphTextHorizontal(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });
|
|
3996
|
+
}
|
|
3997
|
+
function applyTextGlyphsAlongPath(node, ctx, pathD, startOffset, textLength, pathOverflow) {
|
|
3998
|
+
if (!ctx.glyphs) {
|
|
3999
|
+
ctx.warnings.push("textGlyphs: no definitions.fonts");
|
|
4000
|
+
return null;
|
|
4001
|
+
}
|
|
4002
|
+
return materializeGlyphTextAlongPath(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);
|
|
4003
|
+
}
|
|
4004
|
+
|
|
4005
|
+
// src/util/PxNodeCloneUtil.ts
|
|
4006
|
+
function deepClonePxNode(value) {
|
|
4007
|
+
if (value === null || typeof value !== "object") return value;
|
|
4008
|
+
if (Array.isArray(value)) return value.map(deepClonePxNode);
|
|
4009
|
+
const out = {};
|
|
4010
|
+
for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
|
|
4011
|
+
return out;
|
|
4012
|
+
}
|
|
4013
|
+
function regenerateIdsAndRewriteRefs(root, genId3) {
|
|
4014
|
+
const oldToNew = /* @__PURE__ */ new Map();
|
|
4015
|
+
const walkAssign = (n) => {
|
|
4016
|
+
var _a2;
|
|
4017
|
+
if (typeof n.id === "string") {
|
|
4018
|
+
const newId = genId3();
|
|
4019
|
+
oldToNew.set(n.id, newId);
|
|
4020
|
+
n.id = newId;
|
|
4021
|
+
}
|
|
4022
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
|
|
4023
|
+
};
|
|
4024
|
+
walkAssign(root);
|
|
4025
|
+
const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
|
|
4026
|
+
const newId = oldToNew.get(oldId);
|
|
4027
|
+
return newId ? "url(#" + newId + ")" : m;
|
|
4028
|
+
});
|
|
4029
|
+
const walkRewrite = (n) => {
|
|
4030
|
+
var _a2;
|
|
4031
|
+
if (typeof n.href === "string" && n.href.startsWith("#")) {
|
|
4032
|
+
const newId = oldToNew.get(n.href.slice(1));
|
|
4033
|
+
if (newId) n.href = "#" + newId;
|
|
4034
|
+
}
|
|
4035
|
+
for (const k of Object.keys(n)) {
|
|
4036
|
+
if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
|
|
4037
|
+
const v = n[k];
|
|
4038
|
+
if (typeof v === "string" && v.indexOf("url(#") !== -1) {
|
|
4039
|
+
n[k] = rewriteUrl(v);
|
|
4040
|
+
}
|
|
4041
|
+
}
|
|
4042
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
|
|
4043
|
+
};
|
|
4044
|
+
walkRewrite(root);
|
|
4045
|
+
return oldToNew;
|
|
4046
|
+
}
|
|
4047
|
+
function toFiniteNum(v) {
|
|
4048
|
+
const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
|
|
4049
|
+
return Number.isFinite(n) ? n : 0;
|
|
4050
|
+
}
|
|
4051
|
+
function applyUseOffsetToG(gNode) {
|
|
4052
|
+
var _a2;
|
|
4053
|
+
const x = toFiniteNum(gNode.x);
|
|
4054
|
+
const y = toFiniteNum(gNode.y);
|
|
4055
|
+
delete gNode.x;
|
|
4056
|
+
delete gNode.y;
|
|
4057
|
+
if (!x && !y) return gNode;
|
|
4058
|
+
const offset = "translate(" + x + "," + y + ")";
|
|
4059
|
+
const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
|
|
4060
|
+
if (carriesTransform) {
|
|
4061
|
+
const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
|
|
4062
|
+
gNode.children = [inner];
|
|
4063
|
+
} else {
|
|
4064
|
+
gNode.transform = offset;
|
|
4065
|
+
}
|
|
4066
|
+
return gNode;
|
|
4067
|
+
}
|
|
4068
|
+
|
|
4069
|
+
// src/effects/shared/util.ts
|
|
4070
|
+
function genId(ctx, prefix) {
|
|
4071
|
+
return "_lw_" + prefix + "_" + ctx.nextId++;
|
|
4072
|
+
}
|
|
4073
|
+
function stripHash(href) {
|
|
4074
|
+
return typeof href === "string" ? href.replace(/^#/, "") : void 0;
|
|
4075
|
+
}
|
|
4076
|
+
function indexById(node, map) {
|
|
4077
|
+
var _a2;
|
|
4078
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
4079
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((child) => indexById(child, map));
|
|
4080
|
+
}
|
|
4081
|
+
function spliceDefs(root, defs) {
|
|
4082
|
+
if (!defs.length) return;
|
|
4083
|
+
const existing = root.children || (root.children = []);
|
|
4084
|
+
existing.unshift({ type: "defs", children: defs });
|
|
4085
|
+
}
|
|
4086
|
+
var clone = deepClonePxNode;
|
|
4087
|
+
function regenerateIdsInClone(root, ctx) {
|
|
4088
|
+
return regenerateIdsAndRewriteRefs(root, () => genId(ctx, "retimed"));
|
|
4089
|
+
}
|
|
4090
|
+
|
|
4091
|
+
// src/effects/text/textPathEffect.ts
|
|
3119
4092
|
var EXTEND_MARGIN_FRAC = 0.15;
|
|
3120
4093
|
function numRange(v) {
|
|
3121
4094
|
const read = readAnimatable(v);
|
|
@@ -3124,58 +4097,2159 @@ function numRange(v) {
|
|
|
3124
4097
|
const vals = read.keyframes.map((k) => Number(k.value) || 0);
|
|
3125
4098
|
return { min: Math.min(...vals), max: Math.max(...vals) };
|
|
3126
4099
|
}
|
|
3127
|
-
return { min: 0, max: 0 };
|
|
4100
|
+
return { min: 0, max: 0 };
|
|
4101
|
+
}
|
|
4102
|
+
function estimateTextAdvance(node) {
|
|
4103
|
+
let chars = 0, maxFont = 16;
|
|
4104
|
+
const walk = (el) => {
|
|
4105
|
+
var _a2;
|
|
4106
|
+
const fs = parseFloat(String((_a2 = el.fontSize) != null ? _a2 : "")) || 0;
|
|
4107
|
+
if (fs) maxFont = Math.max(maxFont, fs);
|
|
4108
|
+
const t = el.textContent;
|
|
4109
|
+
if (typeof t === "string") chars += t.length;
|
|
4110
|
+
if (el.children) for (const c of el.children) walk(c);
|
|
4111
|
+
};
|
|
4112
|
+
walk(node);
|
|
4113
|
+
return chars * maxFont;
|
|
4114
|
+
}
|
|
4115
|
+
var r3 = (n) => Math.round(n * 1e3) / 1e3;
|
|
4116
|
+
function shiftAnimatable(v, by) {
|
|
4117
|
+
if (!by || v === void 0 || v === null) return v;
|
|
4118
|
+
const read = readAnimatable(v);
|
|
4119
|
+
if (read.kind === "absent" /* Absent */) return v;
|
|
4120
|
+
if (read.kind === "static" /* Static */) return typeof v === "number" ? read.value + by : { value: read.value + by };
|
|
4121
|
+
const out = {
|
|
4122
|
+
keyframes: read.keyframes.map((k) => __spreadProps(__spreadValues({}, k), { value: (Number(k.value) || 0) + by }))
|
|
4123
|
+
};
|
|
4124
|
+
if (read.loop !== void 0) out.loop = read.loop;
|
|
4125
|
+
if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
|
|
4126
|
+
if (read.base !== void 0) out.value = read.base + by;
|
|
4127
|
+
return out;
|
|
4128
|
+
}
|
|
4129
|
+
function extendedPathForBrowser(pathD, opts) {
|
|
4130
|
+
var _a2;
|
|
4131
|
+
if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
|
|
4132
|
+
const sampler = createPathSampler(pathD);
|
|
4133
|
+
if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
|
|
4134
|
+
const L = sampler.totalLength;
|
|
4135
|
+
const margin = EXTEND_MARGIN_FRAC * L;
|
|
4136
|
+
const so = numRange(opts.startOffset);
|
|
4137
|
+
const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
|
|
4138
|
+
const startOverflow = Math.max(0, -so.min);
|
|
4139
|
+
const endOverflow = Math.max(0, so.max + runWidth - L);
|
|
4140
|
+
const startExt = startOverflow > 0 ? startOverflow + margin : 0;
|
|
4141
|
+
const endExt = endOverflow > 0 ? endOverflow + margin : 0;
|
|
4142
|
+
if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };
|
|
4143
|
+
const s = sampler.sampleAtDistance(0);
|
|
4144
|
+
const e = sampler.sampleAtDistance(L);
|
|
4145
|
+
let d = pathD;
|
|
4146
|
+
if (startExt > 0) {
|
|
4147
|
+
const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;
|
|
4148
|
+
const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
|
|
4149
|
+
d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
|
|
4150
|
+
}
|
|
4151
|
+
if (endExt > 0) {
|
|
4152
|
+
const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
|
|
4153
|
+
d += "L" + r3(ex) + "," + r3(ey);
|
|
4154
|
+
}
|
|
4155
|
+
return { d, startShift: startExt };
|
|
4156
|
+
}
|
|
4157
|
+
function applyTextPathEffect(node, fx, ctx) {
|
|
4158
|
+
var _a2;
|
|
4159
|
+
if (!fx || typeof fx.pathData !== "string" || !fx.pathData) return node;
|
|
4160
|
+
const pathId = genId(ctx, "tpath");
|
|
4161
|
+
const { d, startShift } = extendedPathForBrowser(fx.pathData, {
|
|
4162
|
+
pathOverflow: fx.pathOverflow,
|
|
4163
|
+
startOffset: fx.startOffset,
|
|
4164
|
+
textLength: fx.textLength,
|
|
4165
|
+
advance: estimateTextAdvance(node)
|
|
4166
|
+
});
|
|
4167
|
+
ctx.defs.push({ type: "path", id: pathId, d });
|
|
4168
|
+
const textPath = {
|
|
4169
|
+
type: "textPath",
|
|
4170
|
+
href: "#" + pathId,
|
|
4171
|
+
children: (_a2 = node.children) != null ? _a2 : []
|
|
4172
|
+
};
|
|
4173
|
+
if (fx.lengthAdjust !== void 0) textPath.lengthAdjust = fx.lengthAdjust;
|
|
4174
|
+
if (fx.method !== void 0) textPath.method = fx.method;
|
|
4175
|
+
if (fx.spacing !== void 0) textPath.spacing = fx.spacing;
|
|
4176
|
+
applyAnimatableNumber(textPath, "startOffset", shiftAnimatable(fx.startOffset, startShift));
|
|
4177
|
+
applyAnimatableNumber(textPath, "textLength", fx.textLength);
|
|
4178
|
+
node.children = [textPath];
|
|
4179
|
+
return node;
|
|
4180
|
+
}
|
|
4181
|
+
function applyAnimatableNumber(node, attrName, raw) {
|
|
4182
|
+
if (raw === void 0 || raw === null) return;
|
|
4183
|
+
writeAnimatableChannel(node, attrName, readAnimatable(raw), { asString: true });
|
|
4184
|
+
}
|
|
4185
|
+
|
|
4186
|
+
// src/format/PxDocumentDiagnostic.ts
|
|
4187
|
+
var MAX_REPORTED = 6;
|
|
4188
|
+
function diagnoseDocument(doc) {
|
|
4189
|
+
try {
|
|
4190
|
+
return { problems: validateDocument(doc) };
|
|
4191
|
+
} catch (e) {
|
|
4192
|
+
return { problems: [] };
|
|
4193
|
+
}
|
|
4194
|
+
}
|
|
4195
|
+
function reportDocumentDiagnostics(doc, where) {
|
|
4196
|
+
const { problems } = diagnoseDocument(doc);
|
|
4197
|
+
if (!problems.length) return;
|
|
4198
|
+
const shown = problems.slice(0, MAX_REPORTED);
|
|
4199
|
+
const more = problems.length - shown.length;
|
|
4200
|
+
console.warn(
|
|
4201
|
+
where + ": this document does not match the animation schema in " + problems.length + " place" + (problems.length === 1 ? "" : "s") + ".\n" + shown.map((p) => " - " + p).join("\n") + (more > 0 ? "\n \u2026 and " + more + " more" : "") + "\n\nIf you did not author these keys, the usual cause is a build that MANGLES PROPERTY NAMES. An animation document is data loaded at runtime, so renaming the property reads inside the player stops them matching the keys in the JSON, and the animation silently does nothing. Feed the published reserved-name list to your minifier \u2014 @pixodesk/svg-animator-web/mangle-reserved.json \u2014 see docs/library/minification.md."
|
|
4202
|
+
);
|
|
4203
|
+
}
|
|
4204
|
+
|
|
4205
|
+
// src/effects/transform/transformationEffect.ts
|
|
4206
|
+
function applyTransformByEffect(node, fx, ctx) {
|
|
4207
|
+
if (!fx) return node;
|
|
4208
|
+
delete node.transform;
|
|
4209
|
+
let n = node;
|
|
4210
|
+
n = wrapOrigin(
|
|
4211
|
+
n,
|
|
4212
|
+
fx.origin,
|
|
4213
|
+
/*invert=*/
|
|
4214
|
+
true
|
|
4215
|
+
);
|
|
4216
|
+
n = wrapTransformPart(n, "scale" /* Scale */, normalizeScale(fx.scale), ctx);
|
|
4217
|
+
n = wrapTransformPart(n, "skew" /* Skew */, fx.skew, ctx);
|
|
4218
|
+
n = wrapTransformPart(n, "rotate" /* Rotate */, fx.rotate, ctx);
|
|
4219
|
+
n = wrapOrigin(
|
|
4220
|
+
n,
|
|
4221
|
+
fx.origin,
|
|
4222
|
+
/*invert=*/
|
|
4223
|
+
false
|
|
4224
|
+
);
|
|
4225
|
+
if (translateHasAutoOrient(fx.translate)) {
|
|
4226
|
+
n = wrapOrigin(
|
|
4227
|
+
n,
|
|
4228
|
+
fx.origin,
|
|
4229
|
+
/*invert=*/
|
|
4230
|
+
true
|
|
4231
|
+
);
|
|
4232
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
4233
|
+
n = wrapOrigin(
|
|
4234
|
+
n,
|
|
4235
|
+
fx.origin,
|
|
4236
|
+
/*invert=*/
|
|
4237
|
+
false
|
|
4238
|
+
);
|
|
4239
|
+
} else {
|
|
4240
|
+
n = wrapTransformPart(n, "translate" /* Translate */, fx.translate, ctx);
|
|
4241
|
+
}
|
|
4242
|
+
if (n !== node && node.id) {
|
|
4243
|
+
n.id = node.id;
|
|
4244
|
+
delete node.id;
|
|
4245
|
+
}
|
|
4246
|
+
return n;
|
|
4247
|
+
}
|
|
4248
|
+
function translateHasAutoOrient(translate) {
|
|
4249
|
+
if (!translate || typeof translate !== "object") return false;
|
|
4250
|
+
const obj = translate;
|
|
4251
|
+
if (obj.autoOrient) return true;
|
|
4252
|
+
return Array.isArray(obj.keyframes) && obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
4253
|
+
}
|
|
4254
|
+
function normalizeScale(raw) {
|
|
4255
|
+
return raw;
|
|
4256
|
+
}
|
|
4257
|
+
function wrapTransformPart(inner, part, raw, ctx) {
|
|
4258
|
+
if (raw === void 0) return inner;
|
|
4259
|
+
const v = readAnimatable(raw);
|
|
4260
|
+
if (v.kind === "static" /* Static */) {
|
|
4261
|
+
return { type: "g", transform: { value: partsRecord(part, v.value, void 0) }, children: [inner] };
|
|
4262
|
+
}
|
|
4263
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4264
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, partsRecord(part, kf.value, void 0))) };
|
|
4265
|
+
if (v.autoOrient) animTr.autoOrient = true;
|
|
4266
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4267
|
+
return {
|
|
4268
|
+
type: "g",
|
|
4269
|
+
animate: { transform: animTr },
|
|
4270
|
+
children: [inner]
|
|
4271
|
+
};
|
|
4272
|
+
}
|
|
4273
|
+
return inner;
|
|
4274
|
+
}
|
|
4275
|
+
function wrapOrigin(inner, raw, invert) {
|
|
4276
|
+
if (raw === void 0) return inner;
|
|
4277
|
+
const v = readAnimatable(raw);
|
|
4278
|
+
const sign = (value) => invert ? [-value[0], -value[1]] : value;
|
|
4279
|
+
if (v.kind === "absent" /* Absent */) return inner;
|
|
4280
|
+
if (v.kind === "static" /* Static */) {
|
|
4281
|
+
if (v.value[0] === 0 && v.value[1] === 0) return inner;
|
|
4282
|
+
return { type: "g", transform: { value: { translate: sign(v.value) } }, children: [inner] };
|
|
4283
|
+
}
|
|
4284
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4285
|
+
const animTr = { keyframes: v.keyframes.map((kf) => keyframeWith(kf, { translate: sign(kf.value) })) };
|
|
4286
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4287
|
+
return {
|
|
4288
|
+
type: "g",
|
|
4289
|
+
animate: { transform: animTr },
|
|
4290
|
+
children: [inner]
|
|
4291
|
+
};
|
|
4292
|
+
}
|
|
4293
|
+
return inner;
|
|
4294
|
+
}
|
|
4295
|
+
|
|
4296
|
+
// src/effects/reference/contentRefSplit.ts
|
|
4297
|
+
function identifyContentRefTargets(node, ctx, allocator) {
|
|
4298
|
+
var _a2, _b, _c;
|
|
4299
|
+
if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
|
|
4300
|
+
const sourceId = stripHash(node.effects.clone.source);
|
|
4301
|
+
if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
|
|
4302
|
+
ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
(_c = node.children) == null ? void 0 : _c.forEach((c) => identifyContentRefTargets(c, ctx, allocator));
|
|
4306
|
+
}
|
|
4307
|
+
function splitForContentRef(node, transformBy, originalId, innerId, ctx) {
|
|
4308
|
+
const outerBody = liftBodyTranslate(node, transformBy);
|
|
4309
|
+
if (typeof node.id === "string") delete node.id;
|
|
4310
|
+
const { outer: outerTr, inner: innerTr } = splitTransformByEffect(transformBy);
|
|
4311
|
+
let innerNode = node;
|
|
4312
|
+
innerNode = applyTransformByEffect(innerNode, innerTr, ctx);
|
|
4313
|
+
const innerWrapper = { type: "g", id: innerId, children: [innerNode] };
|
|
4314
|
+
let outerWrapper = { type: "g", id: originalId, children: [innerWrapper] };
|
|
4315
|
+
if (outerBody.transform !== void 0) outerWrapper.transform = outerBody.transform;
|
|
4316
|
+
if (outerBody.animate !== void 0) outerWrapper.animate = outerBody.animate;
|
|
4317
|
+
if (outerTr) {
|
|
4318
|
+
delete outerWrapper.id;
|
|
4319
|
+
outerWrapper = applyTransformByEffect(outerWrapper, outerTr, ctx);
|
|
4320
|
+
outerWrapper.id = originalId;
|
|
4321
|
+
}
|
|
4322
|
+
return outerWrapper;
|
|
4323
|
+
}
|
|
4324
|
+
function liftBodyTranslate(node, transformBy) {
|
|
4325
|
+
var _a2, _b, _c;
|
|
4326
|
+
const out = {};
|
|
4327
|
+
let didLiftAnimate = false;
|
|
4328
|
+
const animTr = (_a2 = node.animate) == null ? void 0 : _a2.transform;
|
|
4329
|
+
if (animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes)) {
|
|
4330
|
+
const kfs = animTr.keyframes;
|
|
4331
|
+
const hasTranslate = kfs.some((kf) => kf.value && kf.value.translate);
|
|
4332
|
+
if (hasTranslate) {
|
|
4333
|
+
const outerHasOrigin = needsOriginOnOuter(animTr);
|
|
4334
|
+
const outerKfs = kfs.map((kf) => {
|
|
4335
|
+
const v = kf.value || {};
|
|
4336
|
+
const newValue = {};
|
|
4337
|
+
if (v.translate !== void 0) newValue.translate = v.translate;
|
|
4338
|
+
if (outerHasOrigin && v.origin !== void 0) newValue.origin = v.origin;
|
|
4339
|
+
const outerKf = { value: newValue };
|
|
4340
|
+
if (kf.time !== void 0) outerKf.time = kf.time;
|
|
4341
|
+
if (kf.easing !== void 0) outerKf.easing = kf.easing;
|
|
4342
|
+
if (kf.tangentOut !== void 0) outerKf.tangentOut = kf.tangentOut;
|
|
4343
|
+
if (kf.tangentIn !== void 0) outerKf.tangentIn = kf.tangentIn;
|
|
4344
|
+
return outerKf;
|
|
4345
|
+
});
|
|
4346
|
+
const outerAnimTr = { keyframes: outerKfs };
|
|
4347
|
+
if (animTr.autoOrient) outerAnimTr.autoOrient = true;
|
|
4348
|
+
const srcLoop = animTr.loop;
|
|
4349
|
+
if (srcLoop !== void 0) outerAnimTr.loop = srcLoop;
|
|
4350
|
+
out.animate = { transform: outerAnimTr };
|
|
4351
|
+
const innerHasPivotedPart = kfs.some((kf) => {
|
|
4352
|
+
const v = kf.value || {};
|
|
4353
|
+
return v.rotate !== void 0 || v.scale !== void 0;
|
|
4354
|
+
});
|
|
4355
|
+
const innerKfs = kfs.map((kf) => {
|
|
4356
|
+
const v = kf.value || {};
|
|
4357
|
+
const newValue = {};
|
|
4358
|
+
if (v.rotate !== void 0) newValue.rotate = v.rotate;
|
|
4359
|
+
if (v.scale !== void 0) newValue.scale = v.scale;
|
|
4360
|
+
if (v.origin !== void 0 && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;
|
|
4361
|
+
const innerKf = { value: newValue };
|
|
4362
|
+
if (kf.time !== void 0) innerKf.time = kf.time;
|
|
4363
|
+
if (kf.easing !== void 0) innerKf.easing = kf.easing;
|
|
4364
|
+
return innerKf;
|
|
4365
|
+
});
|
|
4366
|
+
const allInnerEmpty = innerKfs.every((kf) => Object.keys(kf.value).length === 0);
|
|
4367
|
+
if (allInnerEmpty) {
|
|
4368
|
+
delete node.animate.transform;
|
|
4369
|
+
if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;
|
|
4370
|
+
} else {
|
|
4371
|
+
const innerAnimTr = { keyframes: innerKfs };
|
|
4372
|
+
if (srcLoop !== void 0) innerAnimTr.loop = srcLoop;
|
|
4373
|
+
node.animate.transform = innerAnimTr;
|
|
4374
|
+
}
|
|
4375
|
+
didLiftAnimate = true;
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
const transformationHasTranslate = (transformBy == null ? void 0 : transformBy.translate) !== void 0;
|
|
4379
|
+
const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;
|
|
4380
|
+
const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter(((_b = node.animate) == null ? void 0 : _b.transform) || void 0) || didLiftAnimate && needsOriginOnOuter(((_c = out.animate) == null ? void 0 : _c.transform) || void 0);
|
|
4381
|
+
if (typeof node.transform === "string") {
|
|
4382
|
+
const split = splitTransformString(node.transform);
|
|
4383
|
+
if (stripBodyTranslateOnly) {
|
|
4384
|
+
if (split.translate !== void 0) {
|
|
4385
|
+
if (split.rest) node.transform = split.rest;
|
|
4386
|
+
else delete node.transform;
|
|
4387
|
+
} else if (isPureTranslateBody(node.transform)) {
|
|
4388
|
+
delete node.transform;
|
|
4389
|
+
} else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {
|
|
4390
|
+
delete node.transform;
|
|
4391
|
+
}
|
|
4392
|
+
} else if (split.translate) {
|
|
4393
|
+
out.transform = split.translate;
|
|
4394
|
+
if (split.rest) node.transform = split.rest;
|
|
4395
|
+
else delete node.transform;
|
|
4396
|
+
}
|
|
4397
|
+
} else if (node.transform && typeof node.transform === "object" && !Array.isArray(node.transform) && !node.transform.keyframes) {
|
|
4398
|
+
const wrapped = node.transform.value;
|
|
4399
|
+
const isWrapped = !!(wrapped && typeof wrapped === "object");
|
|
4400
|
+
const value = isWrapped ? wrapped : node.transform;
|
|
4401
|
+
const rewrap = (rec) => isWrapped ? { value: rec } : rec;
|
|
4402
|
+
if (Array.isArray(value.translate)) {
|
|
4403
|
+
const rest = __spreadValues({}, value);
|
|
4404
|
+
delete rest.translate;
|
|
4405
|
+
const hasRest = Object.keys(rest).length > 0;
|
|
4406
|
+
if (stripBodyTranslateOnly) {
|
|
4407
|
+
if (hasRest) node.transform = rewrap(rest);
|
|
4408
|
+
else delete node.transform;
|
|
4409
|
+
} else {
|
|
4410
|
+
out.transform = rewrap({ translate: value.translate });
|
|
4411
|
+
if (hasRest) node.transform = rewrap(rest);
|
|
4412
|
+
else delete node.transform;
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4415
|
+
}
|
|
4416
|
+
return out;
|
|
4417
|
+
}
|
|
4418
|
+
function isSingleMatrixBody(s) {
|
|
4419
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4420
|
+
let count = 0;
|
|
4421
|
+
let isMatrix = false;
|
|
4422
|
+
let m;
|
|
4423
|
+
while (m = re.exec(s)) {
|
|
4424
|
+
count++;
|
|
4425
|
+
if (m[1] === "matrix") isMatrix = true;
|
|
4426
|
+
}
|
|
4427
|
+
return count === 1 && isMatrix;
|
|
4428
|
+
}
|
|
4429
|
+
function isPureTranslateBody(s) {
|
|
4430
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4431
|
+
const ops = [];
|
|
4432
|
+
let m;
|
|
4433
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
4434
|
+
if (ops.length !== 1) return false;
|
|
4435
|
+
if (ops[0].name === "translate") return true;
|
|
4436
|
+
if (ops[0].name !== "matrix") return false;
|
|
4437
|
+
const args = /matrix\(([^)]*)\)/.exec(ops[0].full);
|
|
4438
|
+
if (!args) return false;
|
|
4439
|
+
const nums = args[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
4440
|
+
return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;
|
|
4441
|
+
}
|
|
4442
|
+
function splitTransformString(s) {
|
|
4443
|
+
const ops = [];
|
|
4444
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
4445
|
+
let m;
|
|
4446
|
+
while (m = re.exec(s)) ops.push({ name: m[1], full: m[0] });
|
|
4447
|
+
if (!ops.length) return { rest: s || void 0 };
|
|
4448
|
+
if (ops.every((o) => o.name === "translate")) {
|
|
4449
|
+
return { translate: ops.map((o) => o.full).join("") };
|
|
4450
|
+
}
|
|
4451
|
+
const leading = ops[0];
|
|
4452
|
+
const trailing = ops[ops.length - 1];
|
|
4453
|
+
if (trailing.name === "translate" && leading.name === "translate") {
|
|
4454
|
+
const trailingVec = parseTranslateArgs(trailing.full);
|
|
4455
|
+
const leadingVec = parseTranslateArgs(leading.full);
|
|
4456
|
+
const ox = -trailingVec[0];
|
|
4457
|
+
const oy = -trailingVec[1];
|
|
4458
|
+
const userTx = leadingVec[0] - ox;
|
|
4459
|
+
const userTy = leadingVec[1] - oy;
|
|
4460
|
+
if (userTx === 0 && userTy === 0) return { rest: s };
|
|
4461
|
+
const middleAndTrailing = "translate(" + ox + "," + oy + ")" + ops.slice(1).map((o) => o.full).join("");
|
|
4462
|
+
return { translate: "translate(" + userTx + "," + userTy + ")", rest: middleAndTrailing };
|
|
4463
|
+
}
|
|
4464
|
+
if (trailing.name === "translate") return { rest: s };
|
|
4465
|
+
const lifted = [];
|
|
4466
|
+
let i = 0;
|
|
4467
|
+
while (i < ops.length && ops[i].name === "translate") {
|
|
4468
|
+
lifted.push(ops[i].full);
|
|
4469
|
+
i++;
|
|
4470
|
+
}
|
|
4471
|
+
if (!lifted.length) return { rest: s };
|
|
4472
|
+
const rest = ops.slice(i).map((o) => o.full).join("");
|
|
4473
|
+
return {
|
|
4474
|
+
translate: lifted.join(""),
|
|
4475
|
+
rest: rest || void 0
|
|
4476
|
+
};
|
|
4477
|
+
}
|
|
4478
|
+
function parseTranslateArgs(translateOp) {
|
|
4479
|
+
const m = /translate\(([^)]*)\)/.exec(translateOp);
|
|
4480
|
+
if (!m) return [0, 0];
|
|
4481
|
+
const nums = m[1].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
4482
|
+
return [nums[0] || 0, nums[1] || 0];
|
|
4483
|
+
}
|
|
4484
|
+
function splitTransformByEffect(fx) {
|
|
4485
|
+
if (!fx) return {};
|
|
4486
|
+
const originOnOuter = needsOriginOnOuter(fx.translate);
|
|
4487
|
+
const innerHasPivotedPart = fx.rotate !== void 0 || fx.scale !== void 0;
|
|
4488
|
+
const outer = {};
|
|
4489
|
+
const inner = {};
|
|
4490
|
+
if (fx.translate !== void 0) outer.translate = fx.translate;
|
|
4491
|
+
if (originOnOuter && fx.origin !== void 0) outer.origin = fx.origin;
|
|
4492
|
+
if (fx.rotate !== void 0) inner.rotate = fx.rotate;
|
|
4493
|
+
if (fx.scale !== void 0) inner.scale = fx.scale;
|
|
4494
|
+
if (fx.skew !== void 0) inner.skew = fx.skew;
|
|
4495
|
+
if (fx.origin !== void 0 && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;
|
|
4496
|
+
return {
|
|
4497
|
+
outer: Object.keys(outer).length ? outer : void 0,
|
|
4498
|
+
inner: Object.keys(inner).length ? inner : void 0
|
|
4499
|
+
};
|
|
4500
|
+
}
|
|
4501
|
+
function needsOriginOnOuter(translateAnim) {
|
|
4502
|
+
if (!translateAnim || typeof translateAnim !== "object") return false;
|
|
4503
|
+
const obj = translateAnim;
|
|
4504
|
+
if (obj.autoOrient) return true;
|
|
4505
|
+
if (Array.isArray(obj.keyframes)) {
|
|
4506
|
+
return obj.keyframes.some((kf) => kf.tangentOut || kf.tangentIn);
|
|
4507
|
+
}
|
|
4508
|
+
return false;
|
|
4509
|
+
}
|
|
4510
|
+
|
|
4511
|
+
// src/effects/paint/gradientEffect.ts
|
|
4512
|
+
function applyFillGradientEffect(node, fx, ctx) {
|
|
4513
|
+
return applyGradient(node, fx, ctx, "fill");
|
|
4514
|
+
}
|
|
4515
|
+
function applyStrokeGradientEffect(node, fx, ctx) {
|
|
4516
|
+
return applyGradient(node, fx, ctx, "stroke");
|
|
4517
|
+
}
|
|
4518
|
+
function applyGradient(node, fx, ctx, attr) {
|
|
4519
|
+
if (!fx) return node;
|
|
4520
|
+
const id = genId(ctx, "grad");
|
|
4521
|
+
const def = synthesiseGradientDef(fx, id, ctx);
|
|
4522
|
+
ctx.defs.push(def);
|
|
4523
|
+
node[attr] = "url(#" + id + ")";
|
|
4524
|
+
return node;
|
|
4525
|
+
}
|
|
4526
|
+
function synthesiseGradientDef(fx, id, ctx) {
|
|
4527
|
+
const out = {
|
|
4528
|
+
type: fx.type === PxGradientType.radial ? "radialGradient" : "linearGradient",
|
|
4529
|
+
id
|
|
4530
|
+
};
|
|
4531
|
+
if (fx.type === PxGradientType.linear) {
|
|
4532
|
+
applyGeomVec(out, "x1", "y1", fx.start);
|
|
4533
|
+
applyGeomVec(out, "x2", "y2", fx.end);
|
|
4534
|
+
} else {
|
|
4535
|
+
applyGeomVec(out, "cx", "cy", fx.center);
|
|
4536
|
+
applyGeomNumber(out, "r", fx.radius);
|
|
4537
|
+
applyGeomVec(out, "fx", "fy", fx.focal);
|
|
4538
|
+
}
|
|
4539
|
+
if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;
|
|
4540
|
+
if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;
|
|
4541
|
+
if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;
|
|
4542
|
+
out.children = buildStopChildren(fx.stops, ctx);
|
|
4543
|
+
return out;
|
|
4544
|
+
}
|
|
4545
|
+
function applyGeomVec(out, xAttr, yAttr, raw) {
|
|
4546
|
+
var _a2, _b, _c;
|
|
4547
|
+
const read = readAnimatable(raw);
|
|
4548
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
4549
|
+
if (read.kind === "static" /* Static */) {
|
|
4550
|
+
out[xAttr] = String(read.value[0]);
|
|
4551
|
+
out[yAttr] = String(read.value[1]);
|
|
4552
|
+
return;
|
|
4553
|
+
}
|
|
4554
|
+
const axisChannel = (idx) => {
|
|
4555
|
+
const block = {
|
|
4556
|
+
keyframes: read.keyframes.map((kf) => {
|
|
4557
|
+
const axisKf = { time: kf.time, value: Array.isArray(kf.value) ? kf.value[idx] : void 0 };
|
|
4558
|
+
if (kf.easing !== void 0) axisKf.easing = kf.easing;
|
|
4559
|
+
return axisKf;
|
|
4560
|
+
})
|
|
4561
|
+
};
|
|
4562
|
+
if (read.loop !== void 0) block.loop = read.loop;
|
|
4563
|
+
return block;
|
|
4564
|
+
};
|
|
4565
|
+
const animate = (_a2 = out.animate) != null ? _a2 : {};
|
|
4566
|
+
animate[xAttr] = axisChannel(0);
|
|
4567
|
+
animate[yAttr] = axisChannel(1);
|
|
4568
|
+
out.animate = animate;
|
|
4569
|
+
const baseline = (_c = read.base) != null ? _c : (_b = read.keyframes[0]) == null ? void 0 : _b.value;
|
|
4570
|
+
if (Array.isArray(baseline)) {
|
|
4571
|
+
out[xAttr] = String(baseline[0]);
|
|
4572
|
+
out[yAttr] = String(baseline[1]);
|
|
4573
|
+
}
|
|
4574
|
+
}
|
|
4575
|
+
function applyGeomNumber(out, attrName, raw) {
|
|
4576
|
+
const read = readAnimatable(raw);
|
|
4577
|
+
if (read.kind === "absent" /* Absent */) return;
|
|
4578
|
+
writeAnimatableChannel(out, attrName, read, { asString: true });
|
|
4579
|
+
}
|
|
4580
|
+
function buildStopChildren(stops, ctx) {
|
|
4581
|
+
var _a2, _b;
|
|
4582
|
+
if (!stops) return [];
|
|
4583
|
+
const read = readAnimatable(stops);
|
|
4584
|
+
if (read.kind === "absent" /* Absent */) return [];
|
|
4585
|
+
if (read.kind === "static" /* Static */) return Array.isArray(read.value) ? read.value.map(staticStopNode) : [];
|
|
4586
|
+
const kfs = read.keyframes;
|
|
4587
|
+
if (!kfs.length) return [];
|
|
4588
|
+
const loopFromSource = read.loop;
|
|
4589
|
+
let stopCount = 0;
|
|
4590
|
+
for (const kf of kfs) {
|
|
4591
|
+
const v = keyframeValue(kf);
|
|
4592
|
+
if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
|
|
4593
|
+
}
|
|
4594
|
+
if (!stopCount) return [];
|
|
4595
|
+
const firstKfValue = keyframeValue(kfs[0]);
|
|
4596
|
+
const baselineStops = [];
|
|
4597
|
+
for (let i = 0; i < stopCount; i++) {
|
|
4598
|
+
const s = (_b = (_a2 = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a2 : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
|
|
4599
|
+
baselineStops.push({ offset: s.offset, color: s.color });
|
|
4600
|
+
}
|
|
4601
|
+
return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));
|
|
4602
|
+
}
|
|
4603
|
+
function staticStopNode(s) {
|
|
4604
|
+
return {
|
|
4605
|
+
type: "stop",
|
|
4606
|
+
offset: formatOffset(s.offset),
|
|
4607
|
+
stopColor: s.color
|
|
4608
|
+
};
|
|
4609
|
+
}
|
|
4610
|
+
function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
|
|
4611
|
+
var _a2;
|
|
4612
|
+
const colorKfs = [];
|
|
4613
|
+
const offsetKfs = [];
|
|
4614
|
+
let offsetVaries = false;
|
|
4615
|
+
for (const kf of kfs) {
|
|
4616
|
+
const t = keyframeTime(kf);
|
|
4617
|
+
const arr = keyframeValue(kf);
|
|
4618
|
+
const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
|
|
4619
|
+
if (!sliced) continue;
|
|
4620
|
+
const easing = keyframeEasing(kf);
|
|
4621
|
+
const colorOut = { time: t, value: sliced.color };
|
|
4622
|
+
if (easing !== void 0) colorOut.easing = easing;
|
|
4623
|
+
colorKfs.push(colorOut);
|
|
4624
|
+
const offsetOut = { time: t, value: sliced.offset };
|
|
4625
|
+
if (easing !== void 0) offsetOut.easing = easing;
|
|
4626
|
+
offsetKfs.push(offsetOut);
|
|
4627
|
+
if (sliced.offset !== baseline.offset) offsetVaries = true;
|
|
4628
|
+
}
|
|
4629
|
+
const stop = {
|
|
4630
|
+
type: "stop",
|
|
4631
|
+
offset: formatOffset(baseline.offset),
|
|
4632
|
+
stopColor: baseline.color
|
|
4633
|
+
};
|
|
4634
|
+
const animate = {};
|
|
4635
|
+
if (colorKfs.length) {
|
|
4636
|
+
animate.stopColor = { keyframes: colorKfs };
|
|
4637
|
+
if (loop !== void 0) animate.stopColor.loop = loop;
|
|
4638
|
+
}
|
|
4639
|
+
if (offsetVaries && offsetKfs.length) {
|
|
4640
|
+
animate.offset = { keyframes: offsetKfs };
|
|
4641
|
+
if (loop !== void 0) animate.offset.loop = loop;
|
|
4642
|
+
}
|
|
4643
|
+
if (Object.keys(animate).length) stop.animate = animate;
|
|
4644
|
+
return stop;
|
|
4645
|
+
}
|
|
4646
|
+
function prevDefinedStop(kfs, fromIdx, stopIdx) {
|
|
4647
|
+
for (let i = fromIdx; i >= 0; i--) {
|
|
4648
|
+
const arr = keyframeValue(kfs[i]);
|
|
4649
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
4650
|
+
}
|
|
4651
|
+
for (let i = fromIdx + 1; i < kfs.length; i++) {
|
|
4652
|
+
const arr = keyframeValue(kfs[i]);
|
|
4653
|
+
if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
|
|
4654
|
+
}
|
|
4655
|
+
return void 0;
|
|
4656
|
+
}
|
|
4657
|
+
function formatOffset(o) {
|
|
4658
|
+
const pct = Math.round(o * 1e3) / 10;
|
|
4659
|
+
return pct + "%";
|
|
4660
|
+
}
|
|
4661
|
+
|
|
4662
|
+
// src/effects/clipping/clipPathEffect.ts
|
|
4663
|
+
function applyClipPathEffect(node, fx, ctx) {
|
|
4664
|
+
if (!(fx == null ? void 0 : fx.pathData)) return node;
|
|
4665
|
+
const clipId = genId(ctx, "clip");
|
|
4666
|
+
const pathChild = { type: "path" };
|
|
4667
|
+
const read = readAnimatable(fx.pathData);
|
|
4668
|
+
if (read.kind !== "absent" /* Absent */) {
|
|
4669
|
+
if (read.kind === "static" /* Static */) {
|
|
4670
|
+
pathChild.d = pathString(read.value);
|
|
4671
|
+
} else {
|
|
4672
|
+
writeAnimatableChannel(pathChild, "d", read);
|
|
4673
|
+
if (pathChild.d !== void 0) pathChild.d = pathString(pathChild.d);
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
ctx.defs.push({ type: "clipPath", id: clipId, children: [pathChild] });
|
|
4677
|
+
node.clipPath = "url(#" + clipId + ")";
|
|
4678
|
+
return node;
|
|
4679
|
+
}
|
|
4680
|
+
function pathString(v) {
|
|
4681
|
+
if (typeof v === "string") return v;
|
|
4682
|
+
if (v && typeof v === "object" && typeof v.pathData === "string") return v.pathData;
|
|
4683
|
+
return void 0;
|
|
4684
|
+
}
|
|
4685
|
+
|
|
4686
|
+
// src/effects/clipping/maskedByEffect.ts
|
|
4687
|
+
function applyMaskedByEffect(node, fx, transformBy, ctx) {
|
|
4688
|
+
if (!fx) return node;
|
|
4689
|
+
const sourceId = stripHash(fx.source);
|
|
4690
|
+
if (!sourceId) {
|
|
4691
|
+
ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
|
|
4692
|
+
return node;
|
|
4693
|
+
}
|
|
4694
|
+
const maskId = genId(ctx, "mask");
|
|
4695
|
+
let content = { type: "use", href: "#" + sourceId };
|
|
4696
|
+
if (transformBy) {
|
|
4697
|
+
content = wrapInverseTransform(content, transformBy, ctx);
|
|
4698
|
+
} else if (hasAnimateTransform(node)) {
|
|
4699
|
+
content = wrapInverseAnimatedBodyTransform(content, node, ctx);
|
|
4700
|
+
} else {
|
|
4701
|
+
const bodyStatic = readTransformationFromBody(node);
|
|
4702
|
+
if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);
|
|
4703
|
+
}
|
|
4704
|
+
const includeTargetOwn = transformBy === void 0 && !nodeHasBodyTransform(node);
|
|
4705
|
+
content = wrapAncestorChainCompensation(content, node, sourceId, ctx, includeTargetOwn);
|
|
4706
|
+
const mask = { type: "mask", id: maskId, children: [content] };
|
|
4707
|
+
if (fx.maskType) mask.maskType = fx.maskType;
|
|
4708
|
+
if (fx.maskUnits) mask.maskUnits = fx.maskUnits;
|
|
4709
|
+
if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;
|
|
4710
|
+
if (fx.x !== void 0) mask.x = String(fx.x);
|
|
4711
|
+
if (fx.y !== void 0) mask.y = String(fx.y);
|
|
4712
|
+
if (fx.width !== void 0) mask.width = String(fx.width);
|
|
4713
|
+
if (fx.height !== void 0) mask.height = String(fx.height);
|
|
4714
|
+
ctx.defs.push(mask);
|
|
4715
|
+
node.mask = "url(#" + maskId + ")";
|
|
4716
|
+
return node;
|
|
4717
|
+
}
|
|
4718
|
+
function wrapInverseTransform(inner, fx, ctx) {
|
|
4719
|
+
if (!fx) return inner;
|
|
4720
|
+
const origin = readStaticOrigin(fx.origin, ctx);
|
|
4721
|
+
let n = inner;
|
|
4722
|
+
n = wrapInversePart(n, "translate" /* Translate */, fx.translate, void 0, ctx);
|
|
4723
|
+
n = wrapInversePart(n, "rotate" /* Rotate */, fx.rotate, origin, ctx);
|
|
4724
|
+
n = wrapInversePart(n, "scale" /* Scale */, fx.scale, origin, ctx);
|
|
4725
|
+
return n;
|
|
4726
|
+
}
|
|
4727
|
+
function wrapInversePart(inner, part, raw, origin, ctx) {
|
|
4728
|
+
if (raw === void 0) return inner;
|
|
4729
|
+
const normalizedRaw = part === "scale" /* Scale */ && Array.isArray(raw) ? [raw[0] / 100, raw[1] / 100] : raw;
|
|
4730
|
+
const v = readAnimatable(normalizedRaw);
|
|
4731
|
+
if (v.kind === "static" /* Static */) {
|
|
4732
|
+
return { type: "g", transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };
|
|
4733
|
+
}
|
|
4734
|
+
if (v.kind === "animated" /* Animated */) {
|
|
4735
|
+
const animTr = { keyframes: v.keyframes.map((kf) => {
|
|
4736
|
+
const out = keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin));
|
|
4737
|
+
return part === "translate" /* Translate */ ? __spreadValues(__spreadValues({}, out), negatedSpatialTangents(kf)) : out;
|
|
4738
|
+
}) };
|
|
4739
|
+
if (v.loop !== void 0) animTr.loop = v.loop;
|
|
4740
|
+
return {
|
|
4741
|
+
type: "g",
|
|
4742
|
+
animate: { transform: animTr },
|
|
4743
|
+
children: [inner]
|
|
4744
|
+
};
|
|
4745
|
+
}
|
|
4746
|
+
return inner;
|
|
4747
|
+
}
|
|
4748
|
+
function invertPartValue(part, value) {
|
|
4749
|
+
if (part === "translate" /* Translate */) return [-value[0], -value[1]];
|
|
4750
|
+
if (part === "rotate" /* Rotate */) return -value;
|
|
4751
|
+
return [1 / value[0], 1 / value[1]];
|
|
4752
|
+
}
|
|
4753
|
+
function negatedSpatialTangents(kf) {
|
|
4754
|
+
var _a2, _b;
|
|
4755
|
+
const out = {};
|
|
4756
|
+
const to = (_a2 = kf.tangentOut) != null ? _a2 : kf.to;
|
|
4757
|
+
const ti = (_b = kf.tangentIn) != null ? _b : kf.ti;
|
|
4758
|
+
if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];
|
|
4759
|
+
if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];
|
|
4760
|
+
return out;
|
|
4761
|
+
}
|
|
4762
|
+
function wrapInverseAnimatedBodyTransform(inner, node, _ctx) {
|
|
4763
|
+
var _a2;
|
|
4764
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
4765
|
+
const animTr = animate == null ? void 0 : animate.transform;
|
|
4766
|
+
const kfs = animTr && typeof animTr === "object" && Array.isArray(animTr.keyframes) ? animTr.keyframes : void 0;
|
|
4767
|
+
if (!kfs || !kfs.length) return inner;
|
|
4768
|
+
const translateKfs = [];
|
|
4769
|
+
const rotateKfs = [];
|
|
4770
|
+
const scaleKfs = [];
|
|
4771
|
+
for (const kf of kfs) {
|
|
4772
|
+
const v = ((_a2 = kf.value) != null ? _a2 : kf.v) || {};
|
|
4773
|
+
const baseKf = keyframeWith(kf, void 0);
|
|
4774
|
+
if (Array.isArray(v.translate)) {
|
|
4775
|
+
translateKfs.push(__spreadProps(__spreadValues(__spreadValues({}, baseKf), negatedSpatialTangents(kf)), { value: { translate: [-v.translate[0], -v.translate[1]] } }));
|
|
4776
|
+
}
|
|
4777
|
+
if (typeof v.rotate === "number") {
|
|
4778
|
+
const rec = { rotate: -v.rotate };
|
|
4779
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
4780
|
+
rotateKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
4781
|
+
}
|
|
4782
|
+
if (Array.isArray(v.scale)) {
|
|
4783
|
+
const rec = { scale: [1 / v.scale[0], 1 / v.scale[1]] };
|
|
4784
|
+
if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];
|
|
4785
|
+
scaleKfs.push(__spreadProps(__spreadValues({}, baseKf), { value: rec }));
|
|
4786
|
+
}
|
|
4787
|
+
}
|
|
4788
|
+
const srcLoop = animTr == null ? void 0 : animTr.loop;
|
|
4789
|
+
const withLoop = (kfs2) => {
|
|
4790
|
+
const block = { keyframes: kfs2 };
|
|
4791
|
+
if (srcLoop !== void 0) block.loop = srcLoop;
|
|
4792
|
+
return block;
|
|
4793
|
+
};
|
|
4794
|
+
let n = inner;
|
|
4795
|
+
if (translateKfs.length) n = { type: "g", animate: { transform: withLoop(translateKfs) }, children: [n] };
|
|
4796
|
+
if (rotateKfs.length) n = { type: "g", animate: { transform: withLoop(rotateKfs) }, children: [n] };
|
|
4797
|
+
if (scaleKfs.length) n = { type: "g", animate: { transform: withLoop(scaleKfs) }, children: [n] };
|
|
4798
|
+
return n;
|
|
4799
|
+
}
|
|
4800
|
+
function nodeHasBodyTransform(node) {
|
|
4801
|
+
if (typeof node.transform === "string") return true;
|
|
4802
|
+
if (node.transform && typeof node.transform === "object") return true;
|
|
4803
|
+
return hasAnimateTransform(node);
|
|
4804
|
+
}
|
|
4805
|
+
function hasAnimateTransform(node) {
|
|
4806
|
+
const animate = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate : void 0;
|
|
4807
|
+
return !!(animate && animate.transform);
|
|
4808
|
+
}
|
|
4809
|
+
function readTransformationFromBody(node) {
|
|
4810
|
+
if (typeof node.transform === "string") {
|
|
4811
|
+
const parts = parseTransformStringToParts(node.transform);
|
|
4812
|
+
if (!parts) return void 0;
|
|
4813
|
+
const out = {};
|
|
4814
|
+
if (parts.translate) out.translate = parts.translate;
|
|
4815
|
+
if (parts.rotate !== void 0) out.rotate = parts.rotate;
|
|
4816
|
+
if (parts.scale) out.scale = { value: parts.scale };
|
|
4817
|
+
if (parts.origin) out.origin = parts.origin;
|
|
4818
|
+
return Object.keys(out).length ? out : void 0;
|
|
4819
|
+
}
|
|
4820
|
+
if (node.transform && typeof node.transform === "object" && !node.transform.keyframes) {
|
|
4821
|
+
const wrapped = node.transform.value;
|
|
4822
|
+
const value = wrapped && typeof wrapped === "object" ? wrapped : node.transform;
|
|
4823
|
+
if (value && typeof value === "object") {
|
|
4824
|
+
const out = {};
|
|
4825
|
+
if (Array.isArray(value.translate)) out.translate = value.translate;
|
|
4826
|
+
if (typeof value.rotate === "number") out.rotate = value.rotate;
|
|
4827
|
+
if (typeof value.skew === "number") out.skew = value.skew;
|
|
4828
|
+
if (Array.isArray(value.scale)) out.scale = { value: value.scale };
|
|
4829
|
+
if (Array.isArray(value.origin)) out.origin = value.origin;
|
|
4830
|
+
return Object.keys(out).length ? out : void 0;
|
|
4831
|
+
}
|
|
4832
|
+
}
|
|
4833
|
+
return void 0;
|
|
4834
|
+
}
|
|
4835
|
+
function parseTransformStringToParts(s) {
|
|
4836
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
4837
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
4838
|
+
let m;
|
|
4839
|
+
const ops = [];
|
|
4840
|
+
while ((m = re.exec(s)) !== null) {
|
|
4841
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
4842
|
+
ops.push({ name: m[1], args });
|
|
4843
|
+
}
|
|
4844
|
+
if (!ops.length) return void 0;
|
|
4845
|
+
const last = ops[ops.length - 1];
|
|
4846
|
+
if (last.name === "translate") {
|
|
4847
|
+
for (let j = ops.length - 2; j >= 0; j--) {
|
|
4848
|
+
const cand = ops[j];
|
|
4849
|
+
if (cand.name !== "translate") continue;
|
|
4850
|
+
const ox = (_a2 = cand.args[0]) != null ? _a2 : 0;
|
|
4851
|
+
const oy = (_b = cand.args[1]) != null ? _b : 0;
|
|
4852
|
+
const lx = (_c = last.args[0]) != null ? _c : 0;
|
|
4853
|
+
const ly = (_d = last.args[1]) != null ? _d : 0;
|
|
4854
|
+
if (lx !== -ox || ly !== -oy) continue;
|
|
4855
|
+
const out2 = {};
|
|
4856
|
+
out2.origin = [ox, oy];
|
|
4857
|
+
for (let k = 0; k < j; k++) {
|
|
4858
|
+
if (ops[k].name === "translate") {
|
|
4859
|
+
const tx = (_e = ops[k].args[0]) != null ? _e : 0;
|
|
4860
|
+
const ty = (_f = ops[k].args[1]) != null ? _f : 0;
|
|
4861
|
+
out2.translate = out2.translate ? [out2.translate[0] + tx, out2.translate[1] + ty] : [tx, ty];
|
|
4862
|
+
}
|
|
4863
|
+
}
|
|
4864
|
+
for (let k = j + 1; k < ops.length - 1; k++) {
|
|
4865
|
+
const op = ops[k];
|
|
4866
|
+
if (op.name === "rotate") out2.rotate = ((_g = out2.rotate) != null ? _g : 0) + ((_h = op.args[0]) != null ? _h : 0);
|
|
4867
|
+
else if (op.name === "scale") {
|
|
4868
|
+
const sx = (_i = op.args[0]) != null ? _i : 1;
|
|
4869
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
4870
|
+
out2.scale = out2.scale ? [out2.scale[0] * sx, out2.scale[1] * sy] : [sx, sy];
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
return out2;
|
|
4874
|
+
}
|
|
4875
|
+
}
|
|
4876
|
+
let translate;
|
|
4877
|
+
let rotate;
|
|
4878
|
+
let scale;
|
|
4879
|
+
for (const op of ops) {
|
|
4880
|
+
if (op.name === "translate") {
|
|
4881
|
+
const dx = (_j = op.args[0]) != null ? _j : 0;
|
|
4882
|
+
const dy = (_k = op.args[1]) != null ? _k : 0;
|
|
4883
|
+
translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];
|
|
4884
|
+
} else if (op.name === "rotate") {
|
|
4885
|
+
rotate = (rotate != null ? rotate : 0) + ((_l = op.args[0]) != null ? _l : 0);
|
|
4886
|
+
} else if (op.name === "scale") {
|
|
4887
|
+
const sx = (_m = op.args[0]) != null ? _m : 1;
|
|
4888
|
+
const sy = op.args.length > 1 ? op.args[1] : sx;
|
|
4889
|
+
scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];
|
|
4890
|
+
}
|
|
4891
|
+
}
|
|
4892
|
+
const out = {};
|
|
4893
|
+
if (translate) out.translate = translate;
|
|
4894
|
+
if (rotate !== void 0) out.rotate = rotate;
|
|
4895
|
+
if (scale) out.scale = scale;
|
|
4896
|
+
return Object.keys(out).length ? out : void 0;
|
|
4897
|
+
}
|
|
4898
|
+
function wrapAncestorChainCompensation(inner, maskedNode, sourceId, ctx, includeTargetOwn) {
|
|
4899
|
+
const sourceNode = ctx.idMap.get(sourceId);
|
|
4900
|
+
const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];
|
|
4901
|
+
const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : void 0;
|
|
4902
|
+
const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;
|
|
4903
|
+
const sourceChain = sourceNode && ctx.maskAncestorChains.get(sourceNode) || [];
|
|
4904
|
+
if (!targetChain.length && !sourceChain.length) return inner;
|
|
4905
|
+
const times = /* @__PURE__ */ new Set();
|
|
4906
|
+
for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
4907
|
+
for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);
|
|
4908
|
+
const animated = times.size > 0;
|
|
4909
|
+
if (!animated) {
|
|
4910
|
+
const tgt = sumStaticTranslate(targetChain);
|
|
4911
|
+
const src = sumStaticTranslate(sourceChain);
|
|
4912
|
+
const dx = src[0] - tgt[0];
|
|
4913
|
+
const dy = src[1] - tgt[1];
|
|
4914
|
+
if (dx === 0 && dy === 0) return inner;
|
|
4915
|
+
return { type: "g", transform: "translate(" + dx + "," + dy + ")", children: [inner] };
|
|
4916
|
+
}
|
|
4917
|
+
const sortedTimes = Array.from(times).sort((a, b) => a - b);
|
|
4918
|
+
const keyframes = sortedTimes.map((t) => {
|
|
4919
|
+
const tgt = sumTranslateAt(targetChain, t);
|
|
4920
|
+
const src = sumTranslateAt(sourceChain, t);
|
|
4921
|
+
return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] } };
|
|
4922
|
+
});
|
|
4923
|
+
return { type: "g", animate: { transform: { keyframes } }, children: [inner] };
|
|
4924
|
+
}
|
|
4925
|
+
function sumStaticTranslate(chain) {
|
|
4926
|
+
let x = 0, y = 0;
|
|
4927
|
+
for (const a of chain) {
|
|
4928
|
+
if (a.translate) {
|
|
4929
|
+
x += a.translate[0];
|
|
4930
|
+
y += a.translate[1];
|
|
4931
|
+
}
|
|
4932
|
+
}
|
|
4933
|
+
return [x, y];
|
|
4934
|
+
}
|
|
4935
|
+
function sumTranslateAt(chain, t) {
|
|
4936
|
+
let x = 0, y = 0;
|
|
4937
|
+
for (const a of chain) {
|
|
4938
|
+
if (a.translateKeyframes && a.translateKeyframes.length) {
|
|
4939
|
+
const v = interpKfs(a.translateKeyframes, t);
|
|
4940
|
+
x += v[0];
|
|
4941
|
+
y += v[1];
|
|
4942
|
+
} else if (a.translate) {
|
|
4943
|
+
x += a.translate[0];
|
|
4944
|
+
y += a.translate[1];
|
|
4945
|
+
}
|
|
4946
|
+
}
|
|
4947
|
+
return [x, y];
|
|
4948
|
+
}
|
|
4949
|
+
function interpKfs(kfs, t) {
|
|
4950
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
4951
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
4952
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
4953
|
+
if (t <= kfs[i].time) {
|
|
4954
|
+
const prev = kfs[i - 1];
|
|
4955
|
+
const cur = kfs[i];
|
|
4956
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
4957
|
+
return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];
|
|
4958
|
+
}
|
|
4959
|
+
}
|
|
4960
|
+
return kfs[kfs.length - 1].value;
|
|
4961
|
+
}
|
|
4962
|
+
function collectMaskAncestorChains(root, ctx) {
|
|
4963
|
+
const interestingNodes = /* @__PURE__ */ new Set();
|
|
4964
|
+
const collectInterestingNodes = (n) => {
|
|
4965
|
+
var _a2, _b;
|
|
4966
|
+
const maskSourceId = stripHash((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
|
|
4967
|
+
if (typeof maskSourceId === "string") {
|
|
4968
|
+
interestingNodes.add(n);
|
|
4969
|
+
const sourceNode = ctx.idMap.get(maskSourceId);
|
|
4970
|
+
if (sourceNode) interestingNodes.add(sourceNode);
|
|
4971
|
+
}
|
|
4972
|
+
if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);
|
|
4973
|
+
};
|
|
4974
|
+
collectInterestingNodes(root);
|
|
4975
|
+
if (interestingNodes.size === 0) return;
|
|
4976
|
+
const walk = (node, chain) => {
|
|
4977
|
+
if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);
|
|
4978
|
+
if (Array.isArray(node.children)) {
|
|
4979
|
+
const own = extractTranslateOnly(node, ctx);
|
|
4980
|
+
const next = own ? [...chain, own] : chain;
|
|
4981
|
+
for (const ch of node.children) walk(ch, next);
|
|
4982
|
+
}
|
|
4983
|
+
};
|
|
4984
|
+
walk(root, []);
|
|
4985
|
+
}
|
|
4986
|
+
function extractTranslateOnly(node, ctx) {
|
|
4987
|
+
var _a2, _b, _c;
|
|
4988
|
+
const tr = node.transform;
|
|
4989
|
+
const animateBlock = node.animate && typeof node.animate === "object" && !Array.isArray(node.animate) ? node.animate.transform : void 0;
|
|
4990
|
+
if (tr === void 0 && !animateBlock) return void 0;
|
|
4991
|
+
const out = {};
|
|
4992
|
+
if (typeof tr === "string") {
|
|
4993
|
+
const parts = parseTranslateOnlyFromString(tr, ctx);
|
|
4994
|
+
if (parts) out.translate = parts;
|
|
4995
|
+
} else if (tr && typeof tr === "object" && !tr.keyframes) {
|
|
4996
|
+
const wrapped = tr.value;
|
|
4997
|
+
const value = wrapped && typeof wrapped === "object" ? wrapped : tr;
|
|
4998
|
+
if (value && typeof value === "object" && Array.isArray(value.translate)) {
|
|
4999
|
+
out.translate = [value.translate[0] || 0, value.translate[1] || 0];
|
|
5000
|
+
}
|
|
5001
|
+
if (value && (value.rotate !== void 0 || value.scale !== void 0 || value.skew !== void 0)) {
|
|
5002
|
+
ctx.warnings.push("maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)");
|
|
5003
|
+
}
|
|
5004
|
+
}
|
|
5005
|
+
if (animateBlock && Array.isArray(animateBlock.keyframes)) {
|
|
5006
|
+
const kfs = animateBlock.keyframes;
|
|
5007
|
+
const translateKfs = [];
|
|
5008
|
+
for (const kf of kfs) {
|
|
5009
|
+
const v = (_a2 = kf.value) != null ? _a2 : kf.v;
|
|
5010
|
+
const t = (_c = (_b = kf.time) != null ? _b : kf.t) != null ? _c : 0;
|
|
5011
|
+
if (v && typeof v === "object" && Array.isArray(v.translate)) {
|
|
5012
|
+
translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });
|
|
5013
|
+
if (v.rotate !== void 0 || v.scale !== void 0 || v.skew !== void 0) {
|
|
5014
|
+
ctx.warnings.push("maskedBy ancestor: animated non-translate parts ignored");
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
}
|
|
5018
|
+
if (translateKfs.length) out.translateKeyframes = translateKfs;
|
|
5019
|
+
}
|
|
5020
|
+
return out.translate || out.translateKeyframes ? out : void 0;
|
|
5021
|
+
}
|
|
5022
|
+
function parseTranslateOnlyFromString(s, ctx) {
|
|
5023
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
5024
|
+
let m;
|
|
5025
|
+
let x = 0, y = 0;
|
|
5026
|
+
let seen = false;
|
|
5027
|
+
let droppedNonTranslate = false;
|
|
5028
|
+
while ((m = re.exec(s)) !== null) {
|
|
5029
|
+
const name = m[1];
|
|
5030
|
+
const args = m[2].split(/[\s,]+/).filter((a) => a.length > 0).map(Number);
|
|
5031
|
+
if (name === "translate") {
|
|
5032
|
+
x += args[0] || 0;
|
|
5033
|
+
y += args[1] || 0;
|
|
5034
|
+
seen = true;
|
|
5035
|
+
} else {
|
|
5036
|
+
droppedNonTranslate = true;
|
|
5037
|
+
}
|
|
5038
|
+
}
|
|
5039
|
+
if (droppedNonTranslate) ctx.warnings.push("maskedBy ancestor: non-translate transform in string ignored: " + s);
|
|
5040
|
+
return seen ? [x, y] : void 0;
|
|
5041
|
+
}
|
|
5042
|
+
|
|
5043
|
+
// src/effects/reference/refEffect.ts
|
|
5044
|
+
function applyRefHref(node, clone2, ctx) {
|
|
5045
|
+
if (!clone2) return;
|
|
5046
|
+
const sourceId = stripHash(clone2.source);
|
|
5047
|
+
if (!sourceId) {
|
|
5048
|
+
if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
|
|
5049
|
+
return;
|
|
5050
|
+
}
|
|
5051
|
+
const targetId = clone2.without === PxCloneWithout.translate ? ctx.contentRefInnerIds.get(sourceId) || sourceId : sourceId;
|
|
5052
|
+
node.href = "#" + targetId;
|
|
5053
|
+
}
|
|
5054
|
+
function applyRefAndTransformationEffect(node, clone2, transformBy, ctx) {
|
|
5055
|
+
applyRefHref(node, clone2, ctx);
|
|
5056
|
+
return applyTransformByEffect(node, transformBy, ctx);
|
|
5057
|
+
}
|
|
5058
|
+
|
|
5059
|
+
// src/effects/transform/repeaterEffect.ts
|
|
5060
|
+
function applyRepeaterEffect(node, fx, ctx) {
|
|
5061
|
+
var _a2, _b;
|
|
5062
|
+
if (!fx) return node;
|
|
5063
|
+
const copies = (_a2 = fx.copies) != null ? _a2 : 1;
|
|
5064
|
+
if (copies < 1) {
|
|
5065
|
+
ctx.errors.push("repeater.copies invalid: " + fx.copies);
|
|
5066
|
+
return node;
|
|
5067
|
+
}
|
|
5068
|
+
const sharedTransform = node.transform;
|
|
5069
|
+
const sharedAnimTransform = (_b = node.animate) == null ? void 0 : _b.transform;
|
|
5070
|
+
const base = clone(node);
|
|
5071
|
+
delete base.transform;
|
|
5072
|
+
if (base.animate) {
|
|
5073
|
+
delete base.animate.transform;
|
|
5074
|
+
if (Object.keys(base.animate).length === 0) delete base.animate;
|
|
5075
|
+
}
|
|
5076
|
+
delete base.id;
|
|
5077
|
+
const children = [base];
|
|
5078
|
+
for (let i = 1; i < copies; i++) {
|
|
5079
|
+
const baseClone = clone(base);
|
|
5080
|
+
const synthFx = synthesisePerCopyFx(fx, i);
|
|
5081
|
+
const wrapped = synthFx ? applyTransformByEffect(baseClone, synthFx, ctx) : baseClone;
|
|
5082
|
+
children.push(wrapped);
|
|
5083
|
+
}
|
|
5084
|
+
const wrapper = { type: "g", children };
|
|
5085
|
+
if (node.id) wrapper.id = node.id;
|
|
5086
|
+
if (sharedTransform !== void 0) wrapper.transform = sharedTransform;
|
|
5087
|
+
if (sharedAnimTransform !== void 0) wrapper.animate = { transform: sharedAnimTransform };
|
|
5088
|
+
return wrapper;
|
|
5089
|
+
}
|
|
5090
|
+
function synthesisePerCopyFx(fx, i) {
|
|
5091
|
+
const out = {};
|
|
5092
|
+
if (fx.translate !== void 0) {
|
|
5093
|
+
out.translate = mapAnimatable(fx.translate, (v) => [v[0] * i, v[1] * i]);
|
|
5094
|
+
}
|
|
5095
|
+
if (fx.rotate !== void 0) {
|
|
5096
|
+
out.rotate = mapAnimatable(fx.rotate, (v) => v * i);
|
|
5097
|
+
}
|
|
5098
|
+
if (fx.skew !== void 0) {
|
|
5099
|
+
out.skew = mapAnimatable(fx.skew, (v) => v * i);
|
|
5100
|
+
}
|
|
5101
|
+
if (fx.scale !== void 0) {
|
|
5102
|
+
out.scale = synthesiseScale(fx.scale, i);
|
|
5103
|
+
}
|
|
5104
|
+
if (fx.origin !== void 0) {
|
|
5105
|
+
out.origin = fx.origin;
|
|
5106
|
+
}
|
|
5107
|
+
return Object.keys(out).length ? out : void 0;
|
|
5108
|
+
}
|
|
5109
|
+
function mapAnimatable(raw, fn, wrapStatic = false) {
|
|
5110
|
+
const read = readAnimatable(raw);
|
|
5111
|
+
if (read.kind === "absent" /* Absent */) return raw;
|
|
5112
|
+
if (read.kind === "static" /* Static */) {
|
|
5113
|
+
const mapped = fn(read.value);
|
|
5114
|
+
const wasRawStatic = typeof raw === "number" || Array.isArray(raw);
|
|
5115
|
+
return wasRawStatic && !wrapStatic ? mapped : { value: mapped };
|
|
5116
|
+
}
|
|
5117
|
+
const out = {
|
|
5118
|
+
keyframes: read.keyframes.map((kf) => kf && kf.value !== void 0 ? __spreadProps(__spreadValues({}, kf), { value: fn(kf.value) }) : kf)
|
|
5119
|
+
};
|
|
5120
|
+
if (read.loop !== void 0) out.loop = read.loop;
|
|
5121
|
+
if (read.autoOrient !== void 0) out.autoOrient = read.autoOrient;
|
|
5122
|
+
if (read.base !== void 0) out.value = fn(read.base);
|
|
5123
|
+
return out;
|
|
5124
|
+
}
|
|
5125
|
+
function synthesiseScale(raw, i) {
|
|
5126
|
+
const scalePower = (v) => [Math.pow(v[0], i), Math.pow(v[1], i)];
|
|
5127
|
+
return mapAnimatable(raw, scalePower, true);
|
|
5128
|
+
}
|
|
5129
|
+
|
|
5130
|
+
// src/effects/reference/retimeEffect.ts
|
|
5131
|
+
var RETIME_MATERIALIZATION_MODE_INLINE_G = false;
|
|
5132
|
+
function asRetime(r) {
|
|
5133
|
+
var _a2, _b;
|
|
5134
|
+
return { start: (_a2 = r.start) != null ? _a2 : 0, stretch: (_b = r.stretch) != null ? _b : 1 };
|
|
5135
|
+
}
|
|
5136
|
+
var CROP_EDGE_MS = 1;
|
|
5137
|
+
function applyTimeCrop(useNode, crop, ctx) {
|
|
5138
|
+
const [start, end] = crop;
|
|
5139
|
+
if (!Number.isFinite(start) || !Number.isFinite(end)) {
|
|
5140
|
+
ctx.warnings.push("retime: timeCrop is not a pair of finite numbers \u2014 ignored");
|
|
5141
|
+
return;
|
|
5142
|
+
}
|
|
5143
|
+
const keyframes = end <= start ? [{ time: 0, value: 0 }] : [
|
|
5144
|
+
...start > 0 ? [{ time: Math.max(0, start - CROP_EDGE_MS), value: 0 }] : [],
|
|
5145
|
+
{ time: Math.max(0, start), value: 1 },
|
|
5146
|
+
{ time: end, value: 1 },
|
|
5147
|
+
{ time: end + CROP_EDGE_MS, value: 0 }
|
|
5148
|
+
];
|
|
5149
|
+
const inner = __spreadValues({}, useNode);
|
|
5150
|
+
for (const k of Object.keys(useNode)) delete useNode[k];
|
|
5151
|
+
useNode.type = "g";
|
|
5152
|
+
useNode.children = [inner];
|
|
5153
|
+
useNode.animate = { opacity: { keyframes } };
|
|
5154
|
+
}
|
|
5155
|
+
function concatRetime(child, parent) {
|
|
5156
|
+
return {
|
|
5157
|
+
start: parent.start + parent.stretch * child.start,
|
|
5158
|
+
stretch: parent.stretch * child.stretch
|
|
5159
|
+
};
|
|
5160
|
+
}
|
|
5161
|
+
function readCloneRetime(n) {
|
|
5162
|
+
var _a2, _b;
|
|
5163
|
+
return (_b = (_a2 = n.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.retime;
|
|
5164
|
+
}
|
|
5165
|
+
function clearCloneRetime(n) {
|
|
5166
|
+
var _a2;
|
|
5167
|
+
const clone2 = (_a2 = n.effects) == null ? void 0 : _a2.clone;
|
|
5168
|
+
if (!clone2) return;
|
|
5169
|
+
delete clone2.retime;
|
|
5170
|
+
if (Object.keys(clone2).length === 0) delete n.effects.clone;
|
|
5171
|
+
if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;
|
|
5172
|
+
}
|
|
5173
|
+
function applyAllRetimeEffects(root, ctx) {
|
|
5174
|
+
ctx.idMap.clear();
|
|
5175
|
+
indexById(root, ctx.idMap);
|
|
5176
|
+
const sites = [];
|
|
5177
|
+
const collect = (n) => {
|
|
5178
|
+
var _a2;
|
|
5179
|
+
if (readCloneRetime(n)) sites.push(n);
|
|
5180
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(collect);
|
|
5181
|
+
};
|
|
5182
|
+
collect(root);
|
|
5183
|
+
const reachCount = /* @__PURE__ */ new Map();
|
|
5184
|
+
for (const site of sites) {
|
|
5185
|
+
let count = 0;
|
|
5186
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5187
|
+
const walk = (n) => {
|
|
5188
|
+
var _a2;
|
|
5189
|
+
if (!n) return;
|
|
5190
|
+
if (n !== site && readCloneRetime(n)) count++;
|
|
5191
|
+
if (n.type === "use" && n.href) {
|
|
5192
|
+
const id = stripHash(n.href);
|
|
5193
|
+
if (id && !visited.has(id)) {
|
|
5194
|
+
visited.add(id);
|
|
5195
|
+
walk(ctx.idMap.get(id));
|
|
5196
|
+
}
|
|
5197
|
+
}
|
|
5198
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
|
|
5199
|
+
};
|
|
5200
|
+
const rootId = stripHash(site.href);
|
|
5201
|
+
if (rootId) {
|
|
5202
|
+
visited.add(rootId);
|
|
5203
|
+
walk(ctx.idMap.get(rootId));
|
|
5204
|
+
}
|
|
5205
|
+
reachCount.set(site, count);
|
|
5206
|
+
}
|
|
5207
|
+
sites.sort((a, b) => {
|
|
5208
|
+
var _a2, _b;
|
|
5209
|
+
return ((_a2 = reachCount.get(b)) != null ? _a2 : 0) - ((_b = reachCount.get(a)) != null ? _b : 0);
|
|
5210
|
+
});
|
|
5211
|
+
for (const useNode of sites) {
|
|
5212
|
+
const retime = readCloneRetime(useNode);
|
|
5213
|
+
if (!retime) continue;
|
|
5214
|
+
const crop = retime.timeCrop;
|
|
5215
|
+
clearCloneRetime(useNode);
|
|
5216
|
+
materializeRetime(useNode, asRetime(retime), ctx);
|
|
5217
|
+
if (crop) applyTimeCrop(useNode, crop, ctx);
|
|
5218
|
+
}
|
|
5219
|
+
}
|
|
5220
|
+
function materializeRetime(useNode, retime, ctx) {
|
|
5221
|
+
const targetId = stripHash(useNode.href);
|
|
5222
|
+
if (!targetId) {
|
|
5223
|
+
ctx.errors.push("retime: <use> has no href to follow");
|
|
5224
|
+
return;
|
|
5225
|
+
}
|
|
5226
|
+
const chainRootId = buildChainClone(targetId, retime, ctx, /* @__PURE__ */ new Set());
|
|
5227
|
+
if (!chainRootId) return;
|
|
5228
|
+
if (RETIME_MATERIALIZATION_MODE_INLINE_G) {
|
|
5229
|
+
const cloneNode = ctx.idMap.get(chainRootId);
|
|
5230
|
+
useNode.type = "g";
|
|
5231
|
+
delete useNode.href;
|
|
5232
|
+
useNode.children = [cloneNode];
|
|
5233
|
+
applyUseOffsetToG(useNode);
|
|
5234
|
+
ctx.defs = ctx.defs.filter((d) => d !== cloneNode);
|
|
5235
|
+
} else {
|
|
5236
|
+
useNode.href = "#" + chainRootId;
|
|
5237
|
+
}
|
|
5238
|
+
}
|
|
5239
|
+
function buildChainClone(targetId, accum, ctx, chain) {
|
|
5240
|
+
if (chain.has(targetId)) {
|
|
5241
|
+
ctx.errors.push('retime: loop via "' + targetId + '"');
|
|
5242
|
+
return void 0;
|
|
5243
|
+
}
|
|
5244
|
+
const target = ctx.idMap.get(targetId);
|
|
5245
|
+
if (!target) {
|
|
5246
|
+
ctx.warnings.push('retime: target "' + targetId + '" not found');
|
|
5247
|
+
return void 0;
|
|
5248
|
+
}
|
|
5249
|
+
const cloneNode = clone(target);
|
|
5250
|
+
regenerateIdsInClone(cloneNode, ctx);
|
|
5251
|
+
if (target.type === "use") {
|
|
5252
|
+
remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);
|
|
5253
|
+
} else {
|
|
5254
|
+
remapKeyframeTimes(cloneNode, accum.start, accum.stretch);
|
|
5255
|
+
}
|
|
5256
|
+
clearCloneRetime(cloneNode);
|
|
5257
|
+
if (target.type === "use" && target.href) {
|
|
5258
|
+
const subId = stripHash(target.href);
|
|
5259
|
+
if (subId) {
|
|
5260
|
+
const innerRetime = readCloneRetime(target);
|
|
5261
|
+
const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
|
|
5262
|
+
const subChain = new Set(chain);
|
|
5263
|
+
subChain.add(targetId);
|
|
5264
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
5265
|
+
if (subId2) cloneNode.href = "#" + subId2;
|
|
5266
|
+
}
|
|
5267
|
+
} else {
|
|
5268
|
+
materializeNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);
|
|
5269
|
+
}
|
|
5270
|
+
ctx.defs.push(cloneNode);
|
|
5271
|
+
if (typeof cloneNode.id === "string") ctx.idMap.set(cloneNode.id, cloneNode);
|
|
5272
|
+
return typeof cloneNode.id === "string" ? cloneNode.id : void 0;
|
|
5273
|
+
}
|
|
5274
|
+
function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
|
|
5275
|
+
const visit = (n) => {
|
|
5276
|
+
var _a2;
|
|
5277
|
+
const retime = readCloneRetime(n);
|
|
5278
|
+
if (n.type === "use" && retime && n.href) {
|
|
5279
|
+
const subId = stripHash(n.href);
|
|
5280
|
+
if (subId) {
|
|
5281
|
+
const subAccum = concatRetime(asRetime(retime), accum);
|
|
5282
|
+
const subChain = new Set(chain);
|
|
5283
|
+
subChain.add(parentTargetId);
|
|
5284
|
+
const subId2 = buildChainClone(subId, subAccum, ctx, subChain);
|
|
5285
|
+
if (subId2) n.href = "#" + subId2;
|
|
5286
|
+
}
|
|
5287
|
+
clearCloneRetime(n);
|
|
5288
|
+
}
|
|
5289
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
|
|
5290
|
+
};
|
|
5291
|
+
visit(node);
|
|
5292
|
+
}
|
|
5293
|
+
function remapKeyframeTimes(node, start, stretch) {
|
|
5294
|
+
var _a2;
|
|
5295
|
+
remapKeyframeTimesOnly(node, start, stretch);
|
|
5296
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((c) => remapKeyframeTimes(c, start, stretch));
|
|
5297
|
+
}
|
|
5298
|
+
function remapKeyframeTimesOnly(node, start, stretch) {
|
|
5299
|
+
const remap2 = (kfs) => {
|
|
5300
|
+
for (const kf of kfs) if (typeof kf.time === "number") kf.time = start + kf.time * stretch;
|
|
5301
|
+
};
|
|
5302
|
+
if (node.transform && typeof node.transform === "object" && Array.isArray(node.transform.keyframes)) {
|
|
5303
|
+
remap2(node.transform.keyframes);
|
|
5304
|
+
}
|
|
5305
|
+
if (node.animate && typeof node.animate === "object") {
|
|
5306
|
+
for (const prop of Object.keys(node.animate)) {
|
|
5307
|
+
const anim = node.animate[prop];
|
|
5308
|
+
if (anim && Array.isArray(anim.keyframes)) remap2(anim.keyframes);
|
|
5309
|
+
}
|
|
5310
|
+
}
|
|
5311
|
+
}
|
|
5312
|
+
|
|
5313
|
+
// src/effects/stroke/strokeTrimEffect.ts
|
|
5314
|
+
function applyStrokeTrimEffect(node, strokeTrim, ctx) {
|
|
5315
|
+
if (!strokeTrim) return node;
|
|
5316
|
+
const combined = strokeTrim.subPaths === PxStrokeTrimSubPaths.combined;
|
|
5317
|
+
const leafEntries = [];
|
|
5318
|
+
const measure = (n) => {
|
|
5319
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
5320
|
+
for (const ch of n.children) measure(ch);
|
|
5321
|
+
return;
|
|
5322
|
+
}
|
|
5323
|
+
const d = typeof n.d === "string" ? n.d : shapeToPathD(n);
|
|
5324
|
+
if (d === void 0) return;
|
|
5325
|
+
const subpaths = parseSvgPathToBezier(d);
|
|
5326
|
+
if (!subpaths.length) return;
|
|
5327
|
+
const entry = { leaf: n, subpaths: [] };
|
|
5328
|
+
for (const sp of subpaths) {
|
|
5329
|
+
const lengthPx = pxBezierPathLength(sp);
|
|
5330
|
+
entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });
|
|
5331
|
+
}
|
|
5332
|
+
leafEntries.push(entry);
|
|
5333
|
+
};
|
|
5334
|
+
measure(node);
|
|
5335
|
+
if (!leafEntries.length) return node;
|
|
5336
|
+
let acc = 0;
|
|
5337
|
+
const iterOrder = combined ? [...leafEntries].reverse() : leafEntries;
|
|
5338
|
+
for (const entry of iterOrder) {
|
|
5339
|
+
for (const sp of entry.subpaths) {
|
|
5340
|
+
if (!combined) acc = 0;
|
|
5341
|
+
sp.startOffsetPx = acc;
|
|
5342
|
+
acc += sp.lengthPx;
|
|
5343
|
+
}
|
|
5344
|
+
}
|
|
5345
|
+
const chainLengthPx = acc;
|
|
5346
|
+
if (combined && chainLengthPx < 1e-3) return node;
|
|
5347
|
+
const offsetReadRaw = readAnimatable(strokeTrim.offset);
|
|
5348
|
+
const offsetRead = offsetReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: 0 } : offsetReadRaw;
|
|
5349
|
+
const rangeReadRaw = readRangeWithCrossings(strokeTrim.range);
|
|
5350
|
+
const rangeRead = rangeReadRaw.kind === "absent" /* Absent */ ? { kind: "static" /* Static */, value: [0, 1] } : rangeReadRaw;
|
|
5351
|
+
const offsetValues = readScalarValues(offsetRead);
|
|
5352
|
+
const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;
|
|
5353
|
+
const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;
|
|
5354
|
+
const minMaxOffset = [minOffset, maxOffset];
|
|
5355
|
+
if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {
|
|
5356
|
+
const entry = leafEntries[0];
|
|
5357
|
+
const sp = entry.subpaths[0];
|
|
5358
|
+
const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
|
|
5359
|
+
if (pathLengthPx < 1e-3) return node;
|
|
5360
|
+
const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
|
|
5361
|
+
return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);
|
|
5362
|
+
}
|
|
5363
|
+
const replacements = /* @__PURE__ */ new Map();
|
|
5364
|
+
for (const entry of leafEntries) {
|
|
5365
|
+
const newChildren = [];
|
|
5366
|
+
for (const sp of entry.subpaths) {
|
|
5367
|
+
const pathLengthPx = combined ? chainLengthPx : sp.lengthPx;
|
|
5368
|
+
if (pathLengthPx < 1e-3) continue;
|
|
5369
|
+
const startOffsetPct = combined ? sp.startOffsetPx / pathLengthPx : 0;
|
|
5370
|
+
newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));
|
|
5371
|
+
}
|
|
5372
|
+
replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));
|
|
5373
|
+
}
|
|
5374
|
+
const swap = (n) => {
|
|
5375
|
+
const r = replacements.get(n);
|
|
5376
|
+
if (r) return r;
|
|
5377
|
+
if (Array.isArray(n.children) && n.children.length > 0) {
|
|
5378
|
+
return __spreadProps(__spreadValues({}, n), { children: n.children.map(swap) });
|
|
5379
|
+
}
|
|
5380
|
+
return n;
|
|
5381
|
+
};
|
|
5382
|
+
return swap(node);
|
|
5383
|
+
}
|
|
5384
|
+
function wrapLeafAsGroup(leaf, children) {
|
|
5385
|
+
const wrapper = __spreadProps(__spreadValues({}, leaf), { type: "g", children });
|
|
5386
|
+
delete wrapper.d;
|
|
5387
|
+
delete wrapper.strokeDasharray;
|
|
5388
|
+
delete wrapper.strokeDashoffset;
|
|
5389
|
+
delete wrapper.effects;
|
|
5390
|
+
return wrapper;
|
|
5391
|
+
}
|
|
5392
|
+
function buildSubpathNodes(leaf, subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx) {
|
|
5393
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
5394
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
5395
|
+
const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);
|
|
5396
|
+
const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);
|
|
5397
|
+
const strokeOpacityAttr = computeOpacityFromRange(rangeRead);
|
|
5398
|
+
const dStr = bezierToSvgPath(subpath);
|
|
5399
|
+
const base = makeBareSubpath(dStr);
|
|
5400
|
+
applyAttr(base, "strokeDasharray", dashArrayAttr);
|
|
5401
|
+
applyAttr(base, "strokeDashoffset", dashOffsetAttr);
|
|
5402
|
+
applyAttr(base, "strokeOpacity", strokeOpacityAttr);
|
|
5403
|
+
return [base];
|
|
5404
|
+
}
|
|
5405
|
+
function collapseLeafWithTrim(leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead) {
|
|
5406
|
+
const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);
|
|
5407
|
+
const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);
|
|
5408
|
+
const node = __spreadValues({}, leaf);
|
|
5409
|
+
delete node.effects;
|
|
5410
|
+
applyAttr(node, "strokeDasharray", computeAnimAttr(rangeRead, rangeToDasharray));
|
|
5411
|
+
applyAttr(node, "strokeDashoffset", computeAnimAttr(offsetRead, offsetToDashOffset));
|
|
5412
|
+
applyAttr(node, "strokeOpacity", computeOpacityFromRange(rangeRead));
|
|
5413
|
+
return node;
|
|
5414
|
+
}
|
|
5415
|
+
function makeBareSubpath(dStr) {
|
|
5416
|
+
return { type: "path", d: dStr };
|
|
5417
|
+
}
|
|
5418
|
+
var SMALL_PADDING_PX = 1;
|
|
5419
|
+
function makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset) {
|
|
5420
|
+
const [minIdx] = getOffsetIndexRange(minMaxOffset);
|
|
5421
|
+
return (offsetVal) => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;
|
|
5422
|
+
}
|
|
5423
|
+
function makeRangeToDasharray(pathLengthPx, minMaxOffset) {
|
|
5424
|
+
const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);
|
|
5425
|
+
const repeats = maxIdx - minIdx + 1;
|
|
5426
|
+
return (rangeVal) => {
|
|
5427
|
+
const a = clamp(rangeVal[0], 0, 1);
|
|
5428
|
+
const b = clamp(rangeVal[1], 0, 1);
|
|
5429
|
+
const minR = Math.min(a, b);
|
|
5430
|
+
const maxR = Math.max(a, b);
|
|
5431
|
+
const out = [0];
|
|
5432
|
+
let gap = SMALL_PADDING_PX;
|
|
5433
|
+
for (let i = 0; i < repeats; i++) {
|
|
5434
|
+
out.push(gap + minR * pathLengthPx);
|
|
5435
|
+
out.push((maxR - minR) * pathLengthPx);
|
|
5436
|
+
gap = (1 - maxR) * pathLengthPx;
|
|
5437
|
+
}
|
|
5438
|
+
out.push(gap + SMALL_PADDING_PX);
|
|
5439
|
+
return out;
|
|
5440
|
+
};
|
|
5441
|
+
}
|
|
5442
|
+
function getOffsetIndexRange(minMaxOffset) {
|
|
5443
|
+
return [
|
|
5444
|
+
Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),
|
|
5445
|
+
Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1]))
|
|
5446
|
+
];
|
|
5447
|
+
}
|
|
5448
|
+
function readScalarValues(r) {
|
|
5449
|
+
if (r.kind === "absent" /* Absent */) return [];
|
|
5450
|
+
if (r.kind === "static" /* Static */) return [r.value];
|
|
5451
|
+
const out = [];
|
|
5452
|
+
for (const kf of r.keyframes) {
|
|
5453
|
+
const v = keyframeValue(kf);
|
|
5454
|
+
if (typeof v === "number") out.push(v);
|
|
5455
|
+
}
|
|
5456
|
+
return out;
|
|
5457
|
+
}
|
|
5458
|
+
function computeAnimAttr(read, map) {
|
|
5459
|
+
if (read.kind === "absent" /* Absent */) return void 0;
|
|
5460
|
+
if (read.kind === "static" /* Static */) return { kind: "static" /* Static */, value: map(read.value) };
|
|
5461
|
+
return {
|
|
5462
|
+
kind: "animated" /* Animated */,
|
|
5463
|
+
keyframes: read.keyframes.map((kf) => ({
|
|
5464
|
+
time: keyframeTime(kf),
|
|
5465
|
+
value: map(keyframeValue(kf)),
|
|
5466
|
+
easing: keyframeEasing(kf)
|
|
5467
|
+
})),
|
|
5468
|
+
loop: read.loop
|
|
5469
|
+
};
|
|
5470
|
+
}
|
|
5471
|
+
function applyAttr(node, attrName, attr) {
|
|
5472
|
+
if (!attr) return;
|
|
5473
|
+
writeAnimatableChannel(node, attrName, attr);
|
|
5474
|
+
}
|
|
5475
|
+
var OPACITY_STEP_MS = 10;
|
|
5476
|
+
function computeOpacityFromRange(rangeRead) {
|
|
5477
|
+
const hide = (v) => v[0] === v[1];
|
|
5478
|
+
if (rangeRead.kind === "absent" /* Absent */) return void 0;
|
|
5479
|
+
if (rangeRead.kind === "static" /* Static */) return hide(rangeRead.value) ? { kind: "static" /* Static */, value: 0 } : void 0;
|
|
5480
|
+
const kfs = rangeRead.keyframes;
|
|
5481
|
+
let anyHide = false;
|
|
5482
|
+
let allHide = true;
|
|
5483
|
+
for (const kf of kfs) {
|
|
5484
|
+
if (hide(keyframeValue(kf))) anyHide = true;
|
|
5485
|
+
else allHide = false;
|
|
5486
|
+
}
|
|
5487
|
+
if (!anyHide) return void 0;
|
|
5488
|
+
if (allHide) return { kind: "static" /* Static */, value: 0 };
|
|
5489
|
+
const out = [];
|
|
5490
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
5491
|
+
const kf = kfs[i];
|
|
5492
|
+
const prevKf = i > 0 ? kfs[i - 1] : void 0;
|
|
5493
|
+
const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
|
|
5494
|
+
const t = keyframeTime(kf);
|
|
5495
|
+
const thisHide = hide(keyframeValue(kf));
|
|
5496
|
+
const prevHide = prevKf ? thisHide && hide(keyframeValue(prevKf)) : thisHide;
|
|
5497
|
+
const nextHide = nextKf ? thisHide && hide(keyframeValue(nextKf)) : thisHide;
|
|
5498
|
+
if (prevHide && !nextHide) {
|
|
5499
|
+
out.push({ time: t, value: 0 });
|
|
5500
|
+
out.push({ time: t + OPACITY_STEP_MS, value: 1 });
|
|
5501
|
+
} else if (!prevHide && nextHide) {
|
|
5502
|
+
out.push({ time: t - OPACITY_STEP_MS, value: 1 });
|
|
5503
|
+
out.push({ time: t, value: 0 });
|
|
5504
|
+
}
|
|
5505
|
+
}
|
|
5506
|
+
if (out.length <= 1) return void 0;
|
|
5507
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
5508
|
+
}
|
|
5509
|
+
function readRangeWithCrossings(raw) {
|
|
5510
|
+
const r = readAnimatable(raw);
|
|
5511
|
+
if (r.kind !== "animated" /* Animated */) return r;
|
|
5512
|
+
const kfs = r.keyframes.map((kf) => ({
|
|
5513
|
+
time: keyframeTime(kf),
|
|
5514
|
+
value: keyframeValue(kf),
|
|
5515
|
+
easing: keyframeEasing(kf)
|
|
5516
|
+
}));
|
|
5517
|
+
const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
|
|
5518
|
+
if (!hasReverse) {
|
|
5519
|
+
return {
|
|
5520
|
+
kind: "animated" /* Animated */,
|
|
5521
|
+
keyframes: kfs.map((kf) => ({ time: kf.time, value: kf.value, easing: kf.easing }))
|
|
5522
|
+
};
|
|
5523
|
+
}
|
|
5524
|
+
const crossingTimes = [];
|
|
5525
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
5526
|
+
const prev = kfs[i - 1];
|
|
5527
|
+
const cur = kfs[i];
|
|
5528
|
+
const dPrev = prev.value[1] - prev.value[0];
|
|
5529
|
+
const dCur = cur.value[1] - cur.value[0];
|
|
5530
|
+
if (dPrev * dCur < 0) {
|
|
5531
|
+
const t = bisectionForRangeCrossing(prev, cur);
|
|
5532
|
+
if (t !== null && t > prev.time && t < cur.time) {
|
|
5533
|
+
crossingTimes.push(Math.round(t));
|
|
5534
|
+
}
|
|
5535
|
+
}
|
|
5536
|
+
}
|
|
5537
|
+
const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);
|
|
5538
|
+
const out = [];
|
|
5539
|
+
let j = 0;
|
|
5540
|
+
for (const kf of kfs) {
|
|
5541
|
+
while (j < uniqueTs.length && uniqueTs[j] < kf.time) {
|
|
5542
|
+
const t = uniqueTs[j++];
|
|
5543
|
+
const v2 = interpolateRangeAt(kfs, t);
|
|
5544
|
+
const m = (v2[0] + v2[1]) / 2;
|
|
5545
|
+
out.push({ time: t, value: [m, m] });
|
|
5546
|
+
}
|
|
5547
|
+
const v = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;
|
|
5548
|
+
out.push({ time: kf.time, value: v, easing: kf.easing });
|
|
5549
|
+
}
|
|
5550
|
+
while (j < uniqueTs.length) {
|
|
5551
|
+
const t = uniqueTs[j++];
|
|
5552
|
+
const v = interpolateRangeAt(kfs, t);
|
|
5553
|
+
const m = (v[0] + v[1]) / 2;
|
|
5554
|
+
out.push({ time: t, value: [m, m] });
|
|
5555
|
+
}
|
|
5556
|
+
return { kind: "animated" /* Animated */, keyframes: out };
|
|
5557
|
+
}
|
|
5558
|
+
function bisectionForRangeCrossing(prev, cur) {
|
|
5559
|
+
const f = (t) => {
|
|
5560
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
5561
|
+
const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;
|
|
5562
|
+
const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;
|
|
5563
|
+
return v1 - v0;
|
|
5564
|
+
};
|
|
5565
|
+
let lo = prev.time, hi = cur.time;
|
|
5566
|
+
let fLo = f(lo);
|
|
5567
|
+
if (fLo === 0) return lo;
|
|
5568
|
+
const fHi = f(hi);
|
|
5569
|
+
if (fHi === 0) return hi;
|
|
5570
|
+
if (fLo * fHi > 0) return null;
|
|
5571
|
+
for (let i = 0; i < 100; i++) {
|
|
5572
|
+
const mid = (lo + hi) / 2;
|
|
5573
|
+
const fMid = f(mid);
|
|
5574
|
+
if (fMid === 0 || Math.abs(hi - lo) < 1e-4) return mid;
|
|
5575
|
+
if (fLo * fMid < 0) {
|
|
5576
|
+
hi = mid;
|
|
5577
|
+
} else {
|
|
5578
|
+
lo = mid;
|
|
5579
|
+
fLo = fMid;
|
|
5580
|
+
}
|
|
5581
|
+
}
|
|
5582
|
+
return (lo + hi) / 2;
|
|
5583
|
+
}
|
|
5584
|
+
function interpolateRangeAt(kfs, t) {
|
|
5585
|
+
if (t <= kfs[0].time) return kfs[0].value;
|
|
5586
|
+
if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;
|
|
5587
|
+
for (let i = 1; i < kfs.length; i++) {
|
|
5588
|
+
if (t <= kfs[i].time) {
|
|
5589
|
+
const prev = kfs[i - 1];
|
|
5590
|
+
const cur = kfs[i];
|
|
5591
|
+
const a = (t - prev.time) / (cur.time - prev.time);
|
|
5592
|
+
return [
|
|
5593
|
+
prev.value[0] + (cur.value[0] - prev.value[0]) * a,
|
|
5594
|
+
prev.value[1] + (cur.value[1] - prev.value[1]) * a
|
|
5595
|
+
];
|
|
5596
|
+
}
|
|
5597
|
+
}
|
|
5598
|
+
return kfs[kfs.length - 1].value;
|
|
5599
|
+
}
|
|
5600
|
+
function pxBezierPathLength(path) {
|
|
5601
|
+
const v = path.v;
|
|
5602
|
+
if (!v || v.length < 2) return 0;
|
|
5603
|
+
let total = 0;
|
|
5604
|
+
for (let i = 0; i < v.length - 1; i++) {
|
|
5605
|
+
total += segmentLength(path, i, i + 1);
|
|
5606
|
+
}
|
|
5607
|
+
if (path.c && v.length > 1) {
|
|
5608
|
+
total += segmentLength(path, v.length - 1, 0);
|
|
5609
|
+
}
|
|
5610
|
+
return total;
|
|
5611
|
+
}
|
|
5612
|
+
function segmentLength(path, from, to) {
|
|
5613
|
+
var _a2, _b, _c, _d;
|
|
5614
|
+
const v = path.v;
|
|
5615
|
+
const p0 = v[from];
|
|
5616
|
+
const p3 = v[to];
|
|
5617
|
+
const p1 = (_b = (_a2 = path.o) == null ? void 0 : _a2[from]) != null ? _b : p0;
|
|
5618
|
+
const p2 = (_d = (_c = path.i) == null ? void 0 : _c[to]) != null ? _d : p3;
|
|
5619
|
+
const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);
|
|
5620
|
+
return lut.ds[lut.ds.length - 1];
|
|
5621
|
+
}
|
|
5622
|
+
var ARC_KAPPA = 0.5522847498307936;
|
|
5623
|
+
function shapeToPathD(node) {
|
|
5624
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
5625
|
+
if (node.type === "rect") {
|
|
5626
|
+
const x = Number((_a2 = node.x) != null ? _a2 : 0), y = Number((_b = node.y) != null ? _b : 0);
|
|
5627
|
+
const w = Number((_c = node.width) != null ? _c : 0), h = Number((_d = node.height) != null ? _d : 0);
|
|
5628
|
+
return "M" + (x + w) + "," + y + "L" + (x + w) + "," + (y + h) + "L" + x + "," + (y + h) + "L" + x + "," + y + "L" + (x + w) + "," + y + "z";
|
|
5629
|
+
}
|
|
5630
|
+
if (node.type === "ellipse" || node.type === "circle") {
|
|
5631
|
+
const cx = Number((_e = node.cx) != null ? _e : 0), cy = Number((_f = node.cy) != null ? _f : 0);
|
|
5632
|
+
const rx = node.type === "circle" ? Number((_g = node.r) != null ? _g : 0) : Number((_h = node.rx) != null ? _h : 0);
|
|
5633
|
+
const ry = node.type === "circle" ? Number((_i = node.r) != null ? _i : 0) : Number((_j = node.ry) != null ? _j : 0);
|
|
5634
|
+
if (!(rx > 0) || !(ry > 0)) return void 0;
|
|
5635
|
+
const kx = rx * ARC_KAPPA, ky = ry * ARC_KAPPA;
|
|
5636
|
+
const c = (x1, y1, x2, y2, x, y) => "C" + x1 + "," + y1 + " " + x2 + "," + y2 + " " + x + "," + y;
|
|
5637
|
+
return "M" + (cx + rx) + "," + cy + c(cx + rx, cy + ky, cx + kx, cy + ry, cx, cy + ry) + c(cx - kx, cy + ry, cx - rx, cy + ky, cx - rx, cy) + c(cx - rx, cy - ky, cx - kx, cy - ry, cx, cy - ry) + c(cx + kx, cy - ry, cx + rx, cy - ky, cx + rx, cy) + "z";
|
|
5638
|
+
}
|
|
5639
|
+
return void 0;
|
|
5640
|
+
}
|
|
5641
|
+
|
|
5642
|
+
// src/effects/PlayerEffectsUtil.ts
|
|
5643
|
+
function materializeNodeEffects(root) {
|
|
5644
|
+
var _a2, _b;
|
|
5645
|
+
const ctx = {
|
|
5646
|
+
defs: [],
|
|
5647
|
+
warnings: [],
|
|
5648
|
+
errors: [],
|
|
5649
|
+
idMap: /* @__PURE__ */ new Map(),
|
|
5650
|
+
nextId: 0,
|
|
5651
|
+
contentRefInnerIds: /* @__PURE__ */ new Map(),
|
|
5652
|
+
maskAncestorChains: /* @__PURE__ */ new Map(),
|
|
5653
|
+
// Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
|
|
5654
|
+
// waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
|
|
5655
|
+
engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
|
|
5656
|
+
glyphs: (_b = getDefinitions(root)) == null ? void 0 : _b.fonts
|
|
5657
|
+
};
|
|
5658
|
+
const working = clone(root);
|
|
5659
|
+
indexById(working, ctx.idMap);
|
|
5660
|
+
identifyContentRefTargets(working, ctx, () => genId(ctx, "inner"));
|
|
5661
|
+
collectMaskAncestorChains(working, ctx);
|
|
5662
|
+
const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);
|
|
5663
|
+
const out = applyPlayerEffects_retime(afterPass1, ctx);
|
|
5664
|
+
spliceDefs(out, ctx.defs);
|
|
5665
|
+
return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };
|
|
5666
|
+
}
|
|
5667
|
+
function applyPlayerEffects_exceptRetime(node, ctx) {
|
|
5668
|
+
if (node.children) node.children = node.children.map((child) => applyPlayerEffects_exceptRetime(child, ctx));
|
|
5669
|
+
const fx = node.effects;
|
|
5670
|
+
const originalId = typeof node.id === "string" ? node.id : void 0;
|
|
5671
|
+
const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : void 0;
|
|
5672
|
+
if (!fx && !innerIdForContentRef) return node;
|
|
5673
|
+
const { transformBy, repeater, maskedBy, clipPath, strokeTrim, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx != null ? fx : {};
|
|
5674
|
+
if (fx) delete node.effects;
|
|
5675
|
+
let n = node;
|
|
5676
|
+
let consumedByGlyphs = false;
|
|
5677
|
+
if (text == null ? void 0 : text.useGlyphs) {
|
|
5678
|
+
if (textPath) {
|
|
5679
|
+
const pathD = typeof textPath.pathData === "string" ? textPath.pathData : void 0;
|
|
5680
|
+
const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);
|
|
5681
|
+
if (glyphed) {
|
|
5682
|
+
n = glyphed;
|
|
5683
|
+
consumedByGlyphs = true;
|
|
5684
|
+
}
|
|
5685
|
+
} else {
|
|
5686
|
+
n = applyTextGlyphsEffect(n, text, ctx);
|
|
5687
|
+
consumedByGlyphs = true;
|
|
5688
|
+
}
|
|
5689
|
+
}
|
|
5690
|
+
if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);
|
|
5691
|
+
n = applyFillGradientEffect(n, fillGradient, ctx);
|
|
5692
|
+
n = applyStrokeGradientEffect(n, strokeGradient, ctx);
|
|
5693
|
+
n = applyStrokeTrimEffect(n, strokeTrim, ctx);
|
|
5694
|
+
n = applyRepeaterEffect(n, repeater, ctx);
|
|
5695
|
+
n = applyMaskedByEffect(n, maskedBy, transformBy, ctx);
|
|
5696
|
+
n = applyClipPathEffect(n, clipPath, ctx);
|
|
5697
|
+
if (innerIdForContentRef) {
|
|
5698
|
+
applyRefHref(n, cloneFx, ctx);
|
|
5699
|
+
n = splitForContentRef(n, transformBy, originalId, innerIdForContentRef, ctx);
|
|
5700
|
+
} else {
|
|
5701
|
+
n = applyRefAndTransformationEffect(n, cloneFx, transformBy, ctx);
|
|
5702
|
+
}
|
|
5703
|
+
if (cloneFx == null ? void 0 : cloneFx.retime) node.effects = { clone: { retime: cloneFx.retime } };
|
|
5704
|
+
if (originalId) ctx.idMap.set(originalId, n);
|
|
5705
|
+
return n;
|
|
5706
|
+
}
|
|
5707
|
+
function applyPlayerEffects_retime(node, ctx) {
|
|
5708
|
+
applyAllRetimeEffects(node, ctx);
|
|
5709
|
+
return node;
|
|
5710
|
+
}
|
|
5711
|
+
|
|
5712
|
+
// src/materialize/PxOffsetPathMaterializer.ts
|
|
5713
|
+
function cubicAt(p0, c1, c2, p1, t) {
|
|
5714
|
+
const u = 1 - t;
|
|
5715
|
+
const a = u * u * u, b = 3 * u * u * t, c = 3 * u * t * t, d = t * t * t;
|
|
5716
|
+
return [
|
|
5717
|
+
a * p0[0] + b * c1[0] + c * c2[0] + d * p1[0],
|
|
5718
|
+
a * p0[1] + b * c1[1] + c * c2[1] + d * p1[1]
|
|
5719
|
+
];
|
|
5720
|
+
}
|
|
5721
|
+
function cubicLength(p0, c1, c2, p1, steps = 64) {
|
|
5722
|
+
let len = 0;
|
|
5723
|
+
let prev = p0;
|
|
5724
|
+
for (let i = 1; i <= steps; i++) {
|
|
5725
|
+
const pt = cubicAt(p0, c1, c2, p1, i / steps);
|
|
5726
|
+
len += Math.hypot(pt[0] - prev[0], pt[1] - prev[1]);
|
|
5727
|
+
prev = pt;
|
|
5728
|
+
}
|
|
5729
|
+
return len;
|
|
5730
|
+
}
|
|
5731
|
+
var fmt2 = (n) => {
|
|
5732
|
+
const r = Math.round(n * 1e4) / 1e4;
|
|
5733
|
+
return Object.is(r, -0) ? "0" : String(r);
|
|
5734
|
+
};
|
|
5735
|
+
function buildOffsetPath(propAnim) {
|
|
5736
|
+
var _a2, _b, _c;
|
|
5737
|
+
if (propAnim.alongPathMode !== "offsetPath") return void 0;
|
|
5738
|
+
const kfs = propAnim.keyframes;
|
|
5739
|
+
if (!kfs || kfs.length < 2) return void 0;
|
|
5740
|
+
const first = keyframeValue(kfs[0]);
|
|
5741
|
+
const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
|
|
5742
|
+
const points = [];
|
|
5743
|
+
let keyframesCarryRotate = false;
|
|
5744
|
+
for (const kf of kfs) {
|
|
5745
|
+
const v = keyframeValue(kf);
|
|
5746
|
+
const tr = v == null ? void 0 : v.translate;
|
|
5747
|
+
if (!tr || tr.length < 2) return void 0;
|
|
5748
|
+
const parts = Object.keys(v);
|
|
5749
|
+
if (parts.some((p) => p !== TRANSFORM_PART.translate && p !== TRANSFORM_PART.origin && p !== TRANSFORM_PART.rotate)) return void 0;
|
|
5750
|
+
if ((v == null ? void 0 : v.rotate) !== void 0) {
|
|
5751
|
+
if (v.rotate !== 0) return void 0;
|
|
5752
|
+
keyframesCarryRotate = true;
|
|
5753
|
+
}
|
|
5754
|
+
const o = (_a2 = v == null ? void 0 : v.origin) != null ? _a2 : [0, 0];
|
|
5755
|
+
if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
|
|
5756
|
+
points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
|
|
5757
|
+
}
|
|
5758
|
+
if (!kfs.some((kf) => keyframeTangentIn(kf) || keyframeTangentOut(kf))) return void 0;
|
|
5759
|
+
let d = "M" + fmt2(points[0][0]) + "," + fmt2(points[0][1]);
|
|
5760
|
+
const segLens = [];
|
|
5761
|
+
for (let i = 0; i < points.length - 1; i++) {
|
|
5762
|
+
const p0 = points[i], p1 = points[i + 1];
|
|
5763
|
+
const to = (_b = keyframeTangentOut(kfs[i])) != null ? _b : [0, 0];
|
|
5764
|
+
const ti = (_c = keyframeTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
|
|
5765
|
+
const c1 = [p0[0] + to[0], p0[1] + to[1]];
|
|
5766
|
+
const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
|
|
5767
|
+
d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
|
|
5768
|
+
segLens.push(cubicLength(p0, c1, c2, p1));
|
|
5769
|
+
}
|
|
5770
|
+
const total = segLens.reduce((a, b) => a + b, 0);
|
|
5771
|
+
if (!(total > 0)) return void 0;
|
|
5772
|
+
const distanceKfs = [];
|
|
5773
|
+
let cum = 0;
|
|
5774
|
+
for (let i = 0; i < kfs.length; i++) {
|
|
5775
|
+
if (i > 0) cum += segLens[i - 1];
|
|
5776
|
+
const out = { t: keyframeTime(kfs[i]), v: cum / total };
|
|
5777
|
+
const e = keyframeEasing(kfs[i]);
|
|
5778
|
+
if (e !== void 0) out.e = e;
|
|
5779
|
+
distanceKfs.push(out);
|
|
5780
|
+
}
|
|
5781
|
+
return { pathStr: d, distanceKfs, autoOrient: !!propAnim.autoOrient, anchor, keyframesCarryRotate };
|
|
5782
|
+
}
|
|
5783
|
+
function materializeOffsetPathsInTree(root) {
|
|
5784
|
+
const walk = (node) => {
|
|
5785
|
+
var _a2;
|
|
5786
|
+
let out = node;
|
|
5787
|
+
const anim = node.animate;
|
|
5788
|
+
const transform = anim == null ? void 0 : anim["transform"];
|
|
5789
|
+
if (transform) {
|
|
5790
|
+
const built = buildOffsetPath(transform);
|
|
5791
|
+
if (built) {
|
|
5792
|
+
const newAnimate = __spreadValues({}, anim);
|
|
5793
|
+
delete newAnimate[TRANSFORM_ATTR];
|
|
5794
|
+
const distance = { keyframes: built.distanceKfs };
|
|
5795
|
+
if (transform.loop !== void 0) distance.loop = transform.loop;
|
|
5796
|
+
newAnimate[OFFSET_DISTANCE_ATTR] = distance;
|
|
5797
|
+
const staticTr = node.transform;
|
|
5798
|
+
let newTransform = staticTr;
|
|
5799
|
+
if (staticTr && typeof staticTr === "object") {
|
|
5800
|
+
const t = __spreadValues({}, staticTr);
|
|
5801
|
+
delete t[TRANSFORM_PART.translate];
|
|
5802
|
+
delete t[TRANSFORM_PART.origin];
|
|
5803
|
+
if (built.keyframesCarryRotate) delete t[TRANSFORM_PART.rotate];
|
|
5804
|
+
newTransform = Object.keys(t).length ? t : void 0;
|
|
5805
|
+
}
|
|
5806
|
+
out = __spreadProps(__spreadValues({}, node), {
|
|
5807
|
+
animate: newAnimate,
|
|
5808
|
+
style: __spreadProps(__spreadValues({}, node.style), {
|
|
5809
|
+
offsetPath: "path('" + built.pathStr + "')",
|
|
5810
|
+
offsetAnchor: fmt2(built.anchor[0]) + "px " + fmt2(built.anchor[1]) + "px",
|
|
5811
|
+
offsetRotate: built.autoOrient ? "auto" : "0deg",
|
|
5812
|
+
offsetDistance: "0%"
|
|
5813
|
+
})
|
|
5814
|
+
});
|
|
5815
|
+
if (newTransform !== void 0) out.transform = newTransform;
|
|
5816
|
+
else delete out.transform;
|
|
5817
|
+
}
|
|
5818
|
+
}
|
|
5819
|
+
if ((_a2 = out.children) == null ? void 0 : _a2.length) {
|
|
5820
|
+
const children = out.children.map(walk);
|
|
5821
|
+
if (children.some((c, i) => c !== out.children[i])) out = __spreadProps(__spreadValues({}, out), { children });
|
|
5822
|
+
}
|
|
5823
|
+
return out;
|
|
5824
|
+
};
|
|
5825
|
+
return walk(root);
|
|
5826
|
+
}
|
|
5827
|
+
|
|
5828
|
+
// src/materialize/PxAnimatorUseMaterializer.ts
|
|
5829
|
+
function materializeAnimatedUseInstances(root) {
|
|
5830
|
+
var _a2;
|
|
5831
|
+
const idMap = buildIdMap2(root);
|
|
5832
|
+
const animatedIds = computeAnimatedSubtreeIds(root, idMap);
|
|
5833
|
+
if (animatedIds.size === 0) return root;
|
|
5834
|
+
let idCounter = 0;
|
|
5835
|
+
const genId3 = () => "_lw_use_mat_" + ++idCounter;
|
|
5836
|
+
const rootViewport = readRootViewport(root);
|
|
5837
|
+
const defsCollector = [];
|
|
5838
|
+
const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5839
|
+
if (defsCollector.length === 0) return walked;
|
|
5840
|
+
const defsNode = { type: "defs", children: defsCollector };
|
|
5841
|
+
const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
|
|
5842
|
+
return __spreadProps(__spreadValues({}, walked), { children: newChildren });
|
|
5843
|
+
}
|
|
5844
|
+
function readRootViewport(root) {
|
|
5845
|
+
const vb = parseViewBox(root.viewBox);
|
|
5846
|
+
if (vb) return [vb[2], vb[3]];
|
|
5847
|
+
const w = numericAttr(root.width);
|
|
5848
|
+
const h = numericAttr(root.height);
|
|
5849
|
+
if (w !== void 0 && h !== void 0) return [w, h];
|
|
5850
|
+
return [1, 1];
|
|
5851
|
+
}
|
|
5852
|
+
function numericAttr(v) {
|
|
5853
|
+
if (typeof v === "number") return v;
|
|
5854
|
+
if (typeof v === "string") {
|
|
5855
|
+
const n = parseFloat(v);
|
|
5856
|
+
return Number.isFinite(n) ? n : void 0;
|
|
5857
|
+
}
|
|
5858
|
+
return void 0;
|
|
5859
|
+
}
|
|
5860
|
+
function buildIdMap2(root) {
|
|
5861
|
+
const map = /* @__PURE__ */ new Map();
|
|
5862
|
+
const visit = (n) => {
|
|
5863
|
+
var _a2;
|
|
5864
|
+
if (typeof n.id === "string") map.set(n.id, n);
|
|
5865
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
|
|
5866
|
+
};
|
|
5867
|
+
visit(root);
|
|
5868
|
+
return map;
|
|
5869
|
+
}
|
|
5870
|
+
function computeAnimatedSubtreeIds(root, idMap) {
|
|
5871
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
5872
|
+
const result = /* @__PURE__ */ new Set();
|
|
5873
|
+
const hasAnim = (n, visiting) => {
|
|
5874
|
+
const cached = cache.get(n);
|
|
5875
|
+
if (cached !== void 0) return cached;
|
|
5876
|
+
if (visiting.has(n)) return false;
|
|
5877
|
+
visiting.add(n);
|
|
5878
|
+
let r = false;
|
|
5879
|
+
if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
|
|
5880
|
+
for (const _ in n.animate) {
|
|
5881
|
+
r = true;
|
|
5882
|
+
break;
|
|
5883
|
+
}
|
|
5884
|
+
}
|
|
5885
|
+
if (!r && n.children) {
|
|
5886
|
+
for (const ch of n.children) {
|
|
5887
|
+
if (hasAnim(ch, visiting)) {
|
|
5888
|
+
r = true;
|
|
5889
|
+
break;
|
|
5890
|
+
}
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
if (!r && n.type === "use" && typeof n.href === "string") {
|
|
5894
|
+
const targetId = stripHash2(n.href);
|
|
5895
|
+
const target = targetId ? idMap.get(targetId) : void 0;
|
|
5896
|
+
if (target) r = hasAnim(target, visiting);
|
|
5897
|
+
}
|
|
5898
|
+
visiting.delete(n);
|
|
5899
|
+
cache.set(n, r);
|
|
5900
|
+
return r;
|
|
5901
|
+
};
|
|
5902
|
+
for (const [id, node] of idMap) {
|
|
5903
|
+
if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
|
|
5904
|
+
}
|
|
5905
|
+
return result;
|
|
5906
|
+
}
|
|
5907
|
+
function stripHash2(href) {
|
|
5908
|
+
if (typeof href !== "string") return void 0;
|
|
5909
|
+
return href.startsWith("#") ? href.slice(1) : href;
|
|
5910
|
+
}
|
|
5911
|
+
function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
5912
|
+
var _a2, _b, _c, _d;
|
|
5913
|
+
const clone2 = deepClonePxNode(target);
|
|
5914
|
+
regenerateIdsAndRewriteRefs(clone2, genId3);
|
|
5915
|
+
const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
|
|
5916
|
+
const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
|
|
5917
|
+
const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
|
|
5918
|
+
const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
|
|
5919
|
+
const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5920
|
+
const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materializedClone] });
|
|
5921
|
+
delete newNode.href;
|
|
5922
|
+
delete newNode.width;
|
|
5923
|
+
delete newNode.height;
|
|
5924
|
+
return applyUseOffsetToG(newNode);
|
|
5925
|
+
}
|
|
5926
|
+
function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
|
|
5927
|
+
const viewBox = parseViewBox(symbolNode.viewBox);
|
|
5928
|
+
const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
|
|
5929
|
+
delete g.viewBox;
|
|
5930
|
+
delete g.preserveAspectRatio;
|
|
5931
|
+
delete g.width;
|
|
5932
|
+
delete g.height;
|
|
5933
|
+
if (!viewBox) return g;
|
|
5934
|
+
const [vbX, vbY, vbW, vbH] = viewBox;
|
|
5935
|
+
const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
|
|
5936
|
+
const xOff = (useW - vbW * scale) / 2;
|
|
5937
|
+
const yOff = (useH - vbH * scale) / 2;
|
|
5938
|
+
const parts = [];
|
|
5939
|
+
if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
|
|
5940
|
+
if (scale !== 1) parts.push("scale(" + scale + ")");
|
|
5941
|
+
if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
|
|
5942
|
+
if (parts.length) g.transform = parts.join("");
|
|
5943
|
+
const clipId = genId3();
|
|
5944
|
+
defsCollector.push({
|
|
5945
|
+
type: "clipPath",
|
|
5946
|
+
id: clipId,
|
|
5947
|
+
children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
|
|
5948
|
+
});
|
|
5949
|
+
g.clipPath = "url(#" + clipId + ")";
|
|
5950
|
+
return g;
|
|
5951
|
+
}
|
|
5952
|
+
function parseViewBox(v) {
|
|
5953
|
+
if (typeof v !== "string") return void 0;
|
|
5954
|
+
const parts = v.trim().split(/[\s,]+/).map(Number);
|
|
5955
|
+
if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
|
|
5956
|
+
return [parts[0], parts[1], parts[2], parts[3]];
|
|
5957
|
+
}
|
|
5958
|
+
function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
|
|
5959
|
+
if (node.type === "use" && typeof node.href === "string") {
|
|
5960
|
+
const targetId = stripHash2(node.href);
|
|
5961
|
+
if (targetId && animatedIds.has(targetId)) {
|
|
5962
|
+
const target = idMap.get(targetId);
|
|
5963
|
+
if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5964
|
+
}
|
|
5965
|
+
}
|
|
5966
|
+
if (!node.children) return node;
|
|
5967
|
+
let changed = false;
|
|
5968
|
+
const newChildren = node.children.map((ch) => {
|
|
5969
|
+
const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
|
|
5970
|
+
if (m !== ch) changed = true;
|
|
5971
|
+
return m;
|
|
5972
|
+
});
|
|
5973
|
+
return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
|
|
3128
5974
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
5975
|
+
|
|
5976
|
+
// src/util/PxIdUtil.ts
|
|
5977
|
+
var _idCounter = 0;
|
|
5978
|
+
function generateUniqueId() {
|
|
5979
|
+
const timestamp = Date.now().toString(36);
|
|
5980
|
+
const counter = (++_idCounter).toString(36);
|
|
5981
|
+
const random = Math.random().toString(36).substring(2, 6);
|
|
5982
|
+
return "_px_" + timestamp + counter + random;
|
|
5983
|
+
}
|
|
5984
|
+
function deepClone(value) {
|
|
5985
|
+
if (value === null || typeof value !== "object") return value;
|
|
5986
|
+
if (Array.isArray(value)) return value.map((item) => deepClone(item));
|
|
5987
|
+
const obj = value;
|
|
5988
|
+
const cloned = {};
|
|
5989
|
+
for (const key of Object.keys(obj)) {
|
|
5990
|
+
cloned[key] = deepClone(obj[key]);
|
|
5991
|
+
}
|
|
5992
|
+
return cloned;
|
|
5993
|
+
}
|
|
5994
|
+
function generateNewIds(doc) {
|
|
3131
5995
|
var _a2;
|
|
3132
|
-
|
|
3133
|
-
const
|
|
3134
|
-
|
|
3135
|
-
const
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
5996
|
+
const cloned = deepClone(doc);
|
|
5997
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
5998
|
+
const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
|
|
5999
|
+
const urlRefAttrs = /* @__PURE__ */ new Set([
|
|
6000
|
+
"fill",
|
|
6001
|
+
"stroke",
|
|
6002
|
+
"clip-path",
|
|
6003
|
+
"clipPath",
|
|
6004
|
+
"mask",
|
|
6005
|
+
"marker",
|
|
6006
|
+
"marker-start",
|
|
6007
|
+
"marker-mid",
|
|
6008
|
+
"marker-end",
|
|
6009
|
+
"filter",
|
|
6010
|
+
"flood-color",
|
|
6011
|
+
"lighting-color"
|
|
6012
|
+
]);
|
|
6013
|
+
const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
|
|
6014
|
+
const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
|
|
6015
|
+
function collectIds(node) {
|
|
6016
|
+
if (!node || typeof node !== "object") return;
|
|
6017
|
+
if (node.id && typeof node.id === "string") {
|
|
6018
|
+
const oldId = node.id;
|
|
6019
|
+
const newId = generateUniqueId();
|
|
6020
|
+
idMap.set(oldId, newId);
|
|
6021
|
+
node.id = newId;
|
|
6022
|
+
} else if (node.animate) {
|
|
6023
|
+
node.id = generateUniqueId();
|
|
6024
|
+
}
|
|
6025
|
+
if (Array.isArray(node.children)) {
|
|
6026
|
+
for (const child of node.children) {
|
|
6027
|
+
collectIds(child);
|
|
6028
|
+
}
|
|
6029
|
+
}
|
|
3151
6030
|
}
|
|
3152
|
-
|
|
3153
|
-
|
|
3154
|
-
|
|
6031
|
+
function updateRefs(node, parentKey) {
|
|
6032
|
+
if (!node || typeof node !== "object") return;
|
|
6033
|
+
for (const [key, value] of Object.entries(node)) {
|
|
6034
|
+
if (key === "children") {
|
|
6035
|
+
if (Array.isArray(value)) {
|
|
6036
|
+
for (const child of value) {
|
|
6037
|
+
updateRefs(child);
|
|
6038
|
+
}
|
|
6039
|
+
}
|
|
6040
|
+
continue;
|
|
6041
|
+
}
|
|
6042
|
+
if (typeof value === "string") {
|
|
6043
|
+
if (hashRefAttrs.has(key) && value.startsWith("#")) {
|
|
6044
|
+
const oldId = value.slice(1);
|
|
6045
|
+
const newId = idMap.get(oldId);
|
|
6046
|
+
if (newId) {
|
|
6047
|
+
node[key] = "#" + newId;
|
|
6048
|
+
}
|
|
6049
|
+
} else if (urlRefAttrs.has(key)) {
|
|
6050
|
+
node[key] = replaceUrlRefs(value, idMap);
|
|
6051
|
+
} else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
|
|
6052
|
+
const hasHash = value.startsWith("#");
|
|
6053
|
+
const newId = idMap.get(hasHash ? value.slice(1) : value);
|
|
6054
|
+
if (newId) {
|
|
6055
|
+
node[key] = hasHash ? "#" + newId : newId;
|
|
6056
|
+
}
|
|
6057
|
+
} else if (value.includes("url(#")) {
|
|
6058
|
+
node[key] = replaceUrlRefs(value, idMap);
|
|
6059
|
+
}
|
|
6060
|
+
} else if (key === "style" && typeof value === "object" && value !== null) {
|
|
6061
|
+
for (const [styleProp, styleValue] of Object.entries(value)) {
|
|
6062
|
+
if (typeof styleValue === "string") {
|
|
6063
|
+
value[styleProp] = replaceUrlRefs(styleValue, idMap);
|
|
6064
|
+
}
|
|
6065
|
+
}
|
|
6066
|
+
} else if (typeof value === "object" && value !== null) {
|
|
6067
|
+
updateRefs(value, key);
|
|
6068
|
+
}
|
|
6069
|
+
}
|
|
3155
6070
|
}
|
|
3156
|
-
|
|
6071
|
+
collectIds(cloned);
|
|
6072
|
+
updateRefs(cloned);
|
|
6073
|
+
const docBindings = (_a2 = cloned.animator) == null ? void 0 : _a2.bindings;
|
|
6074
|
+
if (Array.isArray(docBindings)) {
|
|
6075
|
+
const updatedBindings = docBindings.map((binding) => {
|
|
6076
|
+
var _a3;
|
|
6077
|
+
const hashed = binding.target.startsWith("#");
|
|
6078
|
+
const id = hashed ? binding.target.slice(1) : binding.target;
|
|
6079
|
+
const newId = (_a3 = idMap.get(id)) != null ? _a3 : id;
|
|
6080
|
+
return __spreadProps(__spreadValues({}, binding), { target: hashed ? "#" + newId : newId });
|
|
6081
|
+
});
|
|
6082
|
+
cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { bindings: updatedBindings });
|
|
6083
|
+
}
|
|
6084
|
+
return cloned;
|
|
6085
|
+
}
|
|
6086
|
+
function replaceUrlRefs(value, idMap) {
|
|
6087
|
+
return value.replace(/url\(#([^)]+)\)/g, (match, oldId) => {
|
|
6088
|
+
const newId = idMap.get(oldId);
|
|
6089
|
+
return newId ? "url(#" + newId + ")" : match;
|
|
6090
|
+
});
|
|
3157
6091
|
}
|
|
3158
6092
|
|
|
3159
|
-
// src/
|
|
3160
|
-
var
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
6093
|
+
// src/materialize/PxRestPose.ts
|
|
6094
|
+
var TRANSFORM_CHANNEL = "transform";
|
|
6095
|
+
var REVERSED_DIRECTIONS = /* @__PURE__ */ new Set(["reverse", "alternate-reverse"]);
|
|
6096
|
+
var VERIFY_SAMPLE_FRACTIONS = [0, 0.25, 0.5, 0.75, 1];
|
|
6097
|
+
var SCRATCH_ID_PREFIX = "__px_rest_";
|
|
6098
|
+
function materializeRestPosesInTree(root, engine) {
|
|
6099
|
+
var _a2, _b;
|
|
6100
|
+
const out = deepClone(root);
|
|
6101
|
+
const config = getAnimatorConfig(out) || {};
|
|
6102
|
+
const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
|
|
6103
|
+
const firstFrameTime = REVERSED_DIRECTIONS.has(String(config.direction)) ? duration : 0;
|
|
6104
|
+
const nodes = animatedNodes(out);
|
|
6105
|
+
if (!nodes.size) return out;
|
|
6106
|
+
const before = bindingsOf(out, engine);
|
|
6107
|
+
const added = /* @__PURE__ */ new Map();
|
|
6108
|
+
for (const [key, animate] of before) {
|
|
6109
|
+
const node = nodes.get(key);
|
|
6110
|
+
if (!node) continue;
|
|
6111
|
+
const channels = Object.keys(animate);
|
|
6112
|
+
for (const channel of channels) {
|
|
6113
|
+
if (PX_TRANSFORM_FN_NAMES.has(channel)) continue;
|
|
6114
|
+
if (!mayCarryRestPose(node, channel)) continue;
|
|
6115
|
+
const value = firstFrameValue(animate, channel, firstFrameTime);
|
|
6116
|
+
if (value === void 0) continue;
|
|
6117
|
+
node[channel] = value;
|
|
6118
|
+
added.set(key, [...(_a2 = added.get(key)) != null ? _a2 : [], channel]);
|
|
6119
|
+
}
|
|
6120
|
+
if (channels.some((channel) => PX_TRANSFORM_FN_NAMES.has(channel)) && mayCarryTransformRestPose(node)) {
|
|
6121
|
+
const parts = firstFrameTransformParts(animate, firstFrameTime);
|
|
6122
|
+
if (parts) {
|
|
6123
|
+
node[TRANSFORM_CHANNEL] = parts;
|
|
6124
|
+
added.set(key, [...(_b = added.get(key)) != null ? _b : [], TRANSFORM_CHANNEL]);
|
|
6125
|
+
}
|
|
6126
|
+
}
|
|
6127
|
+
}
|
|
6128
|
+
if (added.size) {
|
|
6129
|
+
const after = bindingsOf(out, engine);
|
|
6130
|
+
for (const [key, channels] of added) {
|
|
6131
|
+
if (writesTheSameFrames(before.get(key), after.get(key), duration)) continue;
|
|
6132
|
+
const node = nodes.get(key);
|
|
6133
|
+
if (node) for (const channel of channels) delete node[channel];
|
|
6134
|
+
}
|
|
3166
6135
|
}
|
|
6136
|
+
return out;
|
|
3167
6137
|
}
|
|
3168
|
-
function
|
|
3169
|
-
|
|
3170
|
-
if (
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
);
|
|
6138
|
+
function mayCarryRestPose(node, channel) {
|
|
6139
|
+
if (node[channel] !== void 0) return false;
|
|
6140
|
+
if (channel === TRANSFORM_CHANNEL) return mayCarryTransformRestPose(node);
|
|
6141
|
+
return true;
|
|
6142
|
+
}
|
|
6143
|
+
function mayCarryTransformRestPose(node) {
|
|
6144
|
+
if (node[TRANSFORM_CHANNEL] !== void 0) return false;
|
|
6145
|
+
for (const part of PX_TRANSFORM_FN_NAMES) if (node[part] !== void 0) return false;
|
|
6146
|
+
return true;
|
|
6147
|
+
}
|
|
6148
|
+
function firstFrameValue(animate, channel, timeMs) {
|
|
6149
|
+
const values = Object.values(calcAnimationValues({ [channel]: animate[channel] }, timeMs));
|
|
6150
|
+
return values.length === 1 && values[0] !== "" ? values[0] : void 0;
|
|
6151
|
+
}
|
|
6152
|
+
function firstFrameTransformParts(animate, timeMs) {
|
|
6153
|
+
const family = {};
|
|
6154
|
+
for (const channel of Object.keys(animate)) if (PX_TRANSFORM_FN_NAMES.has(channel)) family[channel] = animate[channel];
|
|
6155
|
+
const written = calcAnimationValues(family, timeMs)[TRANSFORM_CHANNEL];
|
|
6156
|
+
if (!written) return void 0;
|
|
6157
|
+
const parts = parseTransformParts(written.replace(/(px|deg)\b/g, ""));
|
|
6158
|
+
return parts && Object.keys(parts).length ? parts : void 0;
|
|
6159
|
+
}
|
|
6160
|
+
function writesTheSameFrames(a, b, durationMs) {
|
|
6161
|
+
if (!a || !b) return a === b;
|
|
6162
|
+
const frame = (animate, t) => JSON.stringify(calcAnimationValues(animate, t)).replace(/\s+/g, "");
|
|
6163
|
+
return VERIFY_SAMPLE_FRACTIONS.every((fraction) => frame(a, fraction * durationMs) === frame(b, fraction * durationMs));
|
|
6164
|
+
}
|
|
6165
|
+
function bindingsOf(tree, engine) {
|
|
6166
|
+
const scratch = deepClone(tree);
|
|
6167
|
+
const keyById = /* @__PURE__ */ new Map();
|
|
6168
|
+
for (const [key, node] of animatedNodes(scratch)) {
|
|
6169
|
+
if (node.id === void 0) node.id = SCRATCH_ID_PREFIX + key;
|
|
6170
|
+
keyById.set(String(node.id), key);
|
|
6171
|
+
}
|
|
6172
|
+
const out = /* @__PURE__ */ new Map();
|
|
6173
|
+
for (const binding of normalizeBindings(scratch, engine)) {
|
|
6174
|
+
const key = keyById.get(binding.id);
|
|
6175
|
+
if (key !== void 0) out.set(key, binding.animate);
|
|
6176
|
+
}
|
|
6177
|
+
return out;
|
|
6178
|
+
}
|
|
6179
|
+
function animatedNodes(tree) {
|
|
6180
|
+
const out = /* @__PURE__ */ new Map();
|
|
6181
|
+
let counter = 0;
|
|
6182
|
+
const visit = (node) => {
|
|
6183
|
+
if (node.animate) out.set(String(counter++), node);
|
|
6184
|
+
if (node.children) for (const child of node.children) visit(child);
|
|
6185
|
+
};
|
|
6186
|
+
if (tree.children) for (const child of tree.children) visit(child);
|
|
6187
|
+
return out;
|
|
6188
|
+
}
|
|
6189
|
+
|
|
6190
|
+
// src/materialize/PxAnimatorMaterializeAll.ts
|
|
6191
|
+
function materializeAllInTree(doc, engine, options) {
|
|
6192
|
+
var _a2, _b;
|
|
6193
|
+
let root = materializeNodeEffects(doc).root;
|
|
6194
|
+
root = materializeOffsetPathsInTree(root);
|
|
6195
|
+
const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : PX_DEFAULT_DURATION_MS;
|
|
6196
|
+
root = materializeInternalLoopsInTree(root, duration);
|
|
6197
|
+
if (engine === PxTimelineEngine.native) {
|
|
6198
|
+
root = materializeMotionPathsInTree(root, options == null ? void 0 : options.motionPath);
|
|
6199
|
+
root = materializeAnimatedUseInstances(root);
|
|
6200
|
+
root = pruneUnreferencedDefs(root);
|
|
6201
|
+
}
|
|
6202
|
+
root = materializeRestPosesInTree(root, engine);
|
|
6203
|
+
return root;
|
|
6204
|
+
}
|
|
6205
|
+
function prepareDocumentForRender(doc) {
|
|
6206
|
+
var _a2;
|
|
6207
|
+
const engine = resolveTimelineEngine((_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.engine);
|
|
6208
|
+
return generateNewIds(materializeAllInTree(doc, engine));
|
|
6209
|
+
}
|
|
6210
|
+
function pruneUnreferencedDefs(root) {
|
|
6211
|
+
const stripHash3 = (h) => h.startsWith("#") ? h.slice(1) : h;
|
|
6212
|
+
const walk = (n, fn) => {
|
|
6213
|
+
var _a2;
|
|
6214
|
+
fn(n);
|
|
6215
|
+
(_a2 = n.children) == null ? void 0 : _a2.forEach((c) => walk(c, fn));
|
|
6216
|
+
};
|
|
6217
|
+
let changed = true;
|
|
6218
|
+
while (changed) {
|
|
6219
|
+
changed = false;
|
|
6220
|
+
const referenced = /* @__PURE__ */ new Set();
|
|
6221
|
+
walk(root, (n) => {
|
|
6222
|
+
if (n.type === "use" && typeof n.href === "string") referenced.add(stripHash3(n.href));
|
|
6223
|
+
});
|
|
6224
|
+
walk(root, (n) => {
|
|
6225
|
+
if (!n.children) return;
|
|
6226
|
+
let kept = n.children;
|
|
6227
|
+
if (n.type === "defs") {
|
|
6228
|
+
kept = kept.filter((c) => !((c.type === "g" || c.type === "symbol") && typeof c.id === "string" && !referenced.has(c.id)));
|
|
6229
|
+
}
|
|
6230
|
+
kept = kept.filter((c) => !(c.type === "defs" && (!c.children || c.children.length === 0)));
|
|
6231
|
+
if (kept.length !== n.children.length) {
|
|
6232
|
+
n.children = kept;
|
|
6233
|
+
changed = true;
|
|
6234
|
+
}
|
|
6235
|
+
});
|
|
6236
|
+
}
|
|
6237
|
+
return root;
|
|
3176
6238
|
}
|
|
3177
6239
|
|
|
3178
6240
|
// src/playback/PxDiagnostics.ts
|
|
6241
|
+
var PxDiagnosticKind = {
|
|
6242
|
+
/** The document is wrong — regenerate or repair the file. */
|
|
6243
|
+
document: "document",
|
|
6244
|
+
/** The page or app cannot provide what the document asks for — fix the mount. */
|
|
6245
|
+
host: "host",
|
|
6246
|
+
/** The platform cannot do it and the player degraded — usually nothing to fix. */
|
|
6247
|
+
platform: "platform",
|
|
6248
|
+
/** The call is wrong or self-contradictory — fix the options or props you passed. */
|
|
6249
|
+
usage: "usage",
|
|
6250
|
+
/** The player failed where it did not expect to — report it to us. */
|
|
6251
|
+
internal: "internal"
|
|
6252
|
+
};
|
|
3179
6253
|
var DOCS_URL = "https://github.com/pixodesk/pixodesk-svg-animator/blob/main/docs/diagnostics.md";
|
|
3180
6254
|
function codeLine(code) {
|
|
3181
6255
|
return "PX" + code + " " + DOCS_URL + "#px" + code;
|
|
@@ -3208,81 +6282,6 @@ function createDiagnostics(config, prefix) {
|
|
|
3208
6282
|
};
|
|
3209
6283
|
}
|
|
3210
6284
|
|
|
3211
|
-
// src/playback/PxScrollMath.ts
|
|
3212
|
-
function isScrollTimeline(config) {
|
|
3213
|
-
return (config == null ? void 0 : config.timelineSource) === "scroll";
|
|
3214
|
-
}
|
|
3215
|
-
function scrollTotalDurationMs(config) {
|
|
3216
|
-
const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : PX_DEFAULT_DURATION_MS;
|
|
3217
|
-
const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
|
|
3218
|
-
return duration * iterations;
|
|
3219
|
-
}
|
|
3220
|
-
function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
|
|
3221
|
-
const s = subjectSize, vp = scrollportSize;
|
|
3222
|
-
switch (phase) {
|
|
3223
|
-
case "cover":
|
|
3224
|
-
return [0, s + vp];
|
|
3225
|
-
case "entry":
|
|
3226
|
-
return [0, Math.min(s, vp)];
|
|
3227
|
-
case "contain":
|
|
3228
|
-
return [Math.min(s, vp), Math.max(s, vp)];
|
|
3229
|
-
case "exit":
|
|
3230
|
-
return [Math.max(s, vp), s + vp];
|
|
3231
|
-
case "entry-crossing":
|
|
3232
|
-
return [0, s];
|
|
3233
|
-
case "exit-crossing":
|
|
3234
|
-
return [vp, s + vp];
|
|
3235
|
-
}
|
|
3236
|
-
}
|
|
3237
|
-
var DEFAULT_PHASE = "cover";
|
|
3238
|
-
function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
|
|
3239
|
-
var _a2;
|
|
3240
|
-
const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
|
|
3241
|
-
const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
|
|
3242
|
-
return u0 + fraction * (u1 - u0);
|
|
3243
|
-
}
|
|
3244
|
-
function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
|
|
3245
|
-
const u = scrollportSize - subjectStart;
|
|
3246
|
-
const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
|
|
3247
|
-
const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
|
|
3248
|
-
if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
|
|
3249
|
-
return clamp((u - uStart) / (uEnd - uStart), 0, 1);
|
|
3250
|
-
}
|
|
3251
|
-
function scrollOffsetProgress(offset, maxOffset, range) {
|
|
3252
|
-
var _a2, _b;
|
|
3253
|
-
const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
|
|
3254
|
-
const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
|
|
3255
|
-
const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
|
|
3256
|
-
if (end <= start) return raw >= end ? 1 : 0;
|
|
3257
|
-
return clamp((raw - start) / (end - start), 0, 1);
|
|
3258
|
-
}
|
|
3259
|
-
function scrollResolveAxis(axis, writingMode) {
|
|
3260
|
-
const a = axis != null ? axis : "block";
|
|
3261
|
-
if (a === "x" || a === "y") return a;
|
|
3262
|
-
const vertical = !!writingMode && writingMode.startsWith("vertical");
|
|
3263
|
-
if (a === "inline") return vertical ? "y" : "x";
|
|
3264
|
-
return vertical ? "x" : "y";
|
|
3265
|
-
}
|
|
3266
|
-
|
|
3267
|
-
// src/util/PxIdUtil.ts
|
|
3268
|
-
var _idCounter = 0;
|
|
3269
|
-
function generateUniqueId() {
|
|
3270
|
-
const timestamp = Date.now().toString(36);
|
|
3271
|
-
const counter = (++_idCounter).toString(36);
|
|
3272
|
-
const random = Math.random().toString(36).substring(2, 6);
|
|
3273
|
-
return "_px_" + timestamp + counter + random;
|
|
3274
|
-
}
|
|
3275
|
-
function deepClone(value) {
|
|
3276
|
-
if (value === null || typeof value !== "object") return value;
|
|
3277
|
-
if (Array.isArray(value)) return value.map((item) => deepClone(item));
|
|
3278
|
-
const obj = value;
|
|
3279
|
-
const cloned = {};
|
|
3280
|
-
for (const key of Object.keys(obj)) {
|
|
3281
|
-
cloned[key] = deepClone(obj[key]);
|
|
3282
|
-
}
|
|
3283
|
-
return cloned;
|
|
3284
|
-
}
|
|
3285
|
-
|
|
3286
6285
|
// src/util/PxNodeProps.ts
|
|
3287
6286
|
var PX_DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
|
|
3288
6287
|
"script",
|
|
@@ -3346,6 +6345,135 @@ function sanitizeAttributeValue(name, value) {
|
|
|
3346
6345
|
}
|
|
3347
6346
|
return value;
|
|
3348
6347
|
}
|
|
6348
|
+
function toDomProps(props) {
|
|
6349
|
+
const propsCopy = {};
|
|
6350
|
+
for (const rawKey of Object.keys(props)) {
|
|
6351
|
+
const key = kebabToCamelCaseWord(rawKey);
|
|
6352
|
+
if (INTERNAL_ATTRS.has(key)) continue;
|
|
6353
|
+
if (key === "style") continue;
|
|
6354
|
+
let value = props[rawKey];
|
|
6355
|
+
if (PX_COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
|
|
6356
|
+
propsCopy[key] = toRGBA(value);
|
|
6357
|
+
} else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
|
|
6358
|
+
const parts = value.value && typeof value.value === "object" ? value.value : value;
|
|
6359
|
+
propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
|
|
6360
|
+
} else if (PX_TRANSFORM_FN_NAMES.has(key)) {
|
|
6361
|
+
if (Array.isArray(value)) {
|
|
6362
|
+
if (key === "translate") value = value.map((v) => v + "px");
|
|
6363
|
+
value = value.join(",");
|
|
6364
|
+
}
|
|
6365
|
+
if (key === "rotate") value = value + "deg";
|
|
6366
|
+
propsCopy[TRANSFORM_ATTR] = key + "(" + value + ")";
|
|
6367
|
+
} else if (Array.isArray(value)) {
|
|
6368
|
+
propsCopy[key] = value.join(",");
|
|
6369
|
+
} else if (value !== void 0 && value !== null) {
|
|
6370
|
+
propsCopy[key] = String(value);
|
|
6371
|
+
}
|
|
6372
|
+
}
|
|
6373
|
+
return propsCopy;
|
|
6374
|
+
}
|
|
6375
|
+
|
|
6376
|
+
// src/render/PxRenderTree.ts
|
|
6377
|
+
var CLASS_NAME_KEY = "className";
|
|
6378
|
+
var CLASS_ATTR2 = "class";
|
|
6379
|
+
var DOM_TYPE_KEY = "domType";
|
|
6380
|
+
var TYPE_ATTR = "type";
|
|
6381
|
+
var DEFAULT_TAG = "g";
|
|
6382
|
+
function renderPxTree(node, factory, diag) {
|
|
6383
|
+
return node ? renderOne(node, factory, diag, true, 0) : null;
|
|
6384
|
+
}
|
|
6385
|
+
function renderOne(node, factory, diag, isRoot, index) {
|
|
6386
|
+
const _a2 = node, { type, children, style } = _a2, props = __objRest(_a2, ["type", "children", "style"]);
|
|
6387
|
+
const tag = type || DEFAULT_TAG;
|
|
6388
|
+
if (PX_DISALLOWED_SVG_TAGS_LOWER.has(tag.toLowerCase())) {
|
|
6389
|
+
(diag != null ? diag : createDiagnostics(void 0, "[PxAnimator]")).warn(PxDiagnosticKind.document, 1103 /* blockedTag */, tag);
|
|
6390
|
+
return null;
|
|
6391
|
+
}
|
|
6392
|
+
const domType = props[DOM_TYPE_KEY];
|
|
6393
|
+
if (domType !== void 0) delete props[DOM_TYPE_KEY];
|
|
6394
|
+
const attrs = {};
|
|
6395
|
+
let inlineStyle;
|
|
6396
|
+
const domProps = toDomProps(props);
|
|
6397
|
+
for (const propName of Object.keys(domProps)) {
|
|
6398
|
+
const sanitized = sanitizeAttributeValue(propName, domProps[propName]);
|
|
6399
|
+
if (sanitized === void 0) continue;
|
|
6400
|
+
if (PX_CSS_ONLY_STYLE_PROPS.has(propName)) {
|
|
6401
|
+
(inlineStyle != null ? inlineStyle : inlineStyle = {})[propName] = String(sanitized);
|
|
6402
|
+
continue;
|
|
6403
|
+
}
|
|
6404
|
+
attrs[propName === CLASS_NAME_KEY ? CLASS_ATTR2 : camelCaseToKebabWordIfNeeded(propName)] = sanitized;
|
|
6405
|
+
}
|
|
6406
|
+
if (domType !== void 0) attrs[TYPE_ATTR] = String(domType);
|
|
6407
|
+
if (style) {
|
|
6408
|
+
for (const styleProp of Object.keys(style)) (inlineStyle != null ? inlineStyle : inlineStyle = {})[styleProp] = String(style[styleProp]);
|
|
6409
|
+
}
|
|
6410
|
+
const rendered = [];
|
|
6411
|
+
if (children) {
|
|
6412
|
+
children.forEach((child, i) => {
|
|
6413
|
+
const el = renderOne(child, factory, diag, false, i);
|
|
6414
|
+
if (el !== null) rendered.push(el);
|
|
6415
|
+
});
|
|
6416
|
+
}
|
|
6417
|
+
const ownText = props[PX_TEXT_CONTENT_ATTR];
|
|
6418
|
+
const text = !rendered.length && typeof ownText === "string" && ownText ? ownText : void 0;
|
|
6419
|
+
return factory({ tag, attrs, style: inlineStyle, children: rendered, text, node, isRoot, index });
|
|
6420
|
+
}
|
|
6421
|
+
|
|
6422
|
+
// src/playback/PxScrollMath.ts
|
|
6423
|
+
function isScrollTimeline(config) {
|
|
6424
|
+
return (config == null ? void 0 : config.timelineSource) === "scroll";
|
|
6425
|
+
}
|
|
6426
|
+
function scrollTotalDurationMs(config) {
|
|
6427
|
+
const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : PX_DEFAULT_DURATION_MS;
|
|
6428
|
+
const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
|
|
6429
|
+
return duration * iterations;
|
|
6430
|
+
}
|
|
6431
|
+
function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
|
|
6432
|
+
const s = subjectSize, vp = scrollportSize;
|
|
6433
|
+
switch (phase) {
|
|
6434
|
+
case "cover":
|
|
6435
|
+
return [0, s + vp];
|
|
6436
|
+
case "entry":
|
|
6437
|
+
return [0, Math.min(s, vp)];
|
|
6438
|
+
case "contain":
|
|
6439
|
+
return [Math.min(s, vp), Math.max(s, vp)];
|
|
6440
|
+
case "exit":
|
|
6441
|
+
return [Math.max(s, vp), s + vp];
|
|
6442
|
+
case "entry-crossing":
|
|
6443
|
+
return [0, s];
|
|
6444
|
+
case "exit-crossing":
|
|
6445
|
+
return [vp, s + vp];
|
|
6446
|
+
}
|
|
6447
|
+
}
|
|
6448
|
+
var DEFAULT_PHASE = "cover";
|
|
6449
|
+
function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
|
|
6450
|
+
var _a2;
|
|
6451
|
+
const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
|
|
6452
|
+
const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
|
|
6453
|
+
return u0 + fraction * (u1 - u0);
|
|
6454
|
+
}
|
|
6455
|
+
function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
|
|
6456
|
+
const u = scrollportSize - subjectStart;
|
|
6457
|
+
const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
|
|
6458
|
+
const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
|
|
6459
|
+
if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
|
|
6460
|
+
return clamp((u - uStart) / (uEnd - uStart), 0, 1);
|
|
6461
|
+
}
|
|
6462
|
+
function scrollOffsetProgress(offset, maxOffset, range) {
|
|
6463
|
+
var _a2, _b;
|
|
6464
|
+
const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
|
|
6465
|
+
const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
|
|
6466
|
+
const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
|
|
6467
|
+
if (end <= start) return raw >= end ? 1 : 0;
|
|
6468
|
+
return clamp((raw - start) / (end - start), 0, 1);
|
|
6469
|
+
}
|
|
6470
|
+
function scrollResolveAxis(axis, writingMode) {
|
|
6471
|
+
const a = axis != null ? axis : "block";
|
|
6472
|
+
if (a === "x" || a === "y") return a;
|
|
6473
|
+
const vertical = !!writingMode && writingMode.startsWith("vertical");
|
|
6474
|
+
if (a === "inline") return vertical ? "y" : "x";
|
|
6475
|
+
return vertical ? "x" : "y";
|
|
6476
|
+
}
|
|
3349
6477
|
|
|
3350
6478
|
// src/version/PxSchemaFieldUniverse.ts
|
|
3351
6479
|
function schemaFieldUniverse(root) {
|
|
@@ -3476,6 +6604,7 @@ function releaseLogProblems(releases, steps, declared, baseline) {
|
|
|
3476
6604
|
PX_COLOR_ATTR_NAMES,
|
|
3477
6605
|
PX_CSS_ONLY_STYLE_PROPS,
|
|
3478
6606
|
PX_DEFAULT_DURATION_MS,
|
|
6607
|
+
PX_DEFAULT_ITERATIONS,
|
|
3479
6608
|
PX_DISALLOWED_SVG_TAGS_LOWER,
|
|
3480
6609
|
PX_LOOP_JUMP_SHIFT_MS,
|
|
3481
6610
|
PX_PCT_BASED_ATTR_NAMES,
|
|
@@ -3506,7 +6635,9 @@ function releaseLogProblems(releases, steps, declared, baseline) {
|
|
|
3506
6635
|
materializeMotionPathInPropAnim,
|
|
3507
6636
|
mergeStaticTransformIntoAnimDef,
|
|
3508
6637
|
planSchemaRelease,
|
|
6638
|
+
prepareDocumentForRender,
|
|
3509
6639
|
releaseLogProblems,
|
|
6640
|
+
renderPxTree,
|
|
3510
6641
|
reportDocumentDiagnostics,
|
|
3511
6642
|
reverseEasing,
|
|
3512
6643
|
sanitizeAttributeValue,
|