@vvfx/ge-ir 0.0.1-beat.2
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/LICENSE +22 -0
- package/README.md +66 -0
- package/dist/ge2ir/converter.d.ts +3 -0
- package/dist/ge2ir/index.d.ts +2 -0
- package/dist/ge2ir/merge/merge.d.ts +9 -0
- package/dist/ge2ir/parsers/animation-parser.d.ts +4 -0
- package/dist/ge2ir/parsers/component-parser.d.ts +16 -0
- package/dist/ge2ir/parsers/keyframe-parser.d.ts +7 -0
- package/dist/ge2ir/parsers/timeline-parser.d.ts +9 -0
- package/dist/ge2ir/parsers/transform-parser.d.ts +3 -0
- package/dist/ge2ir/pool/pool.d.ts +4 -0
- package/dist/ge2ir/reverse/blend-mode.d.ts +2 -0
- package/dist/ge2ir/reverse/coordinate.d.ts +1 -0
- package/dist/ge2ir/reverse/end-behavior.d.ts +3 -0
- package/dist/ge2ir/reverse/timing.d.ts +2 -0
- package/dist/ge2ir/scene-reader.d.ts +3 -0
- package/dist/ge2ir/types.d.ts +24 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +4812 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4790 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ir2ge/assembly/generator.d.ts +23 -0
- package/dist/ir2ge/assembly/scene-assembly.d.ts +11 -0
- package/dist/ir2ge/builders/animation.d.ts +4 -0
- package/dist/ir2ge/builders/bezier.d.ts +44 -0
- package/dist/ir2ge/builders/component.d.ts +13 -0
- package/dist/ir2ge/builders/effects.d.ts +9 -0
- package/dist/ir2ge/builders/layer.d.ts +5 -0
- package/dist/ir2ge/builders/timeline.d.ts +9 -0
- package/dist/ir2ge/builders/timing.d.ts +17 -0
- package/dist/ir2ge/index.d.ts +14 -0
- package/dist/ir2ge/ir/anchor-strategy.d.ts +24 -0
- package/dist/ir2ge/ir/layer-dimensions.d.ts +13 -0
- package/dist/ir2ge/ir/layer-utils.d.ts +14 -0
- package/dist/ir2ge/ir/parent-link.d.ts +15 -0
- package/dist/ir2ge/ir/specific.d.ts +14 -0
- package/dist/ir2ge/post-process/ge-mask-remap.d.ts +18 -0
- package/dist/ir2ge/post-process/index.d.ts +31 -0
- package/dist/ir2ge/post-process/mask.d.ts +26 -0
- package/dist/ir2ge/post-process/parenting.d.ts +3 -0
- package/dist/ir2ge/post-process/visibility.d.ts +26 -0
- package/dist/ir2ge/types.d.ts +37 -0
- package/dist/ir2ge/utils.d.ts +14 -0
- package/dist/shared/coordinate.d.ts +11 -0
- package/dist/shared/ge2ir-metadata.d.ts +17 -0
- package/dist/shared/types.d.ts +60 -0
- package/package.json +42 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,4790 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Name: @vvfx/ge-ir
|
|
3
|
+
* Description: Galacean Effects and animation IR bidirectional conversion package
|
|
4
|
+
* Author: Ant Group CO., Ltd.
|
|
5
|
+
* Contributors: 澄弈
|
|
6
|
+
* Version: v0.0.1-beat.2
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { IRBlendMode, IRShapePrimitiveType, IRFillType, IRLineCap, IRLineJoin, IRShapeFillRule, IREndBehavior, validateIRCompositionWithWarnings } from '@vvfx/animation-ir';
|
|
10
|
+
import { v4 } from 'uuid';
|
|
11
|
+
import { BezierKeyframeType, ValueType, JSONSceneVersion } from '@galacean/effects-specification';
|
|
12
|
+
|
|
13
|
+
function _extends() {
|
|
14
|
+
_extends = Object.assign || function assign(target) {
|
|
15
|
+
for(var i = 1; i < arguments.length; i++){
|
|
16
|
+
var source = arguments[i];
|
|
17
|
+
for(var key in source)if (Object.prototype.hasOwnProperty.call(source, key)) target[key] = source[key];
|
|
18
|
+
}
|
|
19
|
+
return target;
|
|
20
|
+
};
|
|
21
|
+
return _extends.apply(this, arguments);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function _array_like_to_array(arr, len) {
|
|
25
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
26
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
27
|
+
return arr2;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
31
|
+
if (!o) return;
|
|
32
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
33
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
34
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
35
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
36
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function _create_for_of_iterator_helper_loose(o, allowArrayLike) {
|
|
40
|
+
var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
|
|
41
|
+
if (it) return (it = it.call(o)).next.bind(it);
|
|
42
|
+
// Fallback for engines without symbol support
|
|
43
|
+
if (Array.isArray(o) || (it = _unsupported_iterable_to_array(o)) || allowArrayLike) {
|
|
44
|
+
if (it) o = it;
|
|
45
|
+
var i = 0;
|
|
46
|
+
return function() {
|
|
47
|
+
if (i >= o.length) return {
|
|
48
|
+
done: true
|
|
49
|
+
};
|
|
50
|
+
return {
|
|
51
|
+
done: false,
|
|
52
|
+
value: o[i++]
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
var DEFAULT_CAMERA_Z = 8;
|
|
60
|
+
var DEFAULT_CAMERA_FOV = 60;
|
|
61
|
+
var DEFAULT_CLIP_MODE = 1;
|
|
62
|
+
/** 2D pixel space -> GE 3D world unit ratio for a given canvas size. */ function get2dTo3dRatio(width, height) {
|
|
63
|
+
var ratio = 2 / height * DEFAULT_CAMERA_Z * Math.tan(DEFAULT_CAMERA_FOV / 2 * (Math.PI / 180)) + 1e-6;
|
|
64
|
+
{
|
|
65
|
+
ratio *= height / width;
|
|
66
|
+
}
|
|
67
|
+
return ratio;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Convert a 2D point in canvas pixel space (origin top-left) to a GE 3D world
|
|
71
|
+
* point (origin centered, Y flipped). The `z` parameter applies the GE camera
|
|
72
|
+
* adapter to stay perspective-correct for non-zero Z layers.
|
|
73
|
+
*/ function convert2dTo3dPoint(x, y, z, width, height) {
|
|
74
|
+
var ratio = get2dTo3dRatio(width, height);
|
|
75
|
+
var adaptRatioZ = (DEFAULT_CAMERA_Z - z) / DEFAULT_CAMERA_Z;
|
|
76
|
+
var offsetX = (x - width / 2.0) * ratio * adaptRatioZ;
|
|
77
|
+
var offsetY = (height / 2.0 - y) * ratio * adaptRatioZ;
|
|
78
|
+
return [
|
|
79
|
+
offsetX,
|
|
80
|
+
offsetY,
|
|
81
|
+
z
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// ── IDs ──
|
|
86
|
+
/** Generate a 32-char hex GE entity id (UUID v4 with dashes stripped). */ function createId() {
|
|
87
|
+
return v4().replace(/-/g, '');
|
|
88
|
+
}
|
|
89
|
+
/** Wrap an id into a `{ id }` GE DataPath reference. */ function toDataPath(id) {
|
|
90
|
+
return {
|
|
91
|
+
id: id
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// ── Numbers ──
|
|
95
|
+
/** Round a number to the given decimal precision (default 4). */ function roundNumber(value, precision) {
|
|
96
|
+
if (precision === void 0) precision = 4;
|
|
97
|
+
var factor = Math.pow(10, precision);
|
|
98
|
+
return Math.round(value * factor) / factor;
|
|
99
|
+
}
|
|
100
|
+
/** Linear interpolation between `a` and `b` by `factor` ∈ [0, 1]. */ function lerp(a, b, factor) {
|
|
101
|
+
return (1 - factor) * a + factor * b;
|
|
102
|
+
}
|
|
103
|
+
// ── Text metrics ──
|
|
104
|
+
/**
|
|
105
|
+
* Rough text width estimate used when the IR layer does not record a
|
|
106
|
+
* measured width. Average character width ≈ 0.6 × fontSize.
|
|
107
|
+
*/ function estimateTextWidth(text, fontSize, letterSpacing) {
|
|
108
|
+
if (text.length === 0) {
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
var avgCharWidth = fontSize * 0.6;
|
|
112
|
+
var spacing = (letterSpacing != null ? letterSpacing : 0) * (text.length - 1);
|
|
113
|
+
return text.length * avgCharWidth + spacing;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Build the ObjectBindingTrack + Activation/Transform/SpriteColor child tracks
|
|
118
|
+
* for one VFX item. Shared by lottie2ge and dsl2ge generators.
|
|
119
|
+
*
|
|
120
|
+
* The SpriteColor track is omitted for null layers (itemType `'null'` or
|
|
121
|
+
* the GE numeric code `'3'`).
|
|
122
|
+
*/ function buildTimelineTracks(collector, delay, duration, endBehavior, animation, itemType) {
|
|
123
|
+
var objectBindingTrackId = createId();
|
|
124
|
+
var childTrackIds = [];
|
|
125
|
+
childTrackIds.push(toDataPath(buildActivationTrack(collector, delay, duration, endBehavior)));
|
|
126
|
+
childTrackIds.push(toDataPath(buildTransformTrack(collector, delay, duration, endBehavior, animation)));
|
|
127
|
+
if (!isNullItemType(itemType)) {
|
|
128
|
+
childTrackIds.push(toDataPath(buildSpriteColorTrack(collector, delay, duration, endBehavior, animation)));
|
|
129
|
+
}
|
|
130
|
+
collector.miscs.push({
|
|
131
|
+
id: objectBindingTrackId,
|
|
132
|
+
dataType: 'ObjectBindingTrack',
|
|
133
|
+
children: childTrackIds,
|
|
134
|
+
clips: []
|
|
135
|
+
});
|
|
136
|
+
return objectBindingTrackId;
|
|
137
|
+
}
|
|
138
|
+
function isNullItemType(itemType) {
|
|
139
|
+
return itemType === 'null' || itemType === '3';
|
|
140
|
+
}
|
|
141
|
+
function buildActivationTrack(collector, delay, duration, endBehavior) {
|
|
142
|
+
var assetId = createId();
|
|
143
|
+
collector.miscs.push({
|
|
144
|
+
id: assetId,
|
|
145
|
+
dataType: 'ActivationPlayableAsset'
|
|
146
|
+
});
|
|
147
|
+
var trackId = createId();
|
|
148
|
+
var clip = {
|
|
149
|
+
start: roundNumber(delay, 4),
|
|
150
|
+
duration: roundNumber(duration, 4),
|
|
151
|
+
endBehavior: endBehavior,
|
|
152
|
+
asset: toDataPath(assetId)
|
|
153
|
+
};
|
|
154
|
+
collector.miscs.push({
|
|
155
|
+
id: trackId,
|
|
156
|
+
dataType: 'ActivationTrack',
|
|
157
|
+
children: [],
|
|
158
|
+
clips: [
|
|
159
|
+
clip
|
|
160
|
+
]
|
|
161
|
+
});
|
|
162
|
+
return trackId;
|
|
163
|
+
}
|
|
164
|
+
function buildTransformTrack(collector, delay, duration, endBehavior, animation) {
|
|
165
|
+
var _animation_positionOverLifetime;
|
|
166
|
+
var assetId = createId();
|
|
167
|
+
var asset = {
|
|
168
|
+
id: assetId,
|
|
169
|
+
dataType: 'TransformPlayableAsset',
|
|
170
|
+
positionOverLifetime: (_animation_positionOverLifetime = animation.positionOverLifetime) != null ? _animation_positionOverLifetime : {}
|
|
171
|
+
};
|
|
172
|
+
if (animation.rotationOverLifetime != null) {
|
|
173
|
+
asset['rotationOverLifetime'] = animation.rotationOverLifetime;
|
|
174
|
+
}
|
|
175
|
+
if (animation.sizeOverLifetime != null) {
|
|
176
|
+
asset['sizeOverLifetime'] = animation.sizeOverLifetime;
|
|
177
|
+
}
|
|
178
|
+
collector.miscs.push(asset);
|
|
179
|
+
var trackId = createId();
|
|
180
|
+
collector.miscs.push({
|
|
181
|
+
id: trackId,
|
|
182
|
+
dataType: 'TransformTrack',
|
|
183
|
+
children: [],
|
|
184
|
+
clips: [
|
|
185
|
+
{
|
|
186
|
+
start: roundNumber(delay, 4),
|
|
187
|
+
duration: roundNumber(duration, 4),
|
|
188
|
+
endBehavior: endBehavior,
|
|
189
|
+
asset: toDataPath(assetId)
|
|
190
|
+
}
|
|
191
|
+
]
|
|
192
|
+
});
|
|
193
|
+
return trackId;
|
|
194
|
+
}
|
|
195
|
+
function buildSpriteColorTrack(collector, delay, duration, endBehavior, animation) {
|
|
196
|
+
var assetId = createId();
|
|
197
|
+
var asset = {
|
|
198
|
+
id: assetId,
|
|
199
|
+
dataType: 'SpriteColorPlayableAsset',
|
|
200
|
+
startColor: [
|
|
201
|
+
1,
|
|
202
|
+
1,
|
|
203
|
+
1,
|
|
204
|
+
1
|
|
205
|
+
]
|
|
206
|
+
};
|
|
207
|
+
if (animation.colorOverLifetime != null) {
|
|
208
|
+
asset['colorOverLifetime'] = animation.colorOverLifetime;
|
|
209
|
+
}
|
|
210
|
+
collector.miscs.push(asset);
|
|
211
|
+
var trackId = createId();
|
|
212
|
+
collector.miscs.push({
|
|
213
|
+
id: trackId,
|
|
214
|
+
dataType: 'SpriteColorTrack',
|
|
215
|
+
children: [],
|
|
216
|
+
clips: [
|
|
217
|
+
{
|
|
218
|
+
start: roundNumber(delay, 4),
|
|
219
|
+
duration: roundNumber(duration, 4),
|
|
220
|
+
endBehavior: endBehavior,
|
|
221
|
+
asset: toDataPath(assetId)
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
});
|
|
225
|
+
return trackId;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
var DEFAULT_OUT_TANGENT = {
|
|
229
|
+
x: 0.33,
|
|
230
|
+
y: 0.33
|
|
231
|
+
};
|
|
232
|
+
var DEFAULT_IN_TANGENT = {
|
|
233
|
+
x: 0.67,
|
|
234
|
+
y: 0.67
|
|
235
|
+
};
|
|
236
|
+
function normalizeTime(frameTime, startFrame, endFrame) {
|
|
237
|
+
var frames = Math.max(1, endFrame - startFrame);
|
|
238
|
+
return (frameTime - startFrame) / frames;
|
|
239
|
+
}
|
|
240
|
+
function getScalarValue(keyframe, dimensionIndex) {
|
|
241
|
+
var value = keyframe.value;
|
|
242
|
+
if (typeof value === 'number') {
|
|
243
|
+
return value;
|
|
244
|
+
}
|
|
245
|
+
if (Array.isArray(value) && dimensionIndex != null) {
|
|
246
|
+
var _value_dimensionIndex;
|
|
247
|
+
return (_value_dimensionIndex = value[dimensionIndex]) != null ? _value_dimensionIndex : 0;
|
|
248
|
+
}
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Convert a 1D animated property (opacity / rotation) to GE BezierKeyframeValue[][].
|
|
253
|
+
* Returns a single-element outer array with the full curve.
|
|
254
|
+
*/ function irScalarKeyframesToGE(property, timeContext) {
|
|
255
|
+
if (!property.keyframed || property.keyframes == null || property.keyframes.length < 2) {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
var curve = buildCurveForDimension(property.keyframes, timeContext, undefined);
|
|
259
|
+
return curve != null ? [
|
|
260
|
+
curve
|
|
261
|
+
] : undefined;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Convert a multi-dimensional animated property (scale / anchor) to GE BezierKeyframeValue[][].
|
|
265
|
+
* Returns one curve per dimension in the outer array.
|
|
266
|
+
*/ function irVectorKeyframesToGE(property, timeContext) {
|
|
267
|
+
if (!property.keyframed || property.keyframes == null || property.keyframes.length < 2) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
var firstValue = property.keyframes[0].value;
|
|
271
|
+
var dimensions = Array.isArray(firstValue) ? firstValue.length : 1;
|
|
272
|
+
var curves = [];
|
|
273
|
+
for(var d = 0; d < dimensions; d++){
|
|
274
|
+
var curve = buildCurveForDimension(property.keyframes, timeContext, d);
|
|
275
|
+
curves.push(curve != null ? curve : []);
|
|
276
|
+
}
|
|
277
|
+
return curves.length > 0 ? curves : undefined;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Convert position keyframes to GE path animation format (pp/cp + timing curves).
|
|
281
|
+
*/ function irPositionKeyframesToGE(property, timeContext) {
|
|
282
|
+
if (!property.keyframed || property.keyframes == null || property.keyframes.length < 2) {
|
|
283
|
+
return undefined;
|
|
284
|
+
}
|
|
285
|
+
var keyframes = property.keyframes;
|
|
286
|
+
var pathPoints = [];
|
|
287
|
+
var controlPoints = [];
|
|
288
|
+
var timingCurvePoints = [];
|
|
289
|
+
for(var i = 0; i < keyframes.length; i++){
|
|
290
|
+
var _kf_outTangent, _kf_inTangent;
|
|
291
|
+
var kf = keyframes[i];
|
|
292
|
+
var normalizedT = normalizeTime(kf.t, timeContext.startFrame, timeContext.endFrame);
|
|
293
|
+
timingCurvePoints.push({
|
|
294
|
+
t: normalizedT,
|
|
295
|
+
outTangent: (_kf_outTangent = kf.outTangent) != null ? _kf_outTangent : DEFAULT_OUT_TANGENT,
|
|
296
|
+
inTangent: (_kf_inTangent = kf.inTangent) != null ? _kf_inTangent : DEFAULT_IN_TANGENT
|
|
297
|
+
});
|
|
298
|
+
if (i < keyframes.length - 1) {
|
|
299
|
+
var _kf_value, _kf_endValue, _nextKf_value, _startPos_, _startPos_1, _stitchEnd_, _stitchEnd_1;
|
|
300
|
+
var nextKf = keyframes[i + 1];
|
|
301
|
+
var startPos = (_kf_value = kf.value) != null ? _kf_value : [
|
|
302
|
+
0,
|
|
303
|
+
0,
|
|
304
|
+
0
|
|
305
|
+
];
|
|
306
|
+
// Lottie segment end value: kf.endValue is authoritative; falls back to kf.value (mirrors master's `e ?? s`).
|
|
307
|
+
// nextKf.value is only used later in the path-fixup pass to stitch adjacent segments.
|
|
308
|
+
var segmentEnd = kf.hold === true ? startPos : (_kf_endValue = kf.endValue) != null ? _kf_endValue : startPos;
|
|
309
|
+
var stitchEnd = kf.hold === true ? startPos : (_nextKf_value = nextKf.value) != null ? _nextKf_value : [
|
|
310
|
+
0,
|
|
311
|
+
0,
|
|
312
|
+
0
|
|
313
|
+
];
|
|
314
|
+
pathPoints.push([
|
|
315
|
+
[
|
|
316
|
+
(_startPos_ = startPos[0]) != null ? _startPos_ : 0,
|
|
317
|
+
(_startPos_1 = startPos[1]) != null ? _startPos_1 : 0
|
|
318
|
+
],
|
|
319
|
+
[
|
|
320
|
+
(_stitchEnd_ = stitchEnd[0]) != null ? _stitchEnd_ : 0,
|
|
321
|
+
(_stitchEnd_1 = stitchEnd[1]) != null ? _stitchEnd_1 : 0
|
|
322
|
+
]
|
|
323
|
+
]);
|
|
324
|
+
// Spatial control points (per IRKeyframe convention): outgoing CP from
|
|
325
|
+
// kf[i].spatialOut, incoming CP from kf[i+1].spatialIn. Without explicit
|
|
326
|
+
// spatial handles on either side, use linear one-third handles.
|
|
327
|
+
var toPoint = void 0;
|
|
328
|
+
var tiPoint = void 0;
|
|
329
|
+
if (kf.spatialOut != null && nextKf.spatialIn != null) {
|
|
330
|
+
var _kf_spatialOut_, _kf_spatialOut_1, _nextKf_spatialIn_, _nextKf_spatialIn_1;
|
|
331
|
+
toPoint = [
|
|
332
|
+
(_kf_spatialOut_ = kf.spatialOut[0]) != null ? _kf_spatialOut_ : 0,
|
|
333
|
+
(_kf_spatialOut_1 = kf.spatialOut[1]) != null ? _kf_spatialOut_1 : 0
|
|
334
|
+
];
|
|
335
|
+
tiPoint = [
|
|
336
|
+
(_nextKf_spatialIn_ = nextKf.spatialIn[0]) != null ? _nextKf_spatialIn_ : 0,
|
|
337
|
+
(_nextKf_spatialIn_1 = nextKf.spatialIn[1]) != null ? _nextKf_spatialIn_1 : 0
|
|
338
|
+
];
|
|
339
|
+
} else {
|
|
340
|
+
var _startPos_2, _startPos_3, _segmentEnd_, _segmentEnd_1;
|
|
341
|
+
var sx = (_startPos_2 = startPos[0]) != null ? _startPos_2 : 0;
|
|
342
|
+
var sy = (_startPos_3 = startPos[1]) != null ? _startPos_3 : 0;
|
|
343
|
+
var ex = (_segmentEnd_ = segmentEnd[0]) != null ? _segmentEnd_ : 0;
|
|
344
|
+
var ey = (_segmentEnd_1 = segmentEnd[1]) != null ? _segmentEnd_1 : 0;
|
|
345
|
+
toPoint = [
|
|
346
|
+
-sx / 3 + ex / 3,
|
|
347
|
+
-sy / 3 + ey / 3
|
|
348
|
+
];
|
|
349
|
+
tiPoint = [
|
|
350
|
+
sx / 3 - ex / 3,
|
|
351
|
+
sy / 3 - ey / 3
|
|
352
|
+
];
|
|
353
|
+
}
|
|
354
|
+
controlPoints.push([
|
|
355
|
+
toPoint,
|
|
356
|
+
tiPoint
|
|
357
|
+
]);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Fix up path points: adjacent segments should share endpoints
|
|
361
|
+
for(var i1 = 0; i1 < pathPoints.length - 1; i1++){
|
|
362
|
+
pathPoints[i1][1] = pathPoints[i1 + 1][0];
|
|
363
|
+
}
|
|
364
|
+
// Prepend a static segment if the first keyframe doesn't start at t=0.
|
|
365
|
+
// The bridge segment runs synthetic-at-t=0 → original-kf[0]; for it to be a
|
|
366
|
+
// flat hold the END-side tangent (which `buildPositionTimingCurves` reads as
|
|
367
|
+
// `next.inTangent`) must be {1, 1}. Override the original first kf's
|
|
368
|
+
// inTangent before unshifting (its previous value was either DEFAULT, since
|
|
369
|
+
// the IR convention leaves a first-kf inTangent undefined, or whatever the
|
|
370
|
+
// producer set as a no-op).
|
|
371
|
+
if (timingCurvePoints.length > 0 && timingCurvePoints[0].t > 0) {
|
|
372
|
+
var _ref, _ref1;
|
|
373
|
+
var _pathPoints_, _pathPoints_1;
|
|
374
|
+
timingCurvePoints[0].inTangent = {
|
|
375
|
+
x: 1,
|
|
376
|
+
y: 1
|
|
377
|
+
};
|
|
378
|
+
timingCurvePoints.unshift({
|
|
379
|
+
t: 0,
|
|
380
|
+
outTangent: {
|
|
381
|
+
x: 0,
|
|
382
|
+
y: 0
|
|
383
|
+
},
|
|
384
|
+
inTangent: {
|
|
385
|
+
x: 1,
|
|
386
|
+
y: 1
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
pathPoints.unshift([
|
|
390
|
+
(_ref = (_pathPoints_ = pathPoints[0]) == null ? void 0 : _pathPoints_[0]) != null ? _ref : [
|
|
391
|
+
0,
|
|
392
|
+
0
|
|
393
|
+
],
|
|
394
|
+
(_ref1 = (_pathPoints_1 = pathPoints[0]) == null ? void 0 : _pathPoints_1[0]) != null ? _ref1 : [
|
|
395
|
+
0,
|
|
396
|
+
0
|
|
397
|
+
]
|
|
398
|
+
]);
|
|
399
|
+
controlPoints.unshift([
|
|
400
|
+
[
|
|
401
|
+
0,
|
|
402
|
+
0
|
|
403
|
+
],
|
|
404
|
+
[
|
|
405
|
+
0,
|
|
406
|
+
0
|
|
407
|
+
]
|
|
408
|
+
]);
|
|
409
|
+
}
|
|
410
|
+
// Build timing-only bezier curves (in time-time domain)
|
|
411
|
+
var timingCurves = buildPositionTimingCurves(timingCurvePoints);
|
|
412
|
+
return {
|
|
413
|
+
curves: timingCurves != null ? [
|
|
414
|
+
timingCurves
|
|
415
|
+
] : [
|
|
416
|
+
[]
|
|
417
|
+
],
|
|
418
|
+
pathPoints: pathPoints,
|
|
419
|
+
controlPoints: controlPoints
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
// ─── Internal helpers ───────────────────────────────────────
|
|
423
|
+
function makeEaseOut(seg) {
|
|
424
|
+
return [
|
|
425
|
+
BezierKeyframeType.EASE_OUT,
|
|
426
|
+
[
|
|
427
|
+
roundNumber(seg[0], 4),
|
|
428
|
+
roundNumber(seg[1], 4),
|
|
429
|
+
roundNumber(seg[2], 4),
|
|
430
|
+
roundNumber(seg[3], 4)
|
|
431
|
+
],
|
|
432
|
+
BezierKeyframeType.EASE_OUT
|
|
433
|
+
];
|
|
434
|
+
}
|
|
435
|
+
function makeEaseIn(prevSeg) {
|
|
436
|
+
return [
|
|
437
|
+
BezierKeyframeType.EASE_IN,
|
|
438
|
+
[
|
|
439
|
+
roundNumber(prevSeg[4], 4),
|
|
440
|
+
roundNumber(prevSeg[5], 4),
|
|
441
|
+
roundNumber(prevSeg[6], 4),
|
|
442
|
+
roundNumber(prevSeg[7], 4)
|
|
443
|
+
],
|
|
444
|
+
BezierKeyframeType.EASE_IN
|
|
445
|
+
];
|
|
446
|
+
}
|
|
447
|
+
function makeEase(prevSeg, currSeg) {
|
|
448
|
+
return [
|
|
449
|
+
BezierKeyframeType.EASE,
|
|
450
|
+
[
|
|
451
|
+
roundNumber(prevSeg[4], 4),
|
|
452
|
+
roundNumber(prevSeg[5], 4),
|
|
453
|
+
roundNumber(prevSeg[6], 4),
|
|
454
|
+
roundNumber(prevSeg[7], 4),
|
|
455
|
+
roundNumber(currSeg[2], 4),
|
|
456
|
+
roundNumber(currSeg[3], 4)
|
|
457
|
+
],
|
|
458
|
+
BezierKeyframeType.EASE
|
|
459
|
+
];
|
|
460
|
+
}
|
|
461
|
+
function buildCurveForDimension(keyframes, timeContext, dimensionIndex) {
|
|
462
|
+
if (keyframes.length < 2) {
|
|
463
|
+
return undefined;
|
|
464
|
+
}
|
|
465
|
+
// Build intermediate bezier representation
|
|
466
|
+
var bezierCurves = [];
|
|
467
|
+
for(var i = 0; i < keyframes.length - 1; i++){
|
|
468
|
+
var _kf_outTangent, _nextKf_inTangent;
|
|
469
|
+
var kf = keyframes[i];
|
|
470
|
+
var nextKf = keyframes[i + 1];
|
|
471
|
+
var t0 = normalizeTime(kf.t, timeContext.startFrame, timeContext.endFrame);
|
|
472
|
+
var t1 = normalizeTime(nextKf.t, timeContext.startFrame, timeContext.endFrame);
|
|
473
|
+
var v0 = getScalarValue(kf, dimensionIndex);
|
|
474
|
+
var v1 = kf.hold === true ? v0 : getScalarValue(nextKf, dimensionIndex);
|
|
475
|
+
var outHandle = kf.hold === true ? {
|
|
476
|
+
x: 0,
|
|
477
|
+
y: 0
|
|
478
|
+
} : (_kf_outTangent = kf.outTangent) != null ? _kf_outTangent : DEFAULT_OUT_TANGENT;
|
|
479
|
+
// Per IR convention, the incoming tangent for segment i lives on kf[i+1].
|
|
480
|
+
var inHandle = kf.hold === true ? {
|
|
481
|
+
x: 1,
|
|
482
|
+
y: 1
|
|
483
|
+
} : (_nextKf_inTangent = nextKf.inTangent) != null ? _nextKf_inTangent : DEFAULT_IN_TANGENT;
|
|
484
|
+
var outCpX = lerp(t0, t1, outHandle.x);
|
|
485
|
+
var outCpY = lerp(v0, v1, outHandle.y);
|
|
486
|
+
var inCpX = lerp(t0, t1, inHandle.x);
|
|
487
|
+
var inCpY = lerp(v0, v1, inHandle.y);
|
|
488
|
+
bezierCurves.push([
|
|
489
|
+
t0,
|
|
490
|
+
v0,
|
|
491
|
+
outCpX,
|
|
492
|
+
outCpY,
|
|
493
|
+
inCpX,
|
|
494
|
+
inCpY,
|
|
495
|
+
t1,
|
|
496
|
+
v1
|
|
497
|
+
]);
|
|
498
|
+
}
|
|
499
|
+
if (bezierCurves.length === 0) {
|
|
500
|
+
return undefined;
|
|
501
|
+
}
|
|
502
|
+
// Prepend a hold segment if first keyframe is not at t=0
|
|
503
|
+
var firstT = bezierCurves[0][0];
|
|
504
|
+
if (firstT > 0) {
|
|
505
|
+
var firstV = bezierCurves[0][1];
|
|
506
|
+
bezierCurves.unshift([
|
|
507
|
+
0,
|
|
508
|
+
firstV,
|
|
509
|
+
0,
|
|
510
|
+
firstV,
|
|
511
|
+
firstT,
|
|
512
|
+
firstV,
|
|
513
|
+
firstT,
|
|
514
|
+
firstV
|
|
515
|
+
]);
|
|
516
|
+
}
|
|
517
|
+
// Convert to GE BezierKeyframeValue format
|
|
518
|
+
var result = [];
|
|
519
|
+
var totalPoints = bezierCurves.length + 1;
|
|
520
|
+
for(var i1 = 0; i1 < totalPoints; i1++){
|
|
521
|
+
if (i1 === 0) {
|
|
522
|
+
result.push(makeEaseOut(bezierCurves[0]));
|
|
523
|
+
} else if (i1 === totalPoints - 1) {
|
|
524
|
+
result.push(makeEaseIn(bezierCurves[i1 - 1]));
|
|
525
|
+
} else {
|
|
526
|
+
result.push(makeEase(bezierCurves[i1 - 1], bezierCurves[i1]));
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
return result;
|
|
530
|
+
}
|
|
531
|
+
function buildPositionTimingCurves(points) {
|
|
532
|
+
if (points.length < 2) {
|
|
533
|
+
return undefined;
|
|
534
|
+
}
|
|
535
|
+
// For position, the bezier curve is in time-time domain
|
|
536
|
+
var bezierCurves = [];
|
|
537
|
+
for(var i = 0; i < points.length - 1; i++){
|
|
538
|
+
var current = points[i];
|
|
539
|
+
var next = points[i + 1];
|
|
540
|
+
var t0 = current.t;
|
|
541
|
+
var t1 = next.t;
|
|
542
|
+
var outCpX = lerp(t0, t1, current.outTangent.x);
|
|
543
|
+
var outCpY = lerp(t0, t1, current.outTangent.y);
|
|
544
|
+
// Per IR convention: incoming tangent for segment current→next sits on next.
|
|
545
|
+
var inCpX = lerp(t0, t1, next.inTangent.x);
|
|
546
|
+
var inCpY = lerp(t0, t1, next.inTangent.y);
|
|
547
|
+
bezierCurves.push([
|
|
548
|
+
t0,
|
|
549
|
+
t0,
|
|
550
|
+
outCpX,
|
|
551
|
+
outCpY,
|
|
552
|
+
inCpX,
|
|
553
|
+
inCpY,
|
|
554
|
+
t1,
|
|
555
|
+
t1
|
|
556
|
+
]);
|
|
557
|
+
}
|
|
558
|
+
if (bezierCurves.length === 0) {
|
|
559
|
+
return undefined;
|
|
560
|
+
}
|
|
561
|
+
var result = [];
|
|
562
|
+
var totalPoints = bezierCurves.length + 1;
|
|
563
|
+
for(var i1 = 0; i1 < totalPoints; i1++){
|
|
564
|
+
if (i1 === 0) {
|
|
565
|
+
result.push(makeEaseOut(bezierCurves[0]));
|
|
566
|
+
} else if (i1 === totalPoints - 1) {
|
|
567
|
+
result.push(makeEaseIn(bezierCurves[i1 - 1]));
|
|
568
|
+
} else {
|
|
569
|
+
result.push(makeEase(bezierCurves[i1 - 1], bezierCurves[i1]));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
return result;
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Determine if a property has enough keyframes to warrant keyframe mode (pkf/skf/rkf/okf).
|
|
576
|
+
*/ function shouldUseKeyframeMode(property) {
|
|
577
|
+
return property.keyframed === true && property.keyframes != null && property.keyframes.length > 12;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* True when the layer's parent only inherits transform — visibility and
|
|
582
|
+
* lifetime are independent of the parent's window.
|
|
583
|
+
*
|
|
584
|
+
* Reads `IRLayerReference.linkKind` directly. Producers that don't set the
|
|
585
|
+
* field (e.g. dsl2ge) effectively get `false` here, which is the correct
|
|
586
|
+
* default for "full" parent containment.
|
|
587
|
+
*
|
|
588
|
+
* Lottie's parser sets `linkKind: 'transform-only'` when a child's parent
|
|
589
|
+
* relationship comes from `layer.parent` rather than precomp expansion;
|
|
590
|
+
* `applyPostProcess` consumes this to decide whether to advance the parent's
|
|
591
|
+
* activation track when the child starts earlier.
|
|
592
|
+
*/ function isTransformOnlyParentLink(layer) {
|
|
593
|
+
var _layer_parent;
|
|
594
|
+
return ((_layer_parent = layer.parent) == null ? void 0 : _layer_parent.linkKind) === 'transform-only';
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Map an IR layer's time range to GE delay/duration in seconds, applying
|
|
599
|
+
* the time-stretch and offset semantics from `IRTimeContext`.
|
|
600
|
+
*
|
|
601
|
+
* dsl-source IRs leave `stretch` and `offsetFrame` undefined, in which case
|
|
602
|
+
* this collapses to `delay = startFrame / fr` and
|
|
603
|
+
* `duration = (endFrame - startFrame) / fr` — exactly what dsl2ge used to
|
|
604
|
+
* compute inline.
|
|
605
|
+
*
|
|
606
|
+
* Zero/negative durations are clamped to a 0.0001 epsilon so GE keeps the
|
|
607
|
+
* activation track alive for the (degenerate) layer.
|
|
608
|
+
*/ function computeLayerTiming(layer, frameRate) {
|
|
609
|
+
var _time_stretch, _time_offsetFrame;
|
|
610
|
+
var time = layer.time;
|
|
611
|
+
var stretch = (_time_stretch = time.stretch) != null ? _time_stretch : 1;
|
|
612
|
+
var offsetFrame = (_time_offsetFrame = time.offsetFrame) != null ? _time_offsetFrame : 0;
|
|
613
|
+
var delay = roundNumber((offsetFrame + time.startFrame * stretch) / frameRate, 4);
|
|
614
|
+
var rawDuration = (time.endFrame - time.startFrame) * stretch / frameRate;
|
|
615
|
+
var layerDuration = rawDuration > 0 ? roundNumber(rawDuration, 4) : 0.0001;
|
|
616
|
+
return {
|
|
617
|
+
delay: delay,
|
|
618
|
+
layerDuration: layerDuration
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
function computeStaticPosition(layer, ctx, anchorOffsetX, anchorOffsetY) {
|
|
623
|
+
if (anchorOffsetX === void 0) anchorOffsetX = 0;
|
|
624
|
+
if (anchorOffsetY === void 0) anchorOffsetY = 0;
|
|
625
|
+
var _transform_position;
|
|
626
|
+
var transform = layer.transform;
|
|
627
|
+
if (transform == null ? void 0 : (_transform_position = transform.position) == null ? void 0 : _transform_position.keyframed) {
|
|
628
|
+
return convert2dTo3dPoint(ctx.width / 2 + anchorOffsetX, ctx.height / 2 + anchorOffsetY, 0, ctx.width, ctx.height);
|
|
629
|
+
}
|
|
630
|
+
var isNullType = layer.type === 'null' || layer.type === 'precomp';
|
|
631
|
+
if ((transform == null ? void 0 : transform.position) != null && Array.isArray(transform.position.value)) {
|
|
632
|
+
var _pos_, _pos_1, _pos_2;
|
|
633
|
+
var pos = transform.position.value;
|
|
634
|
+
return convert2dTo3dPoint(((_pos_ = pos[0]) != null ? _pos_ : 0) + anchorOffsetX, ((_pos_1 = pos[1]) != null ? _pos_1 : 0) + anchorOffsetY, isNullType ? 0 : (_pos_2 = pos[2]) != null ? _pos_2 : 0, ctx.width, ctx.height);
|
|
635
|
+
}
|
|
636
|
+
return convert2dTo3dPoint(ctx.width / 2 + anchorOffsetX, ctx.height / 2 + anchorOffsetY, 0, ctx.width, ctx.height);
|
|
637
|
+
}
|
|
638
|
+
function getStaticAnchor(layer) {
|
|
639
|
+
var _layer_transform;
|
|
640
|
+
var anchor = (_layer_transform = layer.transform) == null ? void 0 : _layer_transform.anchor;
|
|
641
|
+
if (anchor != null && !anchor.keyframed && Array.isArray(anchor.value) && anchor.value.length >= 2) {
|
|
642
|
+
return [
|
|
643
|
+
anchor.value[0],
|
|
644
|
+
anchor.value[1]
|
|
645
|
+
];
|
|
646
|
+
}
|
|
647
|
+
if ((anchor == null ? void 0 : anchor.keyframed) && anchor.keyframes != null && anchor.keyframes.length > 0) {
|
|
648
|
+
var firstVal = anchor.keyframes[0].value;
|
|
649
|
+
if (Array.isArray(firstVal) && firstVal.length >= 2) {
|
|
650
|
+
return [
|
|
651
|
+
firstVal[0],
|
|
652
|
+
firstVal[1]
|
|
653
|
+
];
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
return [
|
|
657
|
+
0,
|
|
658
|
+
0
|
|
659
|
+
];
|
|
660
|
+
}
|
|
661
|
+
function getStaticScaleFromIR(layer) {
|
|
662
|
+
var _value_, _value_1;
|
|
663
|
+
var _layer_transform;
|
|
664
|
+
var scale = (_layer_transform = layer.transform) == null ? void 0 : _layer_transform.scale;
|
|
665
|
+
if (scale == null || scale.keyframed) {
|
|
666
|
+
return [
|
|
667
|
+
1,
|
|
668
|
+
1
|
|
669
|
+
];
|
|
670
|
+
}
|
|
671
|
+
var value = scale.value;
|
|
672
|
+
if (!Array.isArray(value)) {
|
|
673
|
+
return [
|
|
674
|
+
1,
|
|
675
|
+
1
|
|
676
|
+
];
|
|
677
|
+
}
|
|
678
|
+
return [
|
|
679
|
+
(_value_ = value[0]) != null ? _value_ : 1,
|
|
680
|
+
(_value_1 = value[1]) != null ? _value_1 : 1
|
|
681
|
+
];
|
|
682
|
+
}
|
|
683
|
+
function applyScalePositionAdjust(position, layer, layerWidth, layerHeight, ratio) {
|
|
684
|
+
var staticScale = getStaticScaleFromIR(layer);
|
|
685
|
+
if (staticScale[0] === 1 && staticScale[1] === 1 || layerWidth <= 0 || layerHeight <= 0) {
|
|
686
|
+
return position;
|
|
687
|
+
}
|
|
688
|
+
var anchor = getStaticAnchor(layer);
|
|
689
|
+
var anchorDiffX = anchor[0] - layerWidth / 2;
|
|
690
|
+
var anchorDiffY = anchor[1] - layerHeight / 2;
|
|
691
|
+
if (Math.abs(anchorDiffX) <= 0.5 && Math.abs(anchorDiffY) <= 0.5) {
|
|
692
|
+
return position;
|
|
693
|
+
}
|
|
694
|
+
return [
|
|
695
|
+
position[0] + anchorDiffX * (1 - staticScale[0]) * ratio,
|
|
696
|
+
position[1] - anchorDiffY * (1 - staticScale[1]) * ratio,
|
|
697
|
+
position[2]
|
|
698
|
+
];
|
|
699
|
+
}
|
|
700
|
+
function computeAnchorInfo(layer, layerWidth, layerHeight) {
|
|
701
|
+
var anchor = getStaticAnchor(layer);
|
|
702
|
+
var anchorScaleX = 0.5;
|
|
703
|
+
var anchorScaleY = 0.5;
|
|
704
|
+
var anchorOffsetX = 0;
|
|
705
|
+
var anchorOffsetY = 0;
|
|
706
|
+
if (layerWidth > 0 && layerHeight > 0) {
|
|
707
|
+
anchorScaleX = anchor[0] / layerWidth;
|
|
708
|
+
anchorScaleY = anchor[1] / layerHeight;
|
|
709
|
+
anchorOffsetX = -(anchor[0] - layerWidth / 2);
|
|
710
|
+
anchorOffsetY = -(anchor[1] - layerHeight / 2);
|
|
711
|
+
}
|
|
712
|
+
if (layer.type === 'text' && layer.text != null && layerWidth > 0 && layerHeight > 0) {
|
|
713
|
+
if (layer.text.anchorAdjust === true) {
|
|
714
|
+
if (layer.text.textAlign === 'left') {
|
|
715
|
+
anchorOffsetX = -(anchor[0] - layerWidth / 2);
|
|
716
|
+
anchorScaleX = anchor[0] / layerWidth - 0.5;
|
|
717
|
+
}
|
|
718
|
+
if (layer.text.textAlign === 'center') {
|
|
719
|
+
anchorOffsetX = -anchor[0];
|
|
720
|
+
anchorScaleX = anchor[0] / layerWidth + 0.5;
|
|
721
|
+
}
|
|
722
|
+
if (layer.text.textAlign === 'right') {
|
|
723
|
+
anchorOffsetX = -(anchor[0] + layerWidth / 2);
|
|
724
|
+
anchorScaleX = anchor[0] / layerWidth + 1.5;
|
|
725
|
+
}
|
|
726
|
+
// GE renders glyphs in the lower half of the quad, so offset by half the
|
|
727
|
+
// layer height to align the visible text center with Lottie's anchor.
|
|
728
|
+
var textHeight = layerHeight / 2;
|
|
729
|
+
anchorOffsetY = -(anchor[1] + textHeight);
|
|
730
|
+
anchorScaleY = -anchor[1] / textHeight;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
var isSpriteForAnchor = layer.type === 'image' || layer.type === 'solid';
|
|
734
|
+
var staticRotationZ = getStaticRotationZ(layer);
|
|
735
|
+
var hasStaticRotation = staticRotationZ != null;
|
|
736
|
+
if (isSpriteForAnchor && hasStaticRotation && isTransformOnlyParentLink(layer) && (anchorOffsetX !== 0 || anchorOffsetY !== 0)) {
|
|
737
|
+
var rotValue = staticRotationZ != null ? staticRotationZ : 0;
|
|
738
|
+
if (rotValue !== 0) {
|
|
739
|
+
var rad = rotValue * Math.PI / 180;
|
|
740
|
+
var cosR = Math.cos(rad);
|
|
741
|
+
var sinR = Math.sin(rad);
|
|
742
|
+
var rotatedX = anchorOffsetX * cosR - anchorOffsetY * sinR;
|
|
743
|
+
var rotatedY = anchorOffsetX * sinR + anchorOffsetY * cosR;
|
|
744
|
+
anchorOffsetX = rotatedX;
|
|
745
|
+
anchorOffsetY = rotatedY;
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
anchorScaleX: anchorScaleX,
|
|
750
|
+
anchorScaleY: anchorScaleY,
|
|
751
|
+
anchorOffsetX: anchorOffsetX,
|
|
752
|
+
anchorOffsetY: anchorOffsetY
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
function getStaticRotationZ(layer) {
|
|
756
|
+
var _layer_transform, _layer_transform_separatedRotation, _layer_transform1;
|
|
757
|
+
var rotation = (_layer_transform = layer.transform) == null ? void 0 : _layer_transform.rotation;
|
|
758
|
+
if (rotation != null && !rotation.keyframed && Array.isArray(rotation.value)) {
|
|
759
|
+
var _rotation_value_;
|
|
760
|
+
return (_rotation_value_ = rotation.value[2]) != null ? _rotation_value_ : 0;
|
|
761
|
+
}
|
|
762
|
+
var separatedRotationZ = (_layer_transform1 = layer.transform) == null ? void 0 : (_layer_transform_separatedRotation = _layer_transform1.separatedRotation) == null ? void 0 : _layer_transform_separatedRotation.z;
|
|
763
|
+
if (separatedRotationZ != null && !separatedRotationZ.keyframed && typeof separatedRotationZ.value === 'number') {
|
|
764
|
+
return separatedRotationZ.value;
|
|
765
|
+
}
|
|
766
|
+
return undefined;
|
|
767
|
+
}
|
|
768
|
+
function getTimeContext(layer) {
|
|
769
|
+
return {
|
|
770
|
+
startFrame: layer.time.startFrame,
|
|
771
|
+
endFrame: layer.time.endFrame
|
|
772
|
+
};
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
function _type_of(obj) {
|
|
776
|
+
"@swc/helpers - typeof";
|
|
777
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
function readGE2IRMetadata(ir, layer) {
|
|
781
|
+
if (ir.source !== 'ge') {
|
|
782
|
+
return undefined;
|
|
783
|
+
}
|
|
784
|
+
var metadata = layer.metadata;
|
|
785
|
+
if (metadata == null) {
|
|
786
|
+
return undefined;
|
|
787
|
+
}
|
|
788
|
+
var namespaced = metadata['ge2ir'];
|
|
789
|
+
if (isRecord$1(namespaced)) {
|
|
790
|
+
return namespaced;
|
|
791
|
+
}
|
|
792
|
+
var legacy = readLegacyGE2IRMetadata(metadata);
|
|
793
|
+
return Object.keys(legacy).length > 0 ? legacy : undefined;
|
|
794
|
+
}
|
|
795
|
+
function readLegacyGE2IRMetadata(metadata) {
|
|
796
|
+
var legacy = {};
|
|
797
|
+
var positionOverLifetime = metadata['positionOverLifetime'];
|
|
798
|
+
var rotationOverLifetime = metadata['rotationOverLifetime'];
|
|
799
|
+
var sizeOverLifetime = metadata['sizeOverLifetime'];
|
|
800
|
+
var colorOverLifetime = metadata['colorOverLifetime'];
|
|
801
|
+
var geComponentId = metadata['geComponentId'];
|
|
802
|
+
var geMask = metadata['geMask'];
|
|
803
|
+
if (isRecord$1(positionOverLifetime)) {
|
|
804
|
+
legacy.positionOverLifetime = positionOverLifetime;
|
|
805
|
+
}
|
|
806
|
+
if (isRecord$1(rotationOverLifetime)) {
|
|
807
|
+
legacy.rotationOverLifetime = rotationOverLifetime;
|
|
808
|
+
}
|
|
809
|
+
if (isRecord$1(sizeOverLifetime)) {
|
|
810
|
+
legacy.sizeOverLifetime = sizeOverLifetime;
|
|
811
|
+
}
|
|
812
|
+
if (isRecord$1(colorOverLifetime)) {
|
|
813
|
+
legacy.colorOverLifetime = colorOverLifetime;
|
|
814
|
+
}
|
|
815
|
+
if (typeof geComponentId === 'string') {
|
|
816
|
+
legacy.geComponentId = geComponentId;
|
|
817
|
+
}
|
|
818
|
+
if (isRecord$1(geMask)) {
|
|
819
|
+
legacy.geMask = geMask;
|
|
820
|
+
}
|
|
821
|
+
return legacy;
|
|
822
|
+
}
|
|
823
|
+
function isRecord$1(value) {
|
|
824
|
+
return value != null && (typeof value === "undefined" ? "undefined" : _type_of(value)) === 'object' && !Array.isArray(value);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
function buildTransformAnimation(layer, ctx) {
|
|
828
|
+
var transform = layer.transform;
|
|
829
|
+
if (transform == null) {
|
|
830
|
+
return {};
|
|
831
|
+
}
|
|
832
|
+
var timeContext = getTimeContext(layer);
|
|
833
|
+
// Passthrough: ge2ir stores raw animation data in metadata to bypass the
|
|
834
|
+
// IR keyframe conversion pipeline. Raw GE data is used verbatim when
|
|
835
|
+
// available; otherwise the standard IR → GE conversion runs.
|
|
836
|
+
var ge2irMetadata = readGE2IRMetadata(ctx.ir, layer);
|
|
837
|
+
var passthroughPosition = ge2irMetadata == null ? void 0 : ge2irMetadata.positionOverLifetime;
|
|
838
|
+
var passthroughRotation = ge2irMetadata == null ? void 0 : ge2irMetadata.rotationOverLifetime;
|
|
839
|
+
var passthroughSize = ge2irMetadata == null ? void 0 : ge2irMetadata.sizeOverLifetime;
|
|
840
|
+
var positionOverLifetime = passthroughPosition != null ? passthroughPosition : buildPositionAnim(transform, timeContext, ctx);
|
|
841
|
+
var rotationOverLifetime = passthroughRotation != null ? passthroughRotation : buildRotationAnim(transform, timeContext);
|
|
842
|
+
var sizeOverLifetime = passthroughSize != null ? passthroughSize : buildSizeAnim(transform, timeContext);
|
|
843
|
+
return {
|
|
844
|
+
positionOverLifetime: positionOverLifetime,
|
|
845
|
+
rotationOverLifetime: rotationOverLifetime,
|
|
846
|
+
sizeOverLifetime: sizeOverLifetime
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
function buildPositionAnim(transform, timeContext, ctx) {
|
|
850
|
+
var _posResult_curves_;
|
|
851
|
+
if (transform.position == null || !transform.position.keyframed) {
|
|
852
|
+
return undefined;
|
|
853
|
+
}
|
|
854
|
+
var posResult = irPositionKeyframesToGE(transform.position, timeContext);
|
|
855
|
+
if (posResult == null) {
|
|
856
|
+
return undefined;
|
|
857
|
+
}
|
|
858
|
+
var pathPoints = [];
|
|
859
|
+
var controlPoints = [];
|
|
860
|
+
var useKeyframeMode = shouldUseKeyframeMode(transform.position);
|
|
861
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(posResult.pathPoints), _step; !(_step = _iterator()).done;){
|
|
862
|
+
var pp = _step.value;
|
|
863
|
+
var point3d = convert2dTo3dPoint(pp[0][0], pp[0][1], 0, ctx.width, ctx.height);
|
|
864
|
+
pathPoints.push(point3d);
|
|
865
|
+
}
|
|
866
|
+
if (posResult.pathPoints.length > 0) {
|
|
867
|
+
var lastPp = posResult.pathPoints[posResult.pathPoints.length - 1];
|
|
868
|
+
var lastPoint3d = convert2dTo3dPoint(lastPp[1][0], lastPp[1][1], 0, ctx.width, ctx.height);
|
|
869
|
+
pathPoints.push(lastPoint3d);
|
|
870
|
+
}
|
|
871
|
+
for(var i = 0; i < posResult.controlPoints.length; i++){
|
|
872
|
+
var cp = posResult.controlPoints[i];
|
|
873
|
+
var pp1 = posResult.pathPoints[i];
|
|
874
|
+
if (useKeyframeMode) {
|
|
875
|
+
var dx = pp1[1][0] - pp1[0][0];
|
|
876
|
+
var dy = pp1[1][1] - pp1[0][1];
|
|
877
|
+
var cp1 = convert2dTo3dPoint(dx / 3 + pp1[0][0], dy / 3 + pp1[0][1], 0, ctx.width, ctx.height);
|
|
878
|
+
var cp2 = convert2dTo3dPoint(-dx / 3 + pp1[1][0], -dy / 3 + pp1[1][1], 0, ctx.width, ctx.height);
|
|
879
|
+
controlPoints.push(cp1, cp2);
|
|
880
|
+
} else {
|
|
881
|
+
var cp11 = convert2dTo3dPoint(cp[0][0] + pp1[0][0], cp[0][1] + pp1[0][1], 0, ctx.width, ctx.height);
|
|
882
|
+
var cp21 = convert2dTo3dPoint(cp[1][0] + pp1[1][0], cp[1][1] + pp1[1][1], 0, ctx.width, ctx.height);
|
|
883
|
+
controlPoints.push(cp11, cp21);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
var curveData = (_posResult_curves_ = posResult.curves[0]) != null ? _posResult_curves_ : [];
|
|
887
|
+
var easingData = curveData.map(function(kf) {
|
|
888
|
+
return [
|
|
889
|
+
kf[0],
|
|
890
|
+
kf[1]
|
|
891
|
+
];
|
|
892
|
+
});
|
|
893
|
+
var roundedPathPoints = pathPoints.map(function(p) {
|
|
894
|
+
return [
|
|
895
|
+
roundNumber(p[0], 4),
|
|
896
|
+
roundNumber(p[1], 4),
|
|
897
|
+
p[2]
|
|
898
|
+
];
|
|
899
|
+
});
|
|
900
|
+
var roundedControlPoints = controlPoints.map(function(p) {
|
|
901
|
+
return [
|
|
902
|
+
roundNumber(p[0], 4),
|
|
903
|
+
roundNumber(p[1], 4),
|
|
904
|
+
p[2]
|
|
905
|
+
];
|
|
906
|
+
});
|
|
907
|
+
var pathPayload = [
|
|
908
|
+
easingData,
|
|
909
|
+
roundedPathPoints
|
|
910
|
+
];
|
|
911
|
+
if (roundedControlPoints.length > 0) {
|
|
912
|
+
pathPayload.push(roundedControlPoints);
|
|
913
|
+
}
|
|
914
|
+
return {
|
|
915
|
+
path: [
|
|
916
|
+
ValueType.BEZIER_CURVE_PATH,
|
|
917
|
+
pathPayload
|
|
918
|
+
]
|
|
919
|
+
};
|
|
920
|
+
}
|
|
921
|
+
function buildRotationAnim(transform, timeContext) {
|
|
922
|
+
var result = {};
|
|
923
|
+
var hasZ = false;
|
|
924
|
+
var hasX = false;
|
|
925
|
+
var hasY = false;
|
|
926
|
+
var rotation = transform.rotation;
|
|
927
|
+
if (rotation != null) {
|
|
928
|
+
if (rotation.keyframed) {
|
|
929
|
+
var _curves_, _curves_1, _curves_2;
|
|
930
|
+
var curves = irVectorKeyframesToGE(rotation, timeContext);
|
|
931
|
+
if (curves != null && axisHasRotationValue(rotation, 0) && ((_curves_ = curves[0]) == null ? void 0 : _curves_.length)) {
|
|
932
|
+
result['x'] = [
|
|
933
|
+
ValueType.BEZIER_CURVE,
|
|
934
|
+
curves[0]
|
|
935
|
+
];
|
|
936
|
+
hasX = true;
|
|
937
|
+
}
|
|
938
|
+
if (curves != null && axisHasRotationValue(rotation, 1) && ((_curves_1 = curves[1]) == null ? void 0 : _curves_1.length)) {
|
|
939
|
+
result['y'] = [
|
|
940
|
+
ValueType.BEZIER_CURVE,
|
|
941
|
+
curves[1]
|
|
942
|
+
];
|
|
943
|
+
hasY = true;
|
|
944
|
+
}
|
|
945
|
+
if (curves != null && axisHasRotationValue(rotation, 2) && ((_curves_2 = curves[2]) == null ? void 0 : _curves_2.length)) {
|
|
946
|
+
result['z'] = [
|
|
947
|
+
ValueType.BEZIER_CURVE,
|
|
948
|
+
curves[2]
|
|
949
|
+
];
|
|
950
|
+
hasZ = true;
|
|
951
|
+
}
|
|
952
|
+
} else if (rotation.value != null) {
|
|
953
|
+
var _rotation_value = rotation.value, tmp = _rotation_value[0], x = tmp === void 0 ? 0 : tmp, tmp1 = _rotation_value[1], y = tmp1 === void 0 ? 0 : tmp1, tmp2 = _rotation_value[2], z = tmp2 === void 0 ? 0 : tmp2;
|
|
954
|
+
if (Math.abs(x) > 0.0001) {
|
|
955
|
+
result['x'] = [
|
|
956
|
+
ValueType.CONSTANT,
|
|
957
|
+
x
|
|
958
|
+
];
|
|
959
|
+
hasX = true;
|
|
960
|
+
}
|
|
961
|
+
if (Math.abs(y) > 0.0001) {
|
|
962
|
+
result['y'] = [
|
|
963
|
+
ValueType.CONSTANT,
|
|
964
|
+
y
|
|
965
|
+
];
|
|
966
|
+
hasY = true;
|
|
967
|
+
}
|
|
968
|
+
if (Math.abs(z) > 0.0001) {
|
|
969
|
+
result['z'] = [
|
|
970
|
+
ValueType.CONSTANT,
|
|
971
|
+
z
|
|
972
|
+
];
|
|
973
|
+
hasZ = true;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
} else {
|
|
977
|
+
var _separated_x, _separated_x1, _separated_y, _separated_y1, _separated_z, _separated_z1;
|
|
978
|
+
var separated = transform.separatedRotation;
|
|
979
|
+
if (separated == null ? void 0 : (_separated_x = separated.x) == null ? void 0 : _separated_x.keyframed) {
|
|
980
|
+
var curves1 = irScalarKeyframesToGE(separated.x, timeContext);
|
|
981
|
+
if (curves1 != null) {
|
|
982
|
+
result['x'] = [
|
|
983
|
+
ValueType.BEZIER_CURVE,
|
|
984
|
+
curves1[0]
|
|
985
|
+
];
|
|
986
|
+
hasX = true;
|
|
987
|
+
}
|
|
988
|
+
} else if ((separated == null ? void 0 : (_separated_x1 = separated.x) == null ? void 0 : _separated_x1.value) != null && separated.x.value !== 0) {
|
|
989
|
+
result['x'] = [
|
|
990
|
+
ValueType.CONSTANT,
|
|
991
|
+
separated.x.value
|
|
992
|
+
];
|
|
993
|
+
hasX = true;
|
|
994
|
+
}
|
|
995
|
+
if (separated == null ? void 0 : (_separated_y = separated.y) == null ? void 0 : _separated_y.keyframed) {
|
|
996
|
+
var curves2 = irScalarKeyframesToGE(separated.y, timeContext);
|
|
997
|
+
if (curves2 != null) {
|
|
998
|
+
result['y'] = [
|
|
999
|
+
ValueType.BEZIER_CURVE,
|
|
1000
|
+
curves2[0]
|
|
1001
|
+
];
|
|
1002
|
+
hasY = true;
|
|
1003
|
+
}
|
|
1004
|
+
} else if ((separated == null ? void 0 : (_separated_y1 = separated.y) == null ? void 0 : _separated_y1.value) != null && separated.y.value !== 0) {
|
|
1005
|
+
result['y'] = [
|
|
1006
|
+
ValueType.CONSTANT,
|
|
1007
|
+
separated.y.value
|
|
1008
|
+
];
|
|
1009
|
+
hasY = true;
|
|
1010
|
+
}
|
|
1011
|
+
if (separated == null ? void 0 : (_separated_z = separated.z) == null ? void 0 : _separated_z.keyframed) {
|
|
1012
|
+
var curves3 = irScalarKeyframesToGE(separated.z, timeContext);
|
|
1013
|
+
if (curves3 != null) {
|
|
1014
|
+
result['z'] = [
|
|
1015
|
+
ValueType.BEZIER_CURVE,
|
|
1016
|
+
curves3[0]
|
|
1017
|
+
];
|
|
1018
|
+
hasZ = true;
|
|
1019
|
+
}
|
|
1020
|
+
} else if ((separated == null ? void 0 : (_separated_z1 = separated.z) == null ? void 0 : _separated_z1.value) != null && separated.z.value !== 0) {
|
|
1021
|
+
result['z'] = [
|
|
1022
|
+
ValueType.CONSTANT,
|
|
1023
|
+
separated.z.value
|
|
1024
|
+
];
|
|
1025
|
+
hasZ = true;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
if (!hasZ && !hasX && !hasY) {
|
|
1029
|
+
return undefined;
|
|
1030
|
+
}
|
|
1031
|
+
result['asRotation'] = true;
|
|
1032
|
+
var axisCount = (hasX ? 1 : 0) + (hasY ? 1 : 0) + (hasZ ? 1 : 0);
|
|
1033
|
+
if (axisCount > 1 || hasX || hasY) {
|
|
1034
|
+
result['separateAxes'] = true;
|
|
1035
|
+
}
|
|
1036
|
+
return result;
|
|
1037
|
+
}
|
|
1038
|
+
function axisHasRotationValue(rotation, axis) {
|
|
1039
|
+
var _ref;
|
|
1040
|
+
var _rotation_keyframes;
|
|
1041
|
+
if (!rotation.keyframed) {
|
|
1042
|
+
var _ref1;
|
|
1043
|
+
var _rotation_value;
|
|
1044
|
+
return Math.abs((_ref1 = (_rotation_value = rotation.value) == null ? void 0 : _rotation_value[axis]) != null ? _ref1 : 0) > 0.0001;
|
|
1045
|
+
}
|
|
1046
|
+
return (_ref = (_rotation_keyframes = rotation.keyframes) == null ? void 0 : _rotation_keyframes.some(function(keyframe) {
|
|
1047
|
+
var _keyframe_value_axis, _ref;
|
|
1048
|
+
var _keyframe_endValue;
|
|
1049
|
+
return Math.abs((_keyframe_value_axis = keyframe.value[axis]) != null ? _keyframe_value_axis : 0) > 0.0001 || Math.abs((_ref = (_keyframe_endValue = keyframe.endValue) == null ? void 0 : _keyframe_endValue[axis]) != null ? _ref : 0) > 0.0001;
|
|
1050
|
+
})) != null ? _ref : false;
|
|
1051
|
+
}
|
|
1052
|
+
function buildSizeAnim(transform, timeContext) {
|
|
1053
|
+
if (transform.scale == null) {
|
|
1054
|
+
return undefined;
|
|
1055
|
+
}
|
|
1056
|
+
if (transform.scale.keyframed) {
|
|
1057
|
+
var curves = irVectorKeyframesToGE(transform.scale, timeContext);
|
|
1058
|
+
if (curves != null && curves.length >= 2) {
|
|
1059
|
+
return _extends({
|
|
1060
|
+
separateAxes: true,
|
|
1061
|
+
x: [
|
|
1062
|
+
ValueType.BEZIER_CURVE,
|
|
1063
|
+
curves[0]
|
|
1064
|
+
],
|
|
1065
|
+
y: [
|
|
1066
|
+
ValueType.BEZIER_CURVE,
|
|
1067
|
+
curves[1]
|
|
1068
|
+
]
|
|
1069
|
+
}, curves.length >= 3 && {
|
|
1070
|
+
z: [
|
|
1071
|
+
ValueType.BEZIER_CURVE,
|
|
1072
|
+
curves[2]
|
|
1073
|
+
]
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1076
|
+
return undefined;
|
|
1077
|
+
}
|
|
1078
|
+
var scale = transform.scale.value;
|
|
1079
|
+
if (Array.isArray(scale) && (Math.abs(scale[0] - 1) > 0.0001 || Math.abs(scale[1] - 1) > 0.0001)) {
|
|
1080
|
+
var _scale_;
|
|
1081
|
+
return {
|
|
1082
|
+
separateAxes: true,
|
|
1083
|
+
x: [
|
|
1084
|
+
ValueType.CONSTANT,
|
|
1085
|
+
scale[0]
|
|
1086
|
+
],
|
|
1087
|
+
y: [
|
|
1088
|
+
ValueType.CONSTANT,
|
|
1089
|
+
scale[1]
|
|
1090
|
+
],
|
|
1091
|
+
z: [
|
|
1092
|
+
ValueType.CONSTANT,
|
|
1093
|
+
(_scale_ = scale[2]) != null ? _scale_ : 1
|
|
1094
|
+
]
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
return undefined;
|
|
1098
|
+
}
|
|
1099
|
+
function buildColorAnimation(layer, ir) {
|
|
1100
|
+
var _readGE2IRMetadata;
|
|
1101
|
+
var passthroughColor = (_readGE2IRMetadata = readGE2IRMetadata(ir, layer)) == null ? void 0 : _readGE2IRMetadata.colorOverLifetime;
|
|
1102
|
+
if (passthroughColor != null) {
|
|
1103
|
+
return passthroughColor;
|
|
1104
|
+
}
|
|
1105
|
+
var transform = layer.transform;
|
|
1106
|
+
if ((transform == null ? void 0 : transform.opacity) == null) {
|
|
1107
|
+
return undefined;
|
|
1108
|
+
}
|
|
1109
|
+
var timeContext = getTimeContext(layer);
|
|
1110
|
+
if (timeContext.endFrame - timeContext.startFrame <= 0) {
|
|
1111
|
+
return {
|
|
1112
|
+
opacity: [
|
|
1113
|
+
ValueType.CONSTANT,
|
|
1114
|
+
0
|
|
1115
|
+
]
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
1118
|
+
if (transform.opacity.keyframed) {
|
|
1119
|
+
var curves = irScalarKeyframesToGE(transform.opacity, timeContext);
|
|
1120
|
+
if (curves != null) {
|
|
1121
|
+
return {
|
|
1122
|
+
opacity: [
|
|
1123
|
+
ValueType.BEZIER_CURVE,
|
|
1124
|
+
curves[0]
|
|
1125
|
+
]
|
|
1126
|
+
};
|
|
1127
|
+
}
|
|
1128
|
+
return undefined;
|
|
1129
|
+
}
|
|
1130
|
+
var opacityValue = transform.opacity.value;
|
|
1131
|
+
if (typeof opacityValue === 'number' && opacityValue !== 1) {
|
|
1132
|
+
return {
|
|
1133
|
+
opacity: [
|
|
1134
|
+
ValueType.CONSTANT,
|
|
1135
|
+
opacityValue
|
|
1136
|
+
]
|
|
1137
|
+
};
|
|
1138
|
+
}
|
|
1139
|
+
return undefined;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
function buildGETransform(position, eulerHint, scale) {
|
|
1143
|
+
return {
|
|
1144
|
+
position: {
|
|
1145
|
+
x: position[0],
|
|
1146
|
+
y: position[1],
|
|
1147
|
+
z: position[2]
|
|
1148
|
+
},
|
|
1149
|
+
eulerHint: {
|
|
1150
|
+
x: eulerHint[0],
|
|
1151
|
+
y: eulerHint[1],
|
|
1152
|
+
z: eulerHint[2]
|
|
1153
|
+
},
|
|
1154
|
+
scale: {
|
|
1155
|
+
x: scale[0],
|
|
1156
|
+
y: scale[1],
|
|
1157
|
+
z: scale[2]
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
function getGEItemType(type) {
|
|
1162
|
+
switch(type){
|
|
1163
|
+
case 'image':
|
|
1164
|
+
case 'solid':
|
|
1165
|
+
return 'sprite';
|
|
1166
|
+
case 'text':
|
|
1167
|
+
return 'text';
|
|
1168
|
+
case 'shape':
|
|
1169
|
+
return 'sprite';
|
|
1170
|
+
default:
|
|
1171
|
+
return 'null';
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
function getGEItemTypeCode(type) {
|
|
1175
|
+
switch(type){
|
|
1176
|
+
case 'image':
|
|
1177
|
+
case 'solid':
|
|
1178
|
+
return '1';
|
|
1179
|
+
case 'text':
|
|
1180
|
+
return 'text';
|
|
1181
|
+
case 'shape':
|
|
1182
|
+
return 'shape';
|
|
1183
|
+
default:
|
|
1184
|
+
return '3';
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
function registerTexture(collector, imageUrl, cache) {
|
|
1188
|
+
var cached = cache.get(imageUrl);
|
|
1189
|
+
if (cached != null) {
|
|
1190
|
+
return cached;
|
|
1191
|
+
}
|
|
1192
|
+
var imageId = createId();
|
|
1193
|
+
var textureId = createId();
|
|
1194
|
+
collector.images.push({
|
|
1195
|
+
id: imageId,
|
|
1196
|
+
url: imageUrl
|
|
1197
|
+
});
|
|
1198
|
+
collector.textures.push({
|
|
1199
|
+
id: textureId,
|
|
1200
|
+
dataType: 'Texture',
|
|
1201
|
+
source: toDataPath(imageId),
|
|
1202
|
+
flipY: true
|
|
1203
|
+
});
|
|
1204
|
+
var dataPathRef = toDataPath(textureId);
|
|
1205
|
+
cache.set(imageUrl, dataPathRef);
|
|
1206
|
+
return dataPathRef;
|
|
1207
|
+
}
|
|
1208
|
+
var _obj$1;
|
|
1209
|
+
var GE_BLENDING_BY_IR_MODE = (_obj$1 = {}, _obj$1[IRBlendMode.Normal] = undefined, _obj$1[IRBlendMode.Multiply] = 6, _obj$1[IRBlendMode.Screen] = 9, _obj$1[IRBlendMode.Overlay] = 13, _obj$1[IRBlendMode.Darken] = 2, _obj$1[IRBlendMode.Lighten] = 3, _obj$1[IRBlendMode.ColorDodge] = 10, _obj$1[IRBlendMode.ColorBurn] = 7, _obj$1[IRBlendMode.HardLight] = 14, _obj$1[IRBlendMode.SoftLight] = 15, _obj$1[IRBlendMode.Difference] = 4, _obj$1[IRBlendMode.Exclusion] = 5, _obj$1[IRBlendMode.Hue] = 11, _obj$1[IRBlendMode.Saturation] = 12, _obj$1[IRBlendMode.Color] = 8, _obj$1[IRBlendMode.Luminosity] = 16, _obj$1[IRBlendMode.Add] = 1, _obj$1);
|
|
1210
|
+
function mapBlendingMode(blendMode) {
|
|
1211
|
+
if (blendMode == null) {
|
|
1212
|
+
return undefined;
|
|
1213
|
+
}
|
|
1214
|
+
return GE_BLENDING_BY_IR_MODE[blendMode];
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
var DEFAULT_DISPLAY_SIZE = {
|
|
1218
|
+
width: 1,
|
|
1219
|
+
height: 1
|
|
1220
|
+
};
|
|
1221
|
+
/**
|
|
1222
|
+
* Read the producer-baked display size from an IR layer. When the producer
|
|
1223
|
+
* did not resolve one, returns `fallback` (defaults to `{ 1, 1 }` — the
|
|
1224
|
+
* value every existing call site was using inline).
|
|
1225
|
+
*/ function getLayerDisplaySize(layer, fallback) {
|
|
1226
|
+
if (fallback === void 0) fallback = DEFAULT_DISPLAY_SIZE;
|
|
1227
|
+
var _layer_displaySize;
|
|
1228
|
+
return (_layer_displaySize = layer.displaySize) != null ? _layer_displaySize : fallback;
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
function buildComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx) {
|
|
1232
|
+
switch(layer.type){
|
|
1233
|
+
case 'image':
|
|
1234
|
+
case 'solid':
|
|
1235
|
+
return buildSpriteComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx);
|
|
1236
|
+
case 'text':
|
|
1237
|
+
return buildTextComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx);
|
|
1238
|
+
case 'shape':
|
|
1239
|
+
return buildShapeComponent(layer, itemId, ctx);
|
|
1240
|
+
default:
|
|
1241
|
+
return undefined;
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* Copy the raw GE mask object (from ge2ir passthrough metadata) onto a freshly
|
|
1246
|
+
* built component, as a top-level `mask` field matching GE's structure. For a
|
|
1247
|
+
* mask SOURCE this carries `{isMask:true, alphaMaskEnabled}`; for a TARGET it
|
|
1248
|
+
* carries `{isMask:false, reference, inverted}` where `reference.id` is still
|
|
1249
|
+
* the stale GE1 component id — `applyGeMaskRemap` rewrites it in post-process.
|
|
1250
|
+
* No-op for non-ge sources (Lottie masks go through the IRLayerNode.mask path).
|
|
1251
|
+
*/ function applyGeMask(ir, layer, component) {
|
|
1252
|
+
var _readGE2IRMetadata;
|
|
1253
|
+
var geMask = (_readGE2IRMetadata = readGE2IRMetadata(ir, layer)) == null ? void 0 : _readGE2IRMetadata.geMask;
|
|
1254
|
+
if (geMask != null && component['mask'] == null) {
|
|
1255
|
+
component['mask'] = _extends({}, geMask);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
function buildSpriteComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx) {
|
|
1259
|
+
var _ref;
|
|
1260
|
+
var _layer_asset, _layer_asset1;
|
|
1261
|
+
var componentId = createId();
|
|
1262
|
+
var blending = mapBlendingMode(layer.blendMode);
|
|
1263
|
+
var startColor = layer.solidColor != null ? [
|
|
1264
|
+
roundNumber(layer.solidColor[0], 4),
|
|
1265
|
+
roundNumber(layer.solidColor[1], 4),
|
|
1266
|
+
roundNumber(layer.solidColor[2], 4),
|
|
1267
|
+
roundNumber(layer.solidColor[3], 4)
|
|
1268
|
+
] : [
|
|
1269
|
+
1,
|
|
1270
|
+
1,
|
|
1271
|
+
1,
|
|
1272
|
+
1
|
|
1273
|
+
];
|
|
1274
|
+
var textureDataPath;
|
|
1275
|
+
var textureUrl = (_ref = (_layer_asset = layer.asset) == null ? void 0 : _layer_asset.url) != null ? _ref : (_layer_asset1 = layer.asset) == null ? void 0 : _layer_asset1.refId;
|
|
1276
|
+
if (textureUrl != null && textureUrl !== '' && textureUrl !== 'mask://placeholder') {
|
|
1277
|
+
textureDataPath = registerTexture(ctx.collector, textureUrl, ctx.textureCache);
|
|
1278
|
+
}
|
|
1279
|
+
var component = {
|
|
1280
|
+
id: componentId,
|
|
1281
|
+
dataType: 'SpriteComponent',
|
|
1282
|
+
item: toDataPath(itemId),
|
|
1283
|
+
options: {
|
|
1284
|
+
startColor: startColor
|
|
1285
|
+
},
|
|
1286
|
+
renderer: _extends({
|
|
1287
|
+
renderMode: 1
|
|
1288
|
+
}, blending !== undefined && {
|
|
1289
|
+
blending: blending
|
|
1290
|
+
}, textureDataPath != null && {
|
|
1291
|
+
texture: textureDataPath
|
|
1292
|
+
})
|
|
1293
|
+
};
|
|
1294
|
+
var isNonDefaultAnchor = Math.abs(anchorScaleX - 0.5) > 0.001 || Math.abs(anchorScaleY - 0.5) > 0.001;
|
|
1295
|
+
if (isNonDefaultAnchor) {
|
|
1296
|
+
component['renderer']['anchor'] = [
|
|
1297
|
+
roundNumber(anchorScaleX, 4),
|
|
1298
|
+
roundNumber(anchorScaleY, 4)
|
|
1299
|
+
];
|
|
1300
|
+
}
|
|
1301
|
+
applyGeMask(ctx.ir, layer, component);
|
|
1302
|
+
ctx.collector.components.push(component);
|
|
1303
|
+
return componentId;
|
|
1304
|
+
}
|
|
1305
|
+
function buildTextComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx) {
|
|
1306
|
+
var _textInfo_width, _textInfo_height;
|
|
1307
|
+
var textInfo = layer.text;
|
|
1308
|
+
if (textInfo == null) {
|
|
1309
|
+
return undefined;
|
|
1310
|
+
}
|
|
1311
|
+
var componentId = createId();
|
|
1312
|
+
var blending = mapBlendingMode(layer.blendMode);
|
|
1313
|
+
var textColor = [
|
|
1314
|
+
roundNumber(textInfo.color[0], 4),
|
|
1315
|
+
roundNumber(textInfo.color[1], 4),
|
|
1316
|
+
roundNumber(textInfo.color[2], 4),
|
|
1317
|
+
textInfo.color[3]
|
|
1318
|
+
];
|
|
1319
|
+
var textWidth = (_textInfo_width = textInfo.width) != null ? _textInfo_width : estimateTextWidth(textInfo.content, textInfo.fontSize, textInfo.letterSpacing);
|
|
1320
|
+
var lineHeight = typeof textInfo.lineHeight === 'number' && textInfo.lineHeight > 0 ? textInfo.lineHeight : textInfo.fontSize;
|
|
1321
|
+
var textHeight = Math.max((_textInfo_height = textInfo.height) != null ? _textInfo_height : textInfo.fontSize * 1.2, lineHeight);
|
|
1322
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), layerWidth = _getLayerDisplaySize.width, layerHeight = _getLayerDisplaySize.height;
|
|
1323
|
+
var textSizeW = roundNumber(ctx.ratio * layerWidth, 4);
|
|
1324
|
+
var textSizeH = roundNumber(ctx.ratio * layerHeight, 4);
|
|
1325
|
+
var component = {
|
|
1326
|
+
id: componentId,
|
|
1327
|
+
dataType: 'TextComponent',
|
|
1328
|
+
item: toDataPath(itemId),
|
|
1329
|
+
options: {
|
|
1330
|
+
text: textInfo.content,
|
|
1331
|
+
fontSize: textInfo.fontSize,
|
|
1332
|
+
textColor: textColor,
|
|
1333
|
+
fontFamily: textInfo.fontFamily || 'sans-serif',
|
|
1334
|
+
fontWeight: textInfo.fontWeight,
|
|
1335
|
+
textAlign: textInfo.textAlign === 'center' ? 1 : textInfo.textAlign === 'right' ? 2 : 0,
|
|
1336
|
+
fontStyle: textInfo.fontStyle,
|
|
1337
|
+
letterSpace: textInfo.letterSpacing,
|
|
1338
|
+
lineHeight: lineHeight,
|
|
1339
|
+
textWidth: textWidth,
|
|
1340
|
+
textHeight: textHeight,
|
|
1341
|
+
autoWidth: textInfo.autoWidth,
|
|
1342
|
+
size: [
|
|
1343
|
+
textSizeW,
|
|
1344
|
+
textSizeH
|
|
1345
|
+
]
|
|
1346
|
+
},
|
|
1347
|
+
renderer: _extends({
|
|
1348
|
+
renderMode: 1,
|
|
1349
|
+
anchor: [
|
|
1350
|
+
anchorScaleX,
|
|
1351
|
+
anchorScaleY
|
|
1352
|
+
]
|
|
1353
|
+
}, blending !== undefined && {
|
|
1354
|
+
blending: blending
|
|
1355
|
+
})
|
|
1356
|
+
};
|
|
1357
|
+
applyGeMask(ctx.ir, layer, component);
|
|
1358
|
+
ctx.collector.components.push(component);
|
|
1359
|
+
return componentId;
|
|
1360
|
+
}
|
|
1361
|
+
function buildShapeComponent(layer, itemId, ctx) {
|
|
1362
|
+
if (layer.shapes == null || layer.shapes.length === 0) {
|
|
1363
|
+
return undefined;
|
|
1364
|
+
}
|
|
1365
|
+
var shapeData = layer.shapes[0];
|
|
1366
|
+
var componentId = createId();
|
|
1367
|
+
var blending = mapBlendingMode(layer.blendMode);
|
|
1368
|
+
var component = _extends({
|
|
1369
|
+
id: componentId,
|
|
1370
|
+
dataType: 'ShapeComponent',
|
|
1371
|
+
item: toDataPath(itemId)
|
|
1372
|
+
}, buildShapeOptions(shapeData, ctx.ratio, ctx), {
|
|
1373
|
+
renderer: _extends({
|
|
1374
|
+
renderMode: 1
|
|
1375
|
+
}, blending !== undefined && {
|
|
1376
|
+
blending: blending
|
|
1377
|
+
})
|
|
1378
|
+
});
|
|
1379
|
+
applyGeMask(ctx.ir, layer, component);
|
|
1380
|
+
ctx.collector.components.push(component);
|
|
1381
|
+
return componentId;
|
|
1382
|
+
}
|
|
1383
|
+
function buildShapeOptions(shapeData, ratio, ctx) {
|
|
1384
|
+
var options = {
|
|
1385
|
+
type: mapShapePrimitiveType(shapeData.primitiveType)
|
|
1386
|
+
};
|
|
1387
|
+
if (shapeData.size != null) {
|
|
1388
|
+
options['xSize'] = roundNumber(shapeData.size[0] * ratio, 4);
|
|
1389
|
+
options['ySize'] = roundNumber(shapeData.size[1] * ratio, 4);
|
|
1390
|
+
}
|
|
1391
|
+
setScaledNumber(options, shapeData, 'xRadius', ratio);
|
|
1392
|
+
setScaledNumber(options, shapeData, 'yRadius', ratio);
|
|
1393
|
+
setScaledNumber(options, shapeData, 'width', ratio);
|
|
1394
|
+
setScaledNumber(options, shapeData, 'height', ratio);
|
|
1395
|
+
setScaledNumber(options, shapeData, 'innerRadius', ratio);
|
|
1396
|
+
setScaledNumber(options, shapeData, 'outerRadius', ratio);
|
|
1397
|
+
setScaledNumber(options, shapeData, 'radius', ratio);
|
|
1398
|
+
setRawNumber(options, shapeData, 'roundness');
|
|
1399
|
+
setRawNumber(options, shapeData, 'pointCount');
|
|
1400
|
+
setRawNumber(options, shapeData, 'innerRoundness');
|
|
1401
|
+
setRawNumber(options, shapeData, 'outerRoundness');
|
|
1402
|
+
if (shapeData.fills != null && shapeData.fills.length > 0) {
|
|
1403
|
+
options['fills'] = shapeData.fills.map(function(fill) {
|
|
1404
|
+
return mapShapePaint(fill, ratio, ctx);
|
|
1405
|
+
}).filter(function(fill) {
|
|
1406
|
+
return fill != null;
|
|
1407
|
+
});
|
|
1408
|
+
} else {
|
|
1409
|
+
options['fills'] = [];
|
|
1410
|
+
}
|
|
1411
|
+
if (shapeData.strokes != null && shapeData.strokes.length > 0) {
|
|
1412
|
+
options['strokes'] = shapeData.strokes.map(function(stroke) {
|
|
1413
|
+
return mapShapePaint(stroke, ratio, ctx);
|
|
1414
|
+
}).filter(function(stroke) {
|
|
1415
|
+
return stroke != null;
|
|
1416
|
+
});
|
|
1417
|
+
} else {
|
|
1418
|
+
options['strokes'] = [];
|
|
1419
|
+
}
|
|
1420
|
+
if (typeof shapeData.strokeWidth === 'number') {
|
|
1421
|
+
options['strokeWidth'] = roundNumber(shapeData.strokeWidth * ratio, 4);
|
|
1422
|
+
}
|
|
1423
|
+
if (shapeData.strokeCap != null) {
|
|
1424
|
+
options['strokeCap'] = mapLineCap(shapeData.strokeCap);
|
|
1425
|
+
}
|
|
1426
|
+
if (shapeData.strokeJoin != null) {
|
|
1427
|
+
options['strokeJoin'] = mapLineJoin(shapeData.strokeJoin);
|
|
1428
|
+
}
|
|
1429
|
+
if (shapeData.fillRule != null) {
|
|
1430
|
+
options['fillRule'] = mapShapeFillRule(shapeData.fillRule);
|
|
1431
|
+
}
|
|
1432
|
+
if (shapeData.customPaths != null && shapeData.customPaths.length > 0) {
|
|
1433
|
+
Object.assign(options, mapCustomPaths(shapeData.customPaths, ratio));
|
|
1434
|
+
}
|
|
1435
|
+
if (shapeData.trimPath != null) {
|
|
1436
|
+
options['trimPath'] = shapeData.trimPath;
|
|
1437
|
+
}
|
|
1438
|
+
if (shapeData.repeater != null) {
|
|
1439
|
+
options['repeater'] = shapeData.repeater;
|
|
1440
|
+
}
|
|
1441
|
+
return options;
|
|
1442
|
+
}
|
|
1443
|
+
var _obj;
|
|
1444
|
+
var SHAPE_PRIMITIVE_TYPE_TO_GE = (_obj = {}, _obj[IRShapePrimitiveType.Custom] = 0, _obj[IRShapePrimitiveType.Rectangle] = 1, _obj[IRShapePrimitiveType.Ellipse] = 2, _obj[IRShapePrimitiveType.Polygon] = 3, _obj[IRShapePrimitiveType.Star] = 4, _obj);
|
|
1445
|
+
var _obj1;
|
|
1446
|
+
var FILL_TYPE_TO_GE = (_obj1 = {}, _obj1[IRFillType.Solid] = 0, _obj1[IRFillType.LinearGradient] = 1, _obj1[IRFillType.RadialGradient] = 2, _obj1[IRFillType.AngularGradient] = 3, _obj1[IRFillType.Texture] = 4, _obj1);
|
|
1447
|
+
var _obj2;
|
|
1448
|
+
var LINE_CAP_TO_GE = (_obj2 = {}, _obj2[IRLineCap.Butt] = 0, _obj2[IRLineCap.Round] = 1, _obj2[IRLineCap.Square] = 2, _obj2);
|
|
1449
|
+
var _obj3;
|
|
1450
|
+
var LINE_JOIN_TO_GE = (_obj3 = {}, _obj3[IRLineJoin.Round] = 0, _obj3[IRLineJoin.Bevel] = 1, _obj3[IRLineJoin.Miter] = 2, _obj3);
|
|
1451
|
+
var _obj4;
|
|
1452
|
+
var SHAPE_FILL_RULE_TO_GE = (_obj4 = {}, _obj4[IRShapeFillRule.NonZero] = 0, _obj4[IRShapeFillRule.EvenOdd] = 1, _obj4);
|
|
1453
|
+
function mapShapePrimitiveType(primitiveType) {
|
|
1454
|
+
return SHAPE_PRIMITIVE_TYPE_TO_GE[primitiveType];
|
|
1455
|
+
}
|
|
1456
|
+
function mapLineCap(lineCap) {
|
|
1457
|
+
var _LINE_CAP_TO_GE_lineCap;
|
|
1458
|
+
return (_LINE_CAP_TO_GE_lineCap = LINE_CAP_TO_GE[lineCap]) != null ? _LINE_CAP_TO_GE_lineCap : 0;
|
|
1459
|
+
}
|
|
1460
|
+
function mapLineJoin(lineJoin) {
|
|
1461
|
+
var _LINE_JOIN_TO_GE_lineJoin;
|
|
1462
|
+
return (_LINE_JOIN_TO_GE_lineJoin = LINE_JOIN_TO_GE[lineJoin]) != null ? _LINE_JOIN_TO_GE_lineJoin : 2;
|
|
1463
|
+
}
|
|
1464
|
+
function mapShapeFillRule(fillRule) {
|
|
1465
|
+
var _SHAPE_FILL_RULE_TO_GE_fillRule;
|
|
1466
|
+
return (_SHAPE_FILL_RULE_TO_GE_fillRule = SHAPE_FILL_RULE_TO_GE[fillRule]) != null ? _SHAPE_FILL_RULE_TO_GE_fillRule : 0;
|
|
1467
|
+
}
|
|
1468
|
+
function mapShapePaint(paint, ratio, ctx) {
|
|
1469
|
+
if (paint.type === IRFillType.Solid) {
|
|
1470
|
+
return {
|
|
1471
|
+
type: FILL_TYPE_TO_GE[paint.type],
|
|
1472
|
+
color: colorToGE(paint.color)
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
if (paint.type === IRFillType.LinearGradient || paint.type === IRFillType.RadialGradient || paint.type === IRFillType.AngularGradient) {
|
|
1476
|
+
return _extends({
|
|
1477
|
+
type: FILL_TYPE_TO_GE[paint.type],
|
|
1478
|
+
gradientStops: [
|
|
1479
|
+
ValueType.GRADIENT_COLOR,
|
|
1480
|
+
paint.gradientStops
|
|
1481
|
+
],
|
|
1482
|
+
startPoint: vec2ToGE(paint.gradientStart, ratio),
|
|
1483
|
+
endPoint: vec2ToGE(paint.gradientEnd, ratio)
|
|
1484
|
+
}, paint.color != null && {
|
|
1485
|
+
color: colorToGE(paint.color)
|
|
1486
|
+
});
|
|
1487
|
+
}
|
|
1488
|
+
if (paint.type === IRFillType.Texture) {
|
|
1489
|
+
var _ref, _paint_texture_url, _paint_scaleMode;
|
|
1490
|
+
var textureUrl = (_ref = (_paint_texture_url = paint.texture.url) != null ? _paint_texture_url : paint.texture.refId) != null ? _ref : paint.texture.id;
|
|
1491
|
+
var texture = textureUrl != null && ctx != null ? registerTexture(ctx.collector, textureUrl, ctx.textureCache) : undefined;
|
|
1492
|
+
return _extends({
|
|
1493
|
+
type: FILL_TYPE_TO_GE[paint.type]
|
|
1494
|
+
}, texture != null && {
|
|
1495
|
+
texture: texture
|
|
1496
|
+
}, {
|
|
1497
|
+
scaleMode: (_paint_scaleMode = paint.scaleMode) != null ? _paint_scaleMode : 0
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
return undefined;
|
|
1501
|
+
}
|
|
1502
|
+
function colorToGE(color) {
|
|
1503
|
+
return {
|
|
1504
|
+
r: roundNumber(color[0], 4),
|
|
1505
|
+
g: roundNumber(color[1], 4),
|
|
1506
|
+
b: roundNumber(color[2], 4),
|
|
1507
|
+
a: roundNumber(color[3], 4)
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
function vec2ToGE(value, ratio) {
|
|
1511
|
+
var _ref, _ref1;
|
|
1512
|
+
return {
|
|
1513
|
+
x: roundNumber(((_ref = value == null ? void 0 : value[0]) != null ? _ref : 0) * ratio, 4),
|
|
1514
|
+
y: roundNumber(-((_ref1 = value == null ? void 0 : value[1]) != null ? _ref1 : 0) * ratio, 4)
|
|
1515
|
+
};
|
|
1516
|
+
}
|
|
1517
|
+
function mapCustomPaths(paths, ratio) {
|
|
1518
|
+
var points = [];
|
|
1519
|
+
var easingIns = [];
|
|
1520
|
+
var easingOuts = [];
|
|
1521
|
+
var shapes = [];
|
|
1522
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(paths), _step; !(_step = _iterator()).done;){
|
|
1523
|
+
var path = _step.value;
|
|
1524
|
+
var indexes = [];
|
|
1525
|
+
for(var index = 0; index < path.points.length; index++){
|
|
1526
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
1527
|
+
var point = path.points[index];
|
|
1528
|
+
var easingIn = path.easingIns[index];
|
|
1529
|
+
var easingOut = path.easingOuts[index];
|
|
1530
|
+
var pointIndex = points.length;
|
|
1531
|
+
points.push({
|
|
1532
|
+
x: roundNumber(point.x * ratio, 4),
|
|
1533
|
+
y: roundNumber(-point.y * ratio, 4)
|
|
1534
|
+
});
|
|
1535
|
+
easingIns.push({
|
|
1536
|
+
x: roundNumber(((_ref = easingIn == null ? void 0 : easingIn.x) != null ? _ref : 0) * ratio, 4),
|
|
1537
|
+
y: roundNumber(-((_ref1 = easingIn == null ? void 0 : easingIn.y) != null ? _ref1 : 0) * ratio, 4)
|
|
1538
|
+
});
|
|
1539
|
+
easingOuts.push({
|
|
1540
|
+
x: roundNumber(((_ref2 = easingOut == null ? void 0 : easingOut.x) != null ? _ref2 : 0) * ratio, 4),
|
|
1541
|
+
y: roundNumber(-((_ref3 = easingOut == null ? void 0 : easingOut.y) != null ? _ref3 : 0) * ratio, 4)
|
|
1542
|
+
});
|
|
1543
|
+
indexes.push({
|
|
1544
|
+
point: pointIndex,
|
|
1545
|
+
easingIn: pointIndex,
|
|
1546
|
+
easingOut: pointIndex
|
|
1547
|
+
});
|
|
1548
|
+
}
|
|
1549
|
+
shapes.push({
|
|
1550
|
+
close: path.close,
|
|
1551
|
+
indexes: indexes
|
|
1552
|
+
});
|
|
1553
|
+
}
|
|
1554
|
+
return {
|
|
1555
|
+
points: points,
|
|
1556
|
+
easingIns: easingIns,
|
|
1557
|
+
easingOuts: easingOuts,
|
|
1558
|
+
shapes: shapes
|
|
1559
|
+
};
|
|
1560
|
+
}
|
|
1561
|
+
function setScaledNumber(options, shapeData, key, ratio) {
|
|
1562
|
+
var value = shapeData[key];
|
|
1563
|
+
if (typeof value === 'number') {
|
|
1564
|
+
options[key] = roundNumber(value * ratio, 4);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
function setRawNumber(options, shapeData, key) {
|
|
1568
|
+
var value = shapeData[key];
|
|
1569
|
+
if (typeof value === 'number') {
|
|
1570
|
+
options[key] = value;
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
function getStaticAnchorBehavior(ir, layer) {
|
|
1575
|
+
if (layer.transformSplit === true) {
|
|
1576
|
+
return {
|
|
1577
|
+
kind: 'split-null-sprite'
|
|
1578
|
+
};
|
|
1579
|
+
}
|
|
1580
|
+
// B-class real semantic difference — kept as source branch because pre-baking
|
|
1581
|
+
// anchorScale/anchorOffset into the IR would require pulling computeAnchorInfo's
|
|
1582
|
+
// full input set (text anchorAdjust, static-rotation anchor rotation, display
|
|
1583
|
+
// size fallback) into the producer, at high cost with no readability benefit.
|
|
1584
|
+
// The split gate itself is already pre-baked via `transformSplit` above.
|
|
1585
|
+
//
|
|
1586
|
+
// ge source shares the lottie inline-anchor math: ge2ir reverses GE's
|
|
1587
|
+
// `renderer.anchor` into IRLayerNode.transform.anchor (px) + displaySize, so
|
|
1588
|
+
// computeAnchorInfo reproduces the exact anchorScale/anchorOffset that GE had.
|
|
1589
|
+
// Without this, ge layers fall through to the centered [0.5,0.5] default and
|
|
1590
|
+
// their authored anchor (e.g. a top-anchored sweep) is lost on round-trip.
|
|
1591
|
+
// ge never reaches the lottieNeedsTransformSplit geometry check — its split
|
|
1592
|
+
// decision is pre-baked via `transformSplit` by the ge2ir null+sprite merger.
|
|
1593
|
+
if (ir.source === 'lottie' || ir.source === 'ge') {
|
|
1594
|
+
if (ir.source === 'lottie' && lottieNeedsTransformSplit(layer)) {
|
|
1595
|
+
return {
|
|
1596
|
+
kind: 'split-null-sprite'
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
// The inline-anchor math needs non-zero dimensions to avoid divide-by-zero
|
|
1600
|
+
// in `computeAnchorInfo`; substitute the legacy {1, 1} fallback at the call site
|
|
1601
|
+
// so the field-level default stays neutral.
|
|
1602
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), width = _getLayerDisplaySize.width, height = _getLayerDisplaySize.height;
|
|
1603
|
+
var info = computeAnchorInfo(layer, width, height);
|
|
1604
|
+
return {
|
|
1605
|
+
kind: 'inline-anchor',
|
|
1606
|
+
anchorScale: [
|
|
1607
|
+
info.anchorScaleX,
|
|
1608
|
+
info.anchorScaleY
|
|
1609
|
+
],
|
|
1610
|
+
anchorOffset: [
|
|
1611
|
+
info.anchorOffsetX,
|
|
1612
|
+
info.anchorOffsetY
|
|
1613
|
+
]
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
// dsl layers with off-center anchor have `transformSplit = true` set by the
|
|
1617
|
+
// producer, caught by the guard at the top. Any layer reaching here is
|
|
1618
|
+
// centered — return the default inline-anchor.
|
|
1619
|
+
return {
|
|
1620
|
+
kind: 'inline-anchor',
|
|
1621
|
+
anchorScale: [
|
|
1622
|
+
0.5,
|
|
1623
|
+
0.5
|
|
1624
|
+
],
|
|
1625
|
+
anchorOffset: [
|
|
1626
|
+
0,
|
|
1627
|
+
0
|
|
1628
|
+
]
|
|
1629
|
+
};
|
|
1630
|
+
}
|
|
1631
|
+
function lottieNeedsTransformSplit(layer) {
|
|
1632
|
+
var _transform_rotation, _sep_x, _sep_y, _sep_z, _transform_scale;
|
|
1633
|
+
if (layer.type !== 'image' && layer.type !== 'solid') {
|
|
1634
|
+
return false;
|
|
1635
|
+
}
|
|
1636
|
+
// Without a producer-baked displaySize we cannot decide off-center;
|
|
1637
|
+
// fall through to inline-anchor (matches the pre-displaySize behavior
|
|
1638
|
+
// where missing dimensions returned the {1, 1} default and never split).
|
|
1639
|
+
var size = layer.displaySize;
|
|
1640
|
+
if (size == null) {
|
|
1641
|
+
return false;
|
|
1642
|
+
}
|
|
1643
|
+
var width = size.width, height = size.height;
|
|
1644
|
+
if (width <= 0 || height <= 0) {
|
|
1645
|
+
return false;
|
|
1646
|
+
}
|
|
1647
|
+
var anchor = getStaticAnchor(layer);
|
|
1648
|
+
var anchorOffCenter = Math.abs(anchor[0] - width / 2) > 0.5 || Math.abs(anchor[1] - height / 2) > 0.5;
|
|
1649
|
+
if (!anchorOffCenter) {
|
|
1650
|
+
return false;
|
|
1651
|
+
}
|
|
1652
|
+
var transform = layer.transform;
|
|
1653
|
+
var sep = transform == null ? void 0 : transform.separatedRotation;
|
|
1654
|
+
var hasRotationAnim = (transform == null ? void 0 : (_transform_rotation = transform.rotation) == null ? void 0 : _transform_rotation.keyframed) === true || (sep == null ? void 0 : (_sep_x = sep.x) == null ? void 0 : _sep_x.keyframed) === true || (sep == null ? void 0 : (_sep_y = sep.y) == null ? void 0 : _sep_y.keyframed) === true || (sep == null ? void 0 : (_sep_z = sep.z) == null ? void 0 : _sep_z.keyframed) === true;
|
|
1655
|
+
var hasScaleAnim = (transform == null ? void 0 : (_transform_scale = transform.scale) == null ? void 0 : _transform_scale.keyframed) === true;
|
|
1656
|
+
return hasRotationAnim || hasScaleAnim;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
function processNullLayer(layer, ctx) {
|
|
1660
|
+
var itemId = createId();
|
|
1661
|
+
var layerIndex = layer.index;
|
|
1662
|
+
ctx.layerToItemId[layerIndex] = itemId;
|
|
1663
|
+
var _computeLayerTiming = computeLayerTiming(layer, ctx.frameRate), delay = _computeLayerTiming.delay, layerDuration = _computeLayerTiming.layerDuration;
|
|
1664
|
+
var animation = buildTransformAnimation(layer, ctx);
|
|
1665
|
+
var position = computeStaticPosition(layer, ctx);
|
|
1666
|
+
var objectBindingTrackId = buildTimelineTracks(ctx.collector, delay, layerDuration, 4, animation, 'null');
|
|
1667
|
+
var item = {
|
|
1668
|
+
id: itemId,
|
|
1669
|
+
dataType: 'VFXItemData',
|
|
1670
|
+
name: layer.name,
|
|
1671
|
+
duration: layerDuration,
|
|
1672
|
+
type: '3',
|
|
1673
|
+
visible: layer.visibility.enabled && !layer.visibility.hidden,
|
|
1674
|
+
endBehavior: 4,
|
|
1675
|
+
delay: delay,
|
|
1676
|
+
renderLevel: 'B+',
|
|
1677
|
+
content: {
|
|
1678
|
+
options: {
|
|
1679
|
+
startColor: [
|
|
1680
|
+
1,
|
|
1681
|
+
1,
|
|
1682
|
+
1,
|
|
1683
|
+
1
|
|
1684
|
+
]
|
|
1685
|
+
}
|
|
1686
|
+
},
|
|
1687
|
+
components: [],
|
|
1688
|
+
transform: buildGETransform(position, [
|
|
1689
|
+
0,
|
|
1690
|
+
0,
|
|
1691
|
+
0
|
|
1692
|
+
], [
|
|
1693
|
+
1,
|
|
1694
|
+
1,
|
|
1695
|
+
1
|
|
1696
|
+
])
|
|
1697
|
+
};
|
|
1698
|
+
ctx.collector.items.push(item);
|
|
1699
|
+
ctx.processedItems.push({
|
|
1700
|
+
itemId: itemId,
|
|
1701
|
+
objectBindingTrackId: objectBindingTrackId,
|
|
1702
|
+
layerIndex: layerIndex
|
|
1703
|
+
});
|
|
1704
|
+
}
|
|
1705
|
+
/**
|
|
1706
|
+
* Emit a null+sprite pair: the null carries the layer transform and sits at
|
|
1707
|
+
* the layer's logical position; the sprite/text child carries the visual
|
|
1708
|
+
* content offset by the anchor so the pivot is at the right point.
|
|
1709
|
+
*
|
|
1710
|
+
* Used by both `processParentLayer` (layers referenced as `parent` by others)
|
|
1711
|
+
* and `processTransformSplitLayer` (layers with `transformSplit=true`). The
|
|
1712
|
+
* only knob is `childScale` — parent-layer callers pass a text-aware scale
|
|
1713
|
+
* while transformSplit always uses `[1, 1, 1]`.
|
|
1714
|
+
*/ function emitNullSpritePair(layer, ctx, childScale) {
|
|
1715
|
+
var layerIndex = layer.index;
|
|
1716
|
+
var _computeLayerTiming = computeLayerTiming(layer, ctx.frameRate), delay = _computeLayerTiming.delay, layerDuration = _computeLayerTiming.layerDuration;
|
|
1717
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), layerWidth = _getLayerDisplaySize.width, layerHeight = _getLayerDisplaySize.height;
|
|
1718
|
+
var nullItemId = createId();
|
|
1719
|
+
ctx.layerToItemId[layerIndex] = nullItemId;
|
|
1720
|
+
var nullAnimation = buildTransformAnimation(layer, ctx);
|
|
1721
|
+
var nullPosition = computeStaticPosition(layer, ctx);
|
|
1722
|
+
var nullTrackId = buildTimelineTracks(ctx.collector, delay, layerDuration, 4, nullAnimation, 'null');
|
|
1723
|
+
var nullItem = {
|
|
1724
|
+
id: nullItemId,
|
|
1725
|
+
dataType: 'VFXItemData',
|
|
1726
|
+
name: layer.name,
|
|
1727
|
+
duration: layerDuration,
|
|
1728
|
+
type: '3',
|
|
1729
|
+
visible: true,
|
|
1730
|
+
endBehavior: 4,
|
|
1731
|
+
delay: delay,
|
|
1732
|
+
renderLevel: 'B+',
|
|
1733
|
+
content: {
|
|
1734
|
+
options: {
|
|
1735
|
+
startColor: [
|
|
1736
|
+
1,
|
|
1737
|
+
1,
|
|
1738
|
+
1,
|
|
1739
|
+
1
|
|
1740
|
+
]
|
|
1741
|
+
}
|
|
1742
|
+
},
|
|
1743
|
+
components: [],
|
|
1744
|
+
transform: buildGETransform(nullPosition, [
|
|
1745
|
+
0,
|
|
1746
|
+
0,
|
|
1747
|
+
0
|
|
1748
|
+
], [
|
|
1749
|
+
1,
|
|
1750
|
+
1,
|
|
1751
|
+
1
|
|
1752
|
+
])
|
|
1753
|
+
};
|
|
1754
|
+
ctx.collector.items.push(nullItem);
|
|
1755
|
+
ctx.processedItems.push({
|
|
1756
|
+
itemId: nullItemId,
|
|
1757
|
+
objectBindingTrackId: nullTrackId,
|
|
1758
|
+
layerIndex: layerIndex
|
|
1759
|
+
});
|
|
1760
|
+
var childItemId = createId();
|
|
1761
|
+
var anchor = getStaticAnchor(layer);
|
|
1762
|
+
var childPosition = [
|
|
1763
|
+
-ctx.ratio * (anchor[0] - layerWidth / 2),
|
|
1764
|
+
ctx.ratio * (anchor[1] - layerHeight / 2),
|
|
1765
|
+
0
|
|
1766
|
+
];
|
|
1767
|
+
var childColorAnim = buildColorAnimation(layer, ctx.ir);
|
|
1768
|
+
var childTrackId = buildTimelineTracks(ctx.collector, delay, layerDuration, 0, {
|
|
1769
|
+
colorOverLifetime: childColorAnim
|
|
1770
|
+
}, getGEItemType(layer.type));
|
|
1771
|
+
var componentId = buildComponent(layer, childItemId, 0.5, 0.5, ctx);
|
|
1772
|
+
if (componentId != null) {
|
|
1773
|
+
ctx.layerToComponentId[layerIndex] = componentId;
|
|
1774
|
+
}
|
|
1775
|
+
var scaledW = roundNumber(ctx.ratio * layerWidth, 4);
|
|
1776
|
+
var scaledH = roundNumber(ctx.ratio * layerHeight, 4);
|
|
1777
|
+
var childItem = {
|
|
1778
|
+
id: childItemId,
|
|
1779
|
+
dataType: 'VFXItemData',
|
|
1780
|
+
name: layer.name,
|
|
1781
|
+
duration: layerDuration,
|
|
1782
|
+
type: getGEItemTypeCode(layer.type),
|
|
1783
|
+
visible: layer.visibility.enabled && !layer.visibility.hidden,
|
|
1784
|
+
endBehavior: 0,
|
|
1785
|
+
delay: delay,
|
|
1786
|
+
renderLevel: 'B+',
|
|
1787
|
+
components: componentId != null ? [
|
|
1788
|
+
toDataPath(componentId)
|
|
1789
|
+
] : [],
|
|
1790
|
+
transform: _extends({}, buildGETransform(childPosition, [
|
|
1791
|
+
0,
|
|
1792
|
+
0,
|
|
1793
|
+
0
|
|
1794
|
+
], childScale), {
|
|
1795
|
+
anchor: {
|
|
1796
|
+
x: 0,
|
|
1797
|
+
y: 0
|
|
1798
|
+
},
|
|
1799
|
+
size: {
|
|
1800
|
+
x: scaledW,
|
|
1801
|
+
y: scaledH
|
|
1802
|
+
}
|
|
1803
|
+
}),
|
|
1804
|
+
parentId: nullItemId
|
|
1805
|
+
};
|
|
1806
|
+
ctx.collector.items.push(childItem);
|
|
1807
|
+
ctx.processedItems.push({
|
|
1808
|
+
itemId: childItemId,
|
|
1809
|
+
objectBindingTrackId: childTrackId,
|
|
1810
|
+
layerIndex: layerIndex
|
|
1811
|
+
});
|
|
1812
|
+
}
|
|
1813
|
+
function processParentLayer(layer, ctx) {
|
|
1814
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), layerWidth = _getLayerDisplaySize.width, layerHeight = _getLayerDisplaySize.height;
|
|
1815
|
+
var scaledW = roundNumber(ctx.ratio * layerWidth, 4);
|
|
1816
|
+
var scaledH = roundNumber(ctx.ratio * layerHeight, 4);
|
|
1817
|
+
var childScale = layer.type === 'text' ? [
|
|
1818
|
+
scaledW,
|
|
1819
|
+
scaledH,
|
|
1820
|
+
1
|
|
1821
|
+
] : [
|
|
1822
|
+
1,
|
|
1823
|
+
1,
|
|
1824
|
+
1
|
|
1825
|
+
];
|
|
1826
|
+
emitNullSpritePair(layer, ctx, childScale);
|
|
1827
|
+
}
|
|
1828
|
+
function processVisualLayer(layer, ctx) {
|
|
1829
|
+
if (layer.type === 'shape' && layer.shapes != null && layer.shapes.length > 0) {
|
|
1830
|
+
processShapeLayerMultiItem(layer, ctx);
|
|
1831
|
+
return;
|
|
1832
|
+
}
|
|
1833
|
+
var strategy = getStaticAnchorBehavior(ctx.ir, layer);
|
|
1834
|
+
if (strategy.kind === 'split-null-sprite') {
|
|
1835
|
+
processTransformSplitLayer(layer, ctx);
|
|
1836
|
+
return;
|
|
1837
|
+
}
|
|
1838
|
+
var itemId = createId();
|
|
1839
|
+
var layerIndex = layer.index;
|
|
1840
|
+
ctx.layerToItemId[layerIndex] = itemId;
|
|
1841
|
+
var _computeLayerTiming = computeLayerTiming(layer, ctx.frameRate), delay = _computeLayerTiming.delay, layerDuration = _computeLayerTiming.layerDuration;
|
|
1842
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), layerWidth = _getLayerDisplaySize.width, layerHeight = _getLayerDisplaySize.height;
|
|
1843
|
+
var scaledW = ctx.ratio * layerWidth;
|
|
1844
|
+
var scaledH = ctx.ratio * layerHeight;
|
|
1845
|
+
var _strategy_anchorScale = strategy.anchorScale, anchorScaleX = _strategy_anchorScale[0], anchorScaleY = _strategy_anchorScale[1];
|
|
1846
|
+
var _strategy_anchorOffset = strategy.anchorOffset, anchorOffsetX = _strategy_anchorOffset[0], anchorOffsetY = _strategy_anchorOffset[1];
|
|
1847
|
+
var animation = buildTransformAnimation(layer, ctx);
|
|
1848
|
+
var colorAnimation = buildColorAnimation(layer, ctx.ir);
|
|
1849
|
+
var fullAnimation = _extends({}, animation, {
|
|
1850
|
+
colorOverLifetime: colorAnimation
|
|
1851
|
+
});
|
|
1852
|
+
var rawPosition = computeStaticPosition(layer, ctx, anchorOffsetX, anchorOffsetY);
|
|
1853
|
+
var position = applyScalePositionAdjust(rawPosition, layer, layerWidth, layerHeight, ctx.ratio);
|
|
1854
|
+
var itemType = getGEItemType(layer.type);
|
|
1855
|
+
var objectBindingTrackId = buildTimelineTracks(ctx.collector, delay, layerDuration, 0, fullAnimation, itemType);
|
|
1856
|
+
var componentId = buildComponent(layer, itemId, anchorScaleX, anchorScaleY, ctx);
|
|
1857
|
+
if (componentId != null) {
|
|
1858
|
+
ctx.layerToComponentId[layerIndex] = componentId;
|
|
1859
|
+
}
|
|
1860
|
+
// GE 2.x TextComponent.updateTexture overwrites transform.size to
|
|
1861
|
+
// (textWidth × 0.0123, textHeight × 0.0123) regardless of what we emit,
|
|
1862
|
+
// so the only knob left to control on-screen size is transform.scale.
|
|
1863
|
+
// Pre-bake it so version36Migration's scaleFactor = (preScale / textWidth) / 0.0123
|
|
1864
|
+
// resolves to ctx.ratio / 0.0123 — the correct ratio for this composition.
|
|
1865
|
+
var itemScale = layer.type === 'text' ? [
|
|
1866
|
+
scaledW,
|
|
1867
|
+
scaledH,
|
|
1868
|
+
1
|
|
1869
|
+
] : [
|
|
1870
|
+
1,
|
|
1871
|
+
1,
|
|
1872
|
+
1
|
|
1873
|
+
];
|
|
1874
|
+
var item = {
|
|
1875
|
+
id: itemId,
|
|
1876
|
+
dataType: 'VFXItemData',
|
|
1877
|
+
name: layer.name,
|
|
1878
|
+
duration: layerDuration,
|
|
1879
|
+
type: getGEItemTypeCode(layer.type),
|
|
1880
|
+
visible: layer.visibility.enabled && !layer.visibility.hidden,
|
|
1881
|
+
endBehavior: 0,
|
|
1882
|
+
delay: delay,
|
|
1883
|
+
renderLevel: 'B+',
|
|
1884
|
+
components: componentId != null ? [
|
|
1885
|
+
toDataPath(componentId)
|
|
1886
|
+
] : [],
|
|
1887
|
+
transform: _extends({}, buildGETransform(position, [
|
|
1888
|
+
0,
|
|
1889
|
+
0,
|
|
1890
|
+
0
|
|
1891
|
+
], itemScale), {
|
|
1892
|
+
anchor: {
|
|
1893
|
+
x: 0,
|
|
1894
|
+
y: 0
|
|
1895
|
+
},
|
|
1896
|
+
size: {
|
|
1897
|
+
x: roundNumber(scaledW, 4),
|
|
1898
|
+
y: roundNumber(scaledH, 4)
|
|
1899
|
+
}
|
|
1900
|
+
})
|
|
1901
|
+
};
|
|
1902
|
+
ctx.collector.items.push(item);
|
|
1903
|
+
ctx.processedItems.push({
|
|
1904
|
+
itemId: itemId,
|
|
1905
|
+
objectBindingTrackId: objectBindingTrackId,
|
|
1906
|
+
layerIndex: layerIndex
|
|
1907
|
+
});
|
|
1908
|
+
}
|
|
1909
|
+
function processTransformSplitLayer(layer, ctx) {
|
|
1910
|
+
emitNullSpritePair(layer, ctx, [
|
|
1911
|
+
1,
|
|
1912
|
+
1,
|
|
1913
|
+
1
|
|
1914
|
+
]);
|
|
1915
|
+
}
|
|
1916
|
+
function processShapeLayerMultiItem(layer, ctx) {
|
|
1917
|
+
var layerIndex = layer.index;
|
|
1918
|
+
var _computeLayerTiming = computeLayerTiming(layer, ctx.frameRate), delay = _computeLayerTiming.delay, layerDuration = _computeLayerTiming.layerDuration;
|
|
1919
|
+
var _getLayerDisplaySize = getLayerDisplaySize(layer), layerWidth = _getLayerDisplaySize.width, layerHeight = _getLayerDisplaySize.height;
|
|
1920
|
+
var anchor = getStaticAnchor(layer);
|
|
1921
|
+
var _computeAnchorInfo = computeAnchorInfo(layer, layerWidth, layerHeight), anchorOffsetX = _computeAnchorInfo.anchorOffsetX, anchorOffsetY = _computeAnchorInfo.anchorOffsetY;
|
|
1922
|
+
var animation = buildTransformAnimation(layer, ctx);
|
|
1923
|
+
var colorAnimation = buildColorAnimation(layer, ctx.ir);
|
|
1924
|
+
var fullAnimation = _extends({}, animation, {
|
|
1925
|
+
colorOverLifetime: colorAnimation
|
|
1926
|
+
});
|
|
1927
|
+
var basePosition = computeStaticPosition(layer, ctx, anchorOffsetX, anchorOffsetY);
|
|
1928
|
+
var blending = mapBlendingMode(layer.blendMode);
|
|
1929
|
+
for(var shapeIdx = 0; shapeIdx < layer.shapes.length; shapeIdx++){
|
|
1930
|
+
var shapeData = layer.shapes[shapeIdx];
|
|
1931
|
+
var shapeItemId = createId();
|
|
1932
|
+
if (shapeIdx === 0) {
|
|
1933
|
+
ctx.layerToItemId[layerIndex] = shapeItemId;
|
|
1934
|
+
}
|
|
1935
|
+
var shapeOffsetX = ctx.ratio * (shapeData.position[0] - anchor[0]);
|
|
1936
|
+
var shapeOffsetY = -ctx.ratio * (shapeData.position[1] - anchor[1]);
|
|
1937
|
+
var shapePosition = [
|
|
1938
|
+
basePosition[0] + shapeOffsetX,
|
|
1939
|
+
basePosition[1] + shapeOffsetY,
|
|
1940
|
+
basePosition[2]
|
|
1941
|
+
];
|
|
1942
|
+
var shapeComponentId = createId();
|
|
1943
|
+
var component = _extends({
|
|
1944
|
+
id: shapeComponentId,
|
|
1945
|
+
dataType: 'ShapeComponent',
|
|
1946
|
+
item: toDataPath(shapeItemId)
|
|
1947
|
+
}, buildShapeOptions(shapeData, ctx.ratio, ctx), {
|
|
1948
|
+
renderer: _extends({
|
|
1949
|
+
renderMode: 1
|
|
1950
|
+
}, blending !== undefined && {
|
|
1951
|
+
blending: blending
|
|
1952
|
+
})
|
|
1953
|
+
});
|
|
1954
|
+
// Mask source shape (isMask:true) — copy onto the first shape item only.
|
|
1955
|
+
if (shapeIdx === 0) {
|
|
1956
|
+
applyGeMask(ctx.ir, layer, component);
|
|
1957
|
+
}
|
|
1958
|
+
ctx.collector.components.push(component);
|
|
1959
|
+
if (shapeIdx === 0) {
|
|
1960
|
+
ctx.layerToComponentId[layerIndex] = shapeComponentId;
|
|
1961
|
+
}
|
|
1962
|
+
var objectBindingTrackId = buildTimelineTracks(ctx.collector, delay, layerDuration, 0, fullAnimation, 'shape');
|
|
1963
|
+
var shapeItem = {
|
|
1964
|
+
id: shapeItemId,
|
|
1965
|
+
dataType: 'VFXItemData',
|
|
1966
|
+
name: shapeIdx === 0 ? layer.name : layer.name + "_shape_" + shapeIdx,
|
|
1967
|
+
duration: layerDuration,
|
|
1968
|
+
type: 'shape',
|
|
1969
|
+
visible: layer.visibility.enabled && !layer.visibility.hidden,
|
|
1970
|
+
endBehavior: 0,
|
|
1971
|
+
delay: delay,
|
|
1972
|
+
renderLevel: 'B+',
|
|
1973
|
+
components: [
|
|
1974
|
+
toDataPath(shapeComponentId)
|
|
1975
|
+
],
|
|
1976
|
+
transform: _extends({}, buildGETransform(shapePosition, [
|
|
1977
|
+
0,
|
|
1978
|
+
0,
|
|
1979
|
+
0
|
|
1980
|
+
], [
|
|
1981
|
+
1,
|
|
1982
|
+
1,
|
|
1983
|
+
1
|
|
1984
|
+
]), {
|
|
1985
|
+
anchor: {
|
|
1986
|
+
x: 0,
|
|
1987
|
+
y: 0
|
|
1988
|
+
}
|
|
1989
|
+
})
|
|
1990
|
+
};
|
|
1991
|
+
ctx.collector.items.push(shapeItem);
|
|
1992
|
+
ctx.processedItems.push({
|
|
1993
|
+
itemId: shapeItemId,
|
|
1994
|
+
objectBindingTrackId: objectBindingTrackId,
|
|
1995
|
+
layerIndex: layerIndex
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
var DEFAULT_PLAYER_VERSION = {
|
|
2001
|
+
web: '2.8.9',
|
|
2002
|
+
native: '0.0.1.202311221223'
|
|
2003
|
+
};
|
|
2004
|
+
/**
|
|
2005
|
+
* Assemble the top-level GE JSONScene wrapper from a populated collector.
|
|
2006
|
+
*
|
|
2007
|
+
* Reads composition-level properties (`name`, `width`/`height`, `endBehavior`,
|
|
2008
|
+
* `backgroundColor`) directly from the IR. The optional `duration` arg is a
|
|
2009
|
+
* caller override — when omitted, derived from `(outPoint - inPoint) / frameRate`.
|
|
2010
|
+
*/ function assembleScene(ir, collector, processedItems, duration) {
|
|
2011
|
+
var finalDuration = duration != null ? duration : deriveDuration(ir);
|
|
2012
|
+
var timelineAssetId = createId();
|
|
2013
|
+
var objectBindingTrackRefs = processedItems.map(function(pi) {
|
|
2014
|
+
return toDataPath(pi.objectBindingTrackId);
|
|
2015
|
+
});
|
|
2016
|
+
collector.miscs.push({
|
|
2017
|
+
id: timelineAssetId,
|
|
2018
|
+
dataType: 'TimelineAsset',
|
|
2019
|
+
tracks: objectBindingTrackRefs
|
|
2020
|
+
});
|
|
2021
|
+
var compositionComponentId = createId();
|
|
2022
|
+
var compositionId = createId();
|
|
2023
|
+
var sceneBindings = processedItems.map(function(pi) {
|
|
2024
|
+
return {
|
|
2025
|
+
key: toDataPath(pi.objectBindingTrackId),
|
|
2026
|
+
value: toDataPath(pi.itemId)
|
|
2027
|
+
};
|
|
2028
|
+
});
|
|
2029
|
+
var allItemRefs = processedItems.map(function(pi) {
|
|
2030
|
+
return toDataPath(pi.itemId);
|
|
2031
|
+
});
|
|
2032
|
+
collector.components.push({
|
|
2033
|
+
id: compositionComponentId,
|
|
2034
|
+
dataType: 'CompositionComponent',
|
|
2035
|
+
item: toDataPath(compositionId),
|
|
2036
|
+
items: allItemRefs,
|
|
2037
|
+
timelineAsset: toDataPath(timelineAssetId),
|
|
2038
|
+
sceneBindings: sceneBindings
|
|
2039
|
+
});
|
|
2040
|
+
var composition = {
|
|
2041
|
+
id: compositionId,
|
|
2042
|
+
name: ir.name,
|
|
2043
|
+
duration: finalDuration,
|
|
2044
|
+
startTime: 0,
|
|
2045
|
+
endBehavior: mapCompositionEndBehavior(ir.endBehavior),
|
|
2046
|
+
previewSize: [
|
|
2047
|
+
ir.width,
|
|
2048
|
+
ir.height
|
|
2049
|
+
],
|
|
2050
|
+
camera: {
|
|
2051
|
+
fov: DEFAULT_CAMERA_FOV,
|
|
2052
|
+
far: 40,
|
|
2053
|
+
near: 0.1,
|
|
2054
|
+
clipMode: DEFAULT_CLIP_MODE,
|
|
2055
|
+
position: [
|
|
2056
|
+
0,
|
|
2057
|
+
0,
|
|
2058
|
+
DEFAULT_CAMERA_Z
|
|
2059
|
+
],
|
|
2060
|
+
rotation: [
|
|
2061
|
+
0,
|
|
2062
|
+
0,
|
|
2063
|
+
0
|
|
2064
|
+
]
|
|
2065
|
+
},
|
|
2066
|
+
components: [
|
|
2067
|
+
toDataPath(compositionComponentId)
|
|
2068
|
+
]
|
|
2069
|
+
};
|
|
2070
|
+
if (ir.backgroundColor != null) {
|
|
2071
|
+
composition['background'] = {
|
|
2072
|
+
color: colorToRoundedRgba(ir.backgroundColor)
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
2075
|
+
return {
|
|
2076
|
+
version: JSONSceneVersion['3_6'],
|
|
2077
|
+
playerVersion: DEFAULT_PLAYER_VERSION,
|
|
2078
|
+
images: collector.images,
|
|
2079
|
+
fonts: [],
|
|
2080
|
+
plugins: [],
|
|
2081
|
+
type: 'ge',
|
|
2082
|
+
compositionId: compositionId,
|
|
2083
|
+
compositions: [
|
|
2084
|
+
composition
|
|
2085
|
+
],
|
|
2086
|
+
components: collector.components,
|
|
2087
|
+
geometries: [],
|
|
2088
|
+
materials: [],
|
|
2089
|
+
items: collector.items,
|
|
2090
|
+
shaders: [],
|
|
2091
|
+
bins: [],
|
|
2092
|
+
textures: collector.textures,
|
|
2093
|
+
animations: [],
|
|
2094
|
+
miscs: collector.miscs
|
|
2095
|
+
};
|
|
2096
|
+
}
|
|
2097
|
+
function deriveDuration(ir) {
|
|
2098
|
+
return ir.frameRate > 0 ? (ir.outPoint - ir.inPoint) / ir.frameRate : 0;
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Map IR composition end behavior to GE's numeric end-behavior.
|
|
2102
|
+
* Lottie IR currently leaves this unset; treat undefined as Loop (5) so the
|
|
2103
|
+
* legacy lottie behavior is preserved. dsl2ge writes either Loop or Stop.
|
|
2104
|
+
*/ function mapCompositionEndBehavior(eb) {
|
|
2105
|
+
if (eb == null || eb === IREndBehavior.Loop) {
|
|
2106
|
+
return 5;
|
|
2107
|
+
}
|
|
2108
|
+
if (eb === IREndBehavior.Hold) {
|
|
2109
|
+
return 4;
|
|
2110
|
+
}
|
|
2111
|
+
return 0;
|
|
2112
|
+
}
|
|
2113
|
+
function colorToRoundedRgba(color) {
|
|
2114
|
+
return [
|
|
2115
|
+
roundNumber(color[0]),
|
|
2116
|
+
roundNumber(color[1]),
|
|
2117
|
+
roundNumber(color[2]),
|
|
2118
|
+
roundNumber(color[3], 4)
|
|
2119
|
+
];
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
function applyParenting(layers, items, layerToItemId, ratio, width, height) {
|
|
2123
|
+
var layerByIndex = new Map();
|
|
2124
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(layers), _step; !(_step = _iterator()).done;){
|
|
2125
|
+
var layer = _step.value;
|
|
2126
|
+
layerByIndex.set(layer.index, layer);
|
|
2127
|
+
}
|
|
2128
|
+
var itemById = new Map();
|
|
2129
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(items), _step1; !(_step1 = _iterator1()).done;){
|
|
2130
|
+
var item = _step1.value;
|
|
2131
|
+
itemById.set(item.id, item);
|
|
2132
|
+
}
|
|
2133
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(layers), _step2; !(_step2 = _iterator2()).done;){
|
|
2134
|
+
var layer1 = _step2.value;
|
|
2135
|
+
if (layer1.parent == null) {
|
|
2136
|
+
continue;
|
|
2137
|
+
}
|
|
2138
|
+
var childItemId = layerToItemId[layer1.index];
|
|
2139
|
+
var parentLayer = layerByIndex.get(layer1.parent.index);
|
|
2140
|
+
if (parentLayer == null || childItemId == null) {
|
|
2141
|
+
continue;
|
|
2142
|
+
}
|
|
2143
|
+
var parentItemId = layerToItemId[parentLayer.index];
|
|
2144
|
+
if (parentItemId == null) {
|
|
2145
|
+
continue;
|
|
2146
|
+
}
|
|
2147
|
+
var childItem = itemById.get(childItemId);
|
|
2148
|
+
if (childItem == null) {
|
|
2149
|
+
continue;
|
|
2150
|
+
}
|
|
2151
|
+
childItem.parentId = parentItemId;
|
|
2152
|
+
var parentAnchor = getStaticAnchor(parentLayer);
|
|
2153
|
+
var adjustX = -ratio * (parentAnchor[0] - width / 2);
|
|
2154
|
+
var adjustY = ratio * (parentAnchor[1] - height / 2);
|
|
2155
|
+
childItem.transform.position.x += adjustX;
|
|
2156
|
+
childItem.transform.position.y += adjustY;
|
|
2157
|
+
}
|
|
2158
|
+
}
|
|
2159
|
+
|
|
2160
|
+
function applyMasks(ir, collector, processedItems, ratio, width, height, frameRate, lookup) {
|
|
2161
|
+
var layers = ir.layers;
|
|
2162
|
+
var maskSlotMeta = new Map();
|
|
2163
|
+
var componentById = new Map();
|
|
2164
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(collector.components), _step; !(_step = _iterator()).done;){
|
|
2165
|
+
var comp = _step.value;
|
|
2166
|
+
componentById.set(comp['id'], comp);
|
|
2167
|
+
}
|
|
2168
|
+
for(var i = layers.length - 1; i >= 0; i--){
|
|
2169
|
+
var layer = layers[i];
|
|
2170
|
+
var maskData = layer.mask;
|
|
2171
|
+
if (maskData == null) {
|
|
2172
|
+
continue;
|
|
2173
|
+
}
|
|
2174
|
+
if (isMaskExactCrop(maskData, layer, width, height, lookup)) {
|
|
2175
|
+
continue;
|
|
2176
|
+
}
|
|
2177
|
+
var layerItemId = lookup.getItemId(layer.index);
|
|
2178
|
+
if (layerItemId == null) {
|
|
2179
|
+
continue;
|
|
2180
|
+
}
|
|
2181
|
+
var layerComponentId = lookup.getComponentId(layer.index);
|
|
2182
|
+
buildMaskForLayer(layer, layerItemId, layerComponentId, collector, processedItems, ratio, width, height, frameRate, lookup, maskSlotMeta, componentById, maskData);
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
function getPrimaryPath(mask) {
|
|
2186
|
+
return mask.paths[0];
|
|
2187
|
+
}
|
|
2188
|
+
function buildMaskForLayer(layer, layerItemId, layerComponentId, collector, processedItems, ratio, width, height, frameRate, lookup, maskSlotMeta, componentById, maskData) {
|
|
2189
|
+
var mask = maskData != null ? maskData : layer.mask;
|
|
2190
|
+
var maskItemId = createId();
|
|
2191
|
+
var maskComponentId = createId();
|
|
2192
|
+
var maskBounds = getMaskBounds(mask);
|
|
2193
|
+
var _getStaticAnchor = getStaticAnchor(layer), anchorX = _getStaticAnchor[0], anchorY = _getStaticAnchor[1];
|
|
2194
|
+
var maskPosX = roundNumber((maskBounds.cx - anchorX) * ratio, 4);
|
|
2195
|
+
var maskPosY = roundNumber(-(maskBounds.cy - anchorY) * ratio, 4);
|
|
2196
|
+
var timing = computeLayerTiming(layer, frameRate);
|
|
2197
|
+
var delay = timing.delay;
|
|
2198
|
+
var maskDuration = timing.layerDuration;
|
|
2199
|
+
var layerIsParent = lookup.isParentLayer(layer.index) || layer.type === 'null' || layer.type === 'precomp';
|
|
2200
|
+
var isAutoMask = mask.isAutoMask === true;
|
|
2201
|
+
var maskArea = maskBounds.width * maskBounds.height;
|
|
2202
|
+
if (layerIsParent) {
|
|
2203
|
+
var hasDescendants = hasClaimableRendererDescendants(collector.items, componentById, layerItemId, isAutoMask, maskArea, maskSlotMeta);
|
|
2204
|
+
if (!hasDescendants) {
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
var maskItem = {
|
|
2209
|
+
id: maskItemId,
|
|
2210
|
+
dataType: 'VFXItemData',
|
|
2211
|
+
name: "" + layer.name + "_mask",
|
|
2212
|
+
duration: maskDuration,
|
|
2213
|
+
type: 'shape',
|
|
2214
|
+
visible: true,
|
|
2215
|
+
endBehavior: 0,
|
|
2216
|
+
delay: roundNumber(delay, 4),
|
|
2217
|
+
renderLevel: 'B+',
|
|
2218
|
+
components: [
|
|
2219
|
+
toDataPath(maskComponentId)
|
|
2220
|
+
],
|
|
2221
|
+
transform: {
|
|
2222
|
+
position: {
|
|
2223
|
+
x: maskPosX,
|
|
2224
|
+
y: maskPosY,
|
|
2225
|
+
z: 0
|
|
2226
|
+
},
|
|
2227
|
+
eulerHint: {
|
|
2228
|
+
x: 0,
|
|
2229
|
+
y: 0,
|
|
2230
|
+
z: 0
|
|
2231
|
+
},
|
|
2232
|
+
anchor: {
|
|
2233
|
+
x: 0,
|
|
2234
|
+
y: 0
|
|
2235
|
+
},
|
|
2236
|
+
scale: {
|
|
2237
|
+
x: 1,
|
|
2238
|
+
y: 1,
|
|
2239
|
+
z: 1
|
|
2240
|
+
}
|
|
2241
|
+
},
|
|
2242
|
+
parentId: layerItemId
|
|
2243
|
+
};
|
|
2244
|
+
var maskComponent = isSimpleRectMask(mask) ? {
|
|
2245
|
+
id: maskComponentId,
|
|
2246
|
+
item: toDataPath(maskItemId),
|
|
2247
|
+
type: 1,
|
|
2248
|
+
dataType: 'ShapeComponent',
|
|
2249
|
+
width: roundNumber(maskBounds.width * ratio, 4),
|
|
2250
|
+
height: roundNumber(maskBounds.height * ratio, 4),
|
|
2251
|
+
roundness: 0,
|
|
2252
|
+
fills: [
|
|
2253
|
+
{
|
|
2254
|
+
type: 0,
|
|
2255
|
+
color: {
|
|
2256
|
+
r: 1,
|
|
2257
|
+
g: 1,
|
|
2258
|
+
b: 1,
|
|
2259
|
+
a: 0
|
|
2260
|
+
}
|
|
2261
|
+
}
|
|
2262
|
+
],
|
|
2263
|
+
strokes: [],
|
|
2264
|
+
strokeWidth: 0,
|
|
2265
|
+
strokeCap: 0,
|
|
2266
|
+
strokeJoin: 0,
|
|
2267
|
+
renderer: {
|
|
2268
|
+
renderMode: 1
|
|
2269
|
+
},
|
|
2270
|
+
mask: {
|
|
2271
|
+
isMask: true,
|
|
2272
|
+
alphaMaskEnabled: false
|
|
2273
|
+
}
|
|
2274
|
+
} : buildPolygonMaskComponent(maskComponentId, maskItemId, mask, maskBounds, ratio);
|
|
2275
|
+
collector.items.push(maskItem);
|
|
2276
|
+
collector.components.push(maskComponent);
|
|
2277
|
+
componentById.set(maskComponentId, maskComponent);
|
|
2278
|
+
if (layerIsParent) {
|
|
2279
|
+
applyMaskReferenceToDescendants(collector.items, componentById, layerItemId, maskComponentId, isAutoMask, maskArea, maskSlotMeta);
|
|
2280
|
+
} else if (layerComponentId != null) {
|
|
2281
|
+
var targetComponent = componentById.get(layerComponentId);
|
|
2282
|
+
if (targetComponent != null) {
|
|
2283
|
+
targetComponent['mask'] = buildMaskRef(maskComponentId);
|
|
2284
|
+
maskSlotMeta.set(layerComponentId, {
|
|
2285
|
+
isAutoMask: isAutoMask,
|
|
2286
|
+
area: maskArea
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
var maskTrackId = buildTimelineTracks(collector, delay, maskDuration, 0, {}, 'shape');
|
|
2291
|
+
processedItems.push({
|
|
2292
|
+
itemId: maskItemId,
|
|
2293
|
+
objectBindingTrackId: maskTrackId,
|
|
2294
|
+
layerIndex: -1
|
|
2295
|
+
});
|
|
2296
|
+
}
|
|
2297
|
+
function buildMaskRef(maskComponentId) {
|
|
2298
|
+
return {
|
|
2299
|
+
isMask: false,
|
|
2300
|
+
reference: toDataPath(maskComponentId),
|
|
2301
|
+
inverted: false
|
|
2302
|
+
};
|
|
2303
|
+
}
|
|
2304
|
+
function applyMaskReferenceToDescendants(items, componentById, parentItemId, maskComponentId, isAutoMask, maskArea, maskSlotMeta) {
|
|
2305
|
+
function visit(targetParentId) {
|
|
2306
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(items), _step; !(_step = _iterator()).done;){
|
|
2307
|
+
var item = _step.value;
|
|
2308
|
+
if (item.parentId !== targetParentId) {
|
|
2309
|
+
continue;
|
|
2310
|
+
}
|
|
2311
|
+
if (item.type === 'shape' && item.name.endsWith('_mask')) {
|
|
2312
|
+
continue;
|
|
2313
|
+
}
|
|
2314
|
+
var componentRefs = item.components;
|
|
2315
|
+
if (componentRefs != null && componentRefs.length > 0) {
|
|
2316
|
+
var compRef = componentRefs[0];
|
|
2317
|
+
var component = componentById.get(compRef.id);
|
|
2318
|
+
if (component != null && component['renderer'] != null && shouldClaimMaskSlot(component['mask'] != null, maskSlotMeta.get(compRef.id), isAutoMask, maskArea)) {
|
|
2319
|
+
component['mask'] = buildMaskRef(maskComponentId);
|
|
2320
|
+
maskSlotMeta.set(compRef.id, {
|
|
2321
|
+
isAutoMask: isAutoMask,
|
|
2322
|
+
area: maskArea
|
|
2323
|
+
});
|
|
2324
|
+
}
|
|
2325
|
+
}
|
|
2326
|
+
visit(item.id);
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
visit(parentItemId);
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* Decide whether a propagating mask should take a renderer component's single
|
|
2333
|
+
* mask slot. Preserves the original arbitration: an empty slot is always taken;
|
|
2334
|
+
* an authored mask is never displaced; an auto mask yields to an authored mask
|
|
2335
|
+
* or to a tighter (smaller-area) auto mask.
|
|
2336
|
+
*/ function shouldClaimMaskSlot(hasExistingMask, existing, isAutoMask, maskArea) {
|
|
2337
|
+
if (!hasExistingMask) {
|
|
2338
|
+
return true;
|
|
2339
|
+
}
|
|
2340
|
+
if ((existing == null ? void 0 : existing.isAutoMask) !== true) {
|
|
2341
|
+
return false;
|
|
2342
|
+
}
|
|
2343
|
+
if (!isAutoMask) {
|
|
2344
|
+
return true;
|
|
2345
|
+
}
|
|
2346
|
+
return maskArea < existing.area;
|
|
2347
|
+
}
|
|
2348
|
+
function hasClaimableRendererDescendants(items, componentById, parentItemId, isCurrentAutoMask, currentMaskArea, maskSlotMeta) {
|
|
2349
|
+
function visit(targetParentId) {
|
|
2350
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(items), _step; !(_step = _iterator()).done;){
|
|
2351
|
+
var item = _step.value;
|
|
2352
|
+
if (item.parentId !== targetParentId) {
|
|
2353
|
+
continue;
|
|
2354
|
+
}
|
|
2355
|
+
var componentRefs = item.components;
|
|
2356
|
+
if (componentRefs != null && componentRefs.length > 0) {
|
|
2357
|
+
var compRef = componentRefs[0];
|
|
2358
|
+
var component = componentById.get(compRef.id);
|
|
2359
|
+
if (component != null && component['renderer'] != null && shouldClaimMaskSlot(component['mask'] != null, maskSlotMeta.get(compRef.id), isCurrentAutoMask, currentMaskArea)) {
|
|
2360
|
+
return true;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
if (visit(item.id)) {
|
|
2364
|
+
return true;
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
return false;
|
|
2368
|
+
}
|
|
2369
|
+
return visit(parentItemId);
|
|
2370
|
+
}
|
|
2371
|
+
function computePointBounds(points) {
|
|
2372
|
+
var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
2373
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(points), _step; !(_step = _iterator()).done;){
|
|
2374
|
+
var point = _step.value;
|
|
2375
|
+
minX = Math.min(minX, point.x);
|
|
2376
|
+
minY = Math.min(minY, point.y);
|
|
2377
|
+
maxX = Math.max(maxX, point.x);
|
|
2378
|
+
maxY = Math.max(maxY, point.y);
|
|
2379
|
+
}
|
|
2380
|
+
return {
|
|
2381
|
+
minX: minX,
|
|
2382
|
+
minY: minY,
|
|
2383
|
+
maxX: maxX,
|
|
2384
|
+
maxY: maxY
|
|
2385
|
+
};
|
|
2386
|
+
}
|
|
2387
|
+
function isMaskExactCrop(mask, layer, width, height, lookup) {
|
|
2388
|
+
var path = getPrimaryPath(mask);
|
|
2389
|
+
if (path == null || path.points.length === 0) {
|
|
2390
|
+
return true;
|
|
2391
|
+
}
|
|
2392
|
+
var _computePointBounds = computePointBounds(path.points), minX = _computePointBounds.minX, minY = _computePointBounds.minY, maxX = _computePointBounds.maxX, maxY = _computePointBounds.maxY;
|
|
2393
|
+
var maskW = maxX - minX;
|
|
2394
|
+
var maskH = maxY - minY;
|
|
2395
|
+
if (mask.isAutoMask === true) {
|
|
2396
|
+
if (Math.abs(maskW - width) < 1 && Math.abs(maskH - height) < 1) {
|
|
2397
|
+
return true;
|
|
2398
|
+
}
|
|
2399
|
+
}
|
|
2400
|
+
var layerIsParent = lookup.isParentLayer(layer.index) || layer.type === 'null' || layer.type === 'precomp';
|
|
2401
|
+
if (mask.isAutoMask !== true && layerIsParent && isSimpleRectMask(mask)) {
|
|
2402
|
+
var _layer_asset, _layer_asset1;
|
|
2403
|
+
var precompW = (_layer_asset = layer.asset) == null ? void 0 : _layer_asset.width;
|
|
2404
|
+
var precompH = (_layer_asset1 = layer.asset) == null ? void 0 : _layer_asset1.height;
|
|
2405
|
+
if (precompW != null && precompH != null && precompW > 0 && precompH > 0) {
|
|
2406
|
+
if (minX <= 0 && minY <= 0 && maxX >= precompW && maxY >= precompH) {
|
|
2407
|
+
return true;
|
|
2408
|
+
}
|
|
2409
|
+
}
|
|
2410
|
+
}
|
|
2411
|
+
return false;
|
|
2412
|
+
}
|
|
2413
|
+
function getMaskBounds(mask) {
|
|
2414
|
+
var path = getPrimaryPath(mask);
|
|
2415
|
+
if (path == null || path.points.length === 0) {
|
|
2416
|
+
return {
|
|
2417
|
+
cx: 0,
|
|
2418
|
+
cy: 0,
|
|
2419
|
+
width: 0,
|
|
2420
|
+
height: 0
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
var _computePointBounds = computePointBounds(path.points), minX = _computePointBounds.minX, minY = _computePointBounds.minY, maxX = _computePointBounds.maxX, maxY = _computePointBounds.maxY;
|
|
2424
|
+
return {
|
|
2425
|
+
cx: (minX + maxX) / 2,
|
|
2426
|
+
cy: (minY + maxY) / 2,
|
|
2427
|
+
width: maxX - minX,
|
|
2428
|
+
height: maxY - minY
|
|
2429
|
+
};
|
|
2430
|
+
}
|
|
2431
|
+
function isSimpleRectMask(mask) {
|
|
2432
|
+
var path = getPrimaryPath(mask);
|
|
2433
|
+
if (path == null) {
|
|
2434
|
+
return false;
|
|
2435
|
+
}
|
|
2436
|
+
return path.points.length === 4 && path.easingIns.every(function(e) {
|
|
2437
|
+
return Math.abs(e.x) < 0.01 && Math.abs(e.y) < 0.01;
|
|
2438
|
+
}) && path.easingOuts.every(function(e) {
|
|
2439
|
+
return Math.abs(e.x) < 0.01 && Math.abs(e.y) < 0.01;
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
function buildPolygonMaskComponent(maskComponentId, maskItemId, mask, bounds, ratio) {
|
|
2443
|
+
var _ref;
|
|
2444
|
+
var path = getPrimaryPath(mask);
|
|
2445
|
+
var customPoints = [];
|
|
2446
|
+
var customEasingIns = [];
|
|
2447
|
+
var customEasingOuts = [];
|
|
2448
|
+
var customIndexes = [];
|
|
2449
|
+
if (path != null) {
|
|
2450
|
+
for(var idx = 0; idx < path.points.length; idx++){
|
|
2451
|
+
var _ref1, _ref2, _ref3, _ref4;
|
|
2452
|
+
var pt = path.points[idx];
|
|
2453
|
+
var ei = path.easingIns[idx];
|
|
2454
|
+
var eo = path.easingOuts[idx];
|
|
2455
|
+
customPoints.push({
|
|
2456
|
+
x: roundNumber((pt.x - bounds.cx) * ratio, 4),
|
|
2457
|
+
y: roundNumber(-(pt.y - bounds.cy) * ratio, 4)
|
|
2458
|
+
});
|
|
2459
|
+
customEasingIns.push({
|
|
2460
|
+
x: roundNumber(((_ref1 = ei == null ? void 0 : ei.x) != null ? _ref1 : 0) * ratio, 4),
|
|
2461
|
+
y: roundNumber(-((_ref2 = ei == null ? void 0 : ei.y) != null ? _ref2 : 0) * ratio, 4)
|
|
2462
|
+
});
|
|
2463
|
+
customEasingOuts.push({
|
|
2464
|
+
x: roundNumber(((_ref3 = eo == null ? void 0 : eo.x) != null ? _ref3 : 0) * ratio, 4),
|
|
2465
|
+
y: roundNumber(-((_ref4 = eo == null ? void 0 : eo.y) != null ? _ref4 : 0) * ratio, 4)
|
|
2466
|
+
});
|
|
2467
|
+
customIndexes.push({
|
|
2468
|
+
point: idx,
|
|
2469
|
+
easingIn: idx,
|
|
2470
|
+
easingOut: idx
|
|
2471
|
+
});
|
|
2472
|
+
}
|
|
2473
|
+
}
|
|
2474
|
+
return {
|
|
2475
|
+
id: maskComponentId,
|
|
2476
|
+
item: toDataPath(maskItemId),
|
|
2477
|
+
type: 0,
|
|
2478
|
+
dataType: 'ShapeComponent',
|
|
2479
|
+
points: customPoints,
|
|
2480
|
+
easingIns: customEasingIns,
|
|
2481
|
+
easingOuts: customEasingOuts,
|
|
2482
|
+
shapes: [
|
|
2483
|
+
{
|
|
2484
|
+
close: (_ref = path == null ? void 0 : path.close) != null ? _ref : true,
|
|
2485
|
+
indexes: customIndexes
|
|
2486
|
+
}
|
|
2487
|
+
],
|
|
2488
|
+
fills: [
|
|
2489
|
+
{
|
|
2490
|
+
type: 0,
|
|
2491
|
+
color: {
|
|
2492
|
+
r: 1,
|
|
2493
|
+
g: 1,
|
|
2494
|
+
b: 1,
|
|
2495
|
+
a: 0
|
|
2496
|
+
}
|
|
2497
|
+
}
|
|
2498
|
+
],
|
|
2499
|
+
strokes: [],
|
|
2500
|
+
strokeWidth: 0,
|
|
2501
|
+
strokeCap: 0,
|
|
2502
|
+
strokeJoin: 0,
|
|
2503
|
+
renderer: {
|
|
2504
|
+
renderMode: 1
|
|
2505
|
+
},
|
|
2506
|
+
mask: {
|
|
2507
|
+
isMask: true,
|
|
2508
|
+
alphaMaskEnabled: false
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
/**
|
|
2514
|
+
* Remap GE mask references after ge2ir round-trip.
|
|
2515
|
+
*
|
|
2516
|
+
* ge2ir carries each masked component's raw `mask` object verbatim (via
|
|
2517
|
+
* `IRLayerNode.metadata.ge2ir.geMask`), but `mask.reference.id` still points at the
|
|
2518
|
+
* ORIGINAL (GE1) mask-source component id, which ir2ge has regenerated. This
|
|
2519
|
+
* pass rewrites every target's `reference.id` from the stale GE1 id to the
|
|
2520
|
+
* freshly-minted GE2 component id, using the `geComponentId → newId` map built
|
|
2521
|
+
* during the layer walk.
|
|
2522
|
+
*
|
|
2523
|
+
* Mirrors `applyParenting`: an IR-side reference (here the stale id stored in
|
|
2524
|
+
* data) → map → regenerated id → written in place. Mask SOURCE components have
|
|
2525
|
+
* no `reference` and are skipped. Dangling references (source not regenerated —
|
|
2526
|
+
* e.g. dropped by the null+sprite merger) have their `mask` removed so the GE
|
|
2527
|
+
* runtime doesn't choke on an id that resolves to nothing.
|
|
2528
|
+
*/ function applyGeMaskRemap(collector, geComponentIdToNewId) {
|
|
2529
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(collector.components), _step; !(_step = _iterator()).done;){
|
|
2530
|
+
var component = _step.value;
|
|
2531
|
+
var mask = component['mask'];
|
|
2532
|
+
if (mask == null) {
|
|
2533
|
+
continue;
|
|
2534
|
+
}
|
|
2535
|
+
var reference = mask['reference'];
|
|
2536
|
+
var oldId = reference == null ? void 0 : reference.id;
|
|
2537
|
+
if (oldId == null) {
|
|
2538
|
+
continue;
|
|
2539
|
+
}
|
|
2540
|
+
var newId = geComponentIdToNewId[oldId];
|
|
2541
|
+
if (newId == null) {
|
|
2542
|
+
// Dangling: the referenced source was not regenerated. Drop the mask so
|
|
2543
|
+
// the target renders unmasked rather than referencing a nonexistent id.
|
|
2544
|
+
delete component['mask'];
|
|
2545
|
+
continue;
|
|
2546
|
+
}
|
|
2547
|
+
mask['reference'] = toDataPath(newId);
|
|
2548
|
+
}
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
/**
|
|
2552
|
+
* Normalize child visibility delays so children never appear before their parent.
|
|
2553
|
+
*
|
|
2554
|
+
* Topologically sorts items (parent-first) so by the time we process any child
|
|
2555
|
+
* its parent's delay/duration are already finalized. For transform-only
|
|
2556
|
+
* parent-link children, we instead advance the parent's delay/duration so the
|
|
2557
|
+
* child can render from its own start time (GE requires the parent to be active
|
|
2558
|
+
* for transform inheritance, but the parent-link relationship does not propagate
|
|
2559
|
+
* visibility). Only the ActivationTrack clip is updated; TransformTrack
|
|
2560
|
+
* keyframes are normalized to the original time range and would hold their
|
|
2561
|
+
* first frame value if the track started earlier.
|
|
2562
|
+
*/ function normalizeChildVisibilityByParentDelays(param) {
|
|
2563
|
+
var items = param.items, miscs = param.miscs, processedItems = param.processedItems, _param_transformOnlyParentLinkItemIds = param.transformOnlyParentLinkItemIds, transformOnlyParentLinkItemIds = _param_transformOnlyParentLinkItemIds === void 0 ? new Set() : _param_transformOnlyParentLinkItemIds, roundNumber = param.roundNumber;
|
|
2564
|
+
var itemById = new Map();
|
|
2565
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(items), _step; !(_step = _iterator()).done;){
|
|
2566
|
+
var item = _step.value;
|
|
2567
|
+
itemById.set(item['id'], item);
|
|
2568
|
+
}
|
|
2569
|
+
var processedByItemId = new Map();
|
|
2570
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(processedItems), _step1; !(_step1 = _iterator1()).done;){
|
|
2571
|
+
var pi = _step1.value;
|
|
2572
|
+
processedByItemId.set(pi.itemId, pi);
|
|
2573
|
+
}
|
|
2574
|
+
var miscById = new Map();
|
|
2575
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(miscs), _step2; !(_step2 = _iterator2()).done;){
|
|
2576
|
+
var misc = _step2.value;
|
|
2577
|
+
miscById.set(misc['id'], misc);
|
|
2578
|
+
}
|
|
2579
|
+
// Phase 1: Advance transform-only parent-link parents so their children can
|
|
2580
|
+
// render from the child's own start time.
|
|
2581
|
+
advanceTransformOnlyParentLinkParents(items, itemById, processedByItemId, miscById, transformOnlyParentLinkItemIds, roundNumber);
|
|
2582
|
+
// Phase 2: Normalize precomp child visibility (unchanged).
|
|
2583
|
+
var effectiveDelayCache = new Map();
|
|
2584
|
+
function getEffectiveDelay(itemId, visited) {
|
|
2585
|
+
if (visited === void 0) visited = new Set();
|
|
2586
|
+
var _item_delay;
|
|
2587
|
+
if (effectiveDelayCache.has(itemId)) {
|
|
2588
|
+
return effectiveDelayCache.get(itemId);
|
|
2589
|
+
}
|
|
2590
|
+
if (visited.has(itemId)) {
|
|
2591
|
+
return 0;
|
|
2592
|
+
}
|
|
2593
|
+
visited.add(itemId);
|
|
2594
|
+
var item = itemById.get(itemId);
|
|
2595
|
+
if (item == null) {
|
|
2596
|
+
return 0;
|
|
2597
|
+
}
|
|
2598
|
+
var delay = (_item_delay = item['delay']) != null ? _item_delay : 0;
|
|
2599
|
+
var parentId = item['parentId'];
|
|
2600
|
+
if (parentId != null && parentId !== '') {
|
|
2601
|
+
delay = Math.max(delay, getEffectiveDelay(parentId, visited));
|
|
2602
|
+
}
|
|
2603
|
+
effectiveDelayCache.set(itemId, delay);
|
|
2604
|
+
return delay;
|
|
2605
|
+
}
|
|
2606
|
+
// Build topological order (parent-first) so that when processing any child,
|
|
2607
|
+
// its parent's delay/duration are already finalized.
|
|
2608
|
+
var sortedItems = topologicalSort(items, itemById);
|
|
2609
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(sortedItems), _step3; !(_step3 = _iterator3()).done;){
|
|
2610
|
+
var item1 = _step3.value;
|
|
2611
|
+
var _item_delay, _item_duration, _parentItem_duration;
|
|
2612
|
+
var itemId = item1['id'];
|
|
2613
|
+
var originalDelay = (_item_delay = item1['delay']) != null ? _item_delay : 0;
|
|
2614
|
+
var originalDuration = (_item_duration = item1['duration']) != null ? _item_duration : 0;
|
|
2615
|
+
var effectiveDelay = getEffectiveDelay(itemId);
|
|
2616
|
+
if (effectiveDelay <= originalDelay) {
|
|
2617
|
+
continue;
|
|
2618
|
+
}
|
|
2619
|
+
var parentId = item1['parentId'];
|
|
2620
|
+
var parentItem = parentId != null && parentId !== '' ? itemById.get(parentId) : undefined;
|
|
2621
|
+
var parentDuration = parentItem ? (_parentItem_duration = parentItem['duration']) != null ? _parentItem_duration : 0 : 0;
|
|
2622
|
+
// Distinguish time-contained children from global-time parent-link children:
|
|
2623
|
+
// Precomp children live entirely within the parent's time range (delay + duration <= parentDuration).
|
|
2624
|
+
// Parent-link children share the global time coordinate with their parent.
|
|
2625
|
+
var isPrecompChild = parentItem != null && originalDelay + originalDuration <= parentDuration + 0.001;
|
|
2626
|
+
var newDuration = void 0;
|
|
2627
|
+
if (isPrecompChild) {
|
|
2628
|
+
// Precomp child: keep duration unchanged (clamped to parent boundary).
|
|
2629
|
+
newDuration = Math.min(originalDuration, parentDuration - originalDelay);
|
|
2630
|
+
} else {
|
|
2631
|
+
// Parent-link child: trim the invisible portion before effectiveDelay.
|
|
2632
|
+
var timeDiff = effectiveDelay - originalDelay;
|
|
2633
|
+
newDuration = originalDuration - timeDiff;
|
|
2634
|
+
}
|
|
2635
|
+
if (newDuration <= 0) {
|
|
2636
|
+
newDuration = 0.0001;
|
|
2637
|
+
}
|
|
2638
|
+
item1['delay'] = roundNumber(effectiveDelay, 4);
|
|
2639
|
+
item1['duration'] = roundNumber(newDuration, 4);
|
|
2640
|
+
syncTimelineClips(itemId, effectiveDelay, newDuration, processedByItemId, miscById, roundNumber);
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
function advanceTransformOnlyParentLinkParents(items, itemById, processedByItemId, miscById, transformOnlyParentLinkItemIds, roundNumber) {
|
|
2644
|
+
if (transformOnlyParentLinkItemIds.size === 0) {
|
|
2645
|
+
return;
|
|
2646
|
+
}
|
|
2647
|
+
// Collect the maximum advance (head) and extension (tail) needed per parent.
|
|
2648
|
+
var parentAdvanceMap = new Map();
|
|
2649
|
+
var parentExtendMap = new Map();
|
|
2650
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(items), _step; !(_step = _iterator()).done;){
|
|
2651
|
+
var item = _step.value;
|
|
2652
|
+
var _item_delay, _item_duration, _parentItem_delay, _parentItem_duration;
|
|
2653
|
+
if (!transformOnlyParentLinkItemIds.has(item['id'])) {
|
|
2654
|
+
continue;
|
|
2655
|
+
}
|
|
2656
|
+
var parentId = item['parentId'];
|
|
2657
|
+
if (parentId == null || parentId === '') {
|
|
2658
|
+
continue;
|
|
2659
|
+
}
|
|
2660
|
+
var parentItem = itemById.get(parentId);
|
|
2661
|
+
if (parentItem == null) {
|
|
2662
|
+
continue;
|
|
2663
|
+
}
|
|
2664
|
+
var childDelay = (_item_delay = item['delay']) != null ? _item_delay : 0;
|
|
2665
|
+
var childDuration = (_item_duration = item['duration']) != null ? _item_duration : 0;
|
|
2666
|
+
var parentDelay = (_parentItem_delay = parentItem['delay']) != null ? _parentItem_delay : 0;
|
|
2667
|
+
var parentDuration = (_parentItem_duration = parentItem['duration']) != null ? _parentItem_duration : 0;
|
|
2668
|
+
if (childDelay < parentDelay) {
|
|
2669
|
+
var _parentAdvanceMap_get;
|
|
2670
|
+
var advance = parentDelay - childDelay;
|
|
2671
|
+
var existing = (_parentAdvanceMap_get = parentAdvanceMap.get(parentId)) != null ? _parentAdvanceMap_get : 0;
|
|
2672
|
+
if (advance > existing) {
|
|
2673
|
+
parentAdvanceMap.set(parentId, advance);
|
|
2674
|
+
}
|
|
2675
|
+
}
|
|
2676
|
+
var childEnd = childDelay + childDuration;
|
|
2677
|
+
var parentEnd = parentDelay + parentDuration;
|
|
2678
|
+
if (childEnd > parentEnd + 0.001) {
|
|
2679
|
+
var _parentExtendMap_get;
|
|
2680
|
+
var extend = childEnd - parentEnd;
|
|
2681
|
+
var existing1 = (_parentExtendMap_get = parentExtendMap.get(parentId)) != null ? _parentExtendMap_get : 0;
|
|
2682
|
+
if (extend > existing1) {
|
|
2683
|
+
parentExtendMap.set(parentId, extend);
|
|
2684
|
+
}
|
|
2685
|
+
}
|
|
2686
|
+
}
|
|
2687
|
+
// Merge all parent IDs that need adjustment.
|
|
2688
|
+
var allParentIds = new Set([].concat(parentAdvanceMap.keys(), parentExtendMap.keys()));
|
|
2689
|
+
// Apply adjustments: update parent item delay/duration and sync ActivationTrack clips.
|
|
2690
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(allParentIds), _step1; !(_step1 = _iterator1()).done;){
|
|
2691
|
+
var parentId1 = _step1.value;
|
|
2692
|
+
var _parentAdvanceMap_get1, _parentExtendMap_get1, _parentItem_delay1, _parentItem_duration1;
|
|
2693
|
+
var parentItem1 = itemById.get(parentId1);
|
|
2694
|
+
if (parentItem1 == null) {
|
|
2695
|
+
continue;
|
|
2696
|
+
}
|
|
2697
|
+
var advance1 = (_parentAdvanceMap_get1 = parentAdvanceMap.get(parentId1)) != null ? _parentAdvanceMap_get1 : 0;
|
|
2698
|
+
var extend1 = (_parentExtendMap_get1 = parentExtendMap.get(parentId1)) != null ? _parentExtendMap_get1 : 0;
|
|
2699
|
+
var parentDelay1 = (_parentItem_delay1 = parentItem1['delay']) != null ? _parentItem_delay1 : 0;
|
|
2700
|
+
var parentDuration1 = (_parentItem_duration1 = parentItem1['duration']) != null ? _parentItem_duration1 : 0;
|
|
2701
|
+
var newDelay = roundNumber(parentDelay1 - advance1, 4);
|
|
2702
|
+
var newDuration = roundNumber(parentDuration1 + advance1 + extend1, 4);
|
|
2703
|
+
parentItem1['delay'] = newDelay;
|
|
2704
|
+
parentItem1['duration'] = newDuration;
|
|
2705
|
+
// Only sync ActivationTrack — TransformTrack keyframes are normalized to
|
|
2706
|
+
// the original time range and will hold their last frame value when the
|
|
2707
|
+
// track extends beyond the original duration.
|
|
2708
|
+
var processed = processedByItemId.get(parentId1);
|
|
2709
|
+
if (processed != null) {
|
|
2710
|
+
var obt = miscById.get(processed.objectBindingTrackId);
|
|
2711
|
+
if (obt != null && Array.isArray(obt['children'])) {
|
|
2712
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(obt['children']), _step2; !(_step2 = _iterator2()).done;){
|
|
2713
|
+
var childRef = _step2.value;
|
|
2714
|
+
var childTrack = miscById.get(childRef.id);
|
|
2715
|
+
if ((childTrack == null ? void 0 : childTrack['dataType']) === 'ActivationTrack' && Array.isArray(childTrack['clips'])) {
|
|
2716
|
+
for(var _iterator3 = _create_for_of_iterator_helper_loose(childTrack['clips']), _step3; !(_step3 = _iterator3()).done;){
|
|
2717
|
+
var clip = _step3.value;
|
|
2718
|
+
clip.start = newDelay;
|
|
2719
|
+
clip.duration = newDuration;
|
|
2720
|
+
}
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
}
|
|
2726
|
+
}
|
|
2727
|
+
/**
|
|
2728
|
+
* Topological sort: parents are processed before their children.
|
|
2729
|
+
* Falls back to original order for items without parent relationships.
|
|
2730
|
+
*/ function topologicalSort(items, itemById) {
|
|
2731
|
+
var sorted = [];
|
|
2732
|
+
var visited = new Set();
|
|
2733
|
+
function visit(item) {
|
|
2734
|
+
var itemId = item['id'];
|
|
2735
|
+
if (visited.has(itemId)) {
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
visited.add(itemId);
|
|
2739
|
+
var parentId = item['parentId'];
|
|
2740
|
+
if (parentId != null && parentId !== '') {
|
|
2741
|
+
var parentItem = itemById.get(parentId);
|
|
2742
|
+
if (parentItem != null) {
|
|
2743
|
+
visit(parentItem);
|
|
2744
|
+
}
|
|
2745
|
+
}
|
|
2746
|
+
sorted.push(item);
|
|
2747
|
+
}
|
|
2748
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(items), _step; !(_step = _iterator()).done;){
|
|
2749
|
+
var item = _step.value;
|
|
2750
|
+
visit(item);
|
|
2751
|
+
}
|
|
2752
|
+
return sorted;
|
|
2753
|
+
}
|
|
2754
|
+
function syncTimelineClips(itemId, delay, duration, processedByItemId, miscById, roundNumber) {
|
|
2755
|
+
var processedItem = processedByItemId.get(itemId);
|
|
2756
|
+
if (processedItem == null) {
|
|
2757
|
+
return;
|
|
2758
|
+
}
|
|
2759
|
+
var obt = miscById.get(processedItem.objectBindingTrackId);
|
|
2760
|
+
if (obt == null || !Array.isArray(obt['children'])) {
|
|
2761
|
+
return;
|
|
2762
|
+
}
|
|
2763
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(obt['children']), _step; !(_step = _iterator()).done;){
|
|
2764
|
+
var childRef = _step.value;
|
|
2765
|
+
var childTrack = miscById.get(childRef.id);
|
|
2766
|
+
if (childTrack == null || !Array.isArray(childTrack['clips'])) {
|
|
2767
|
+
continue;
|
|
2768
|
+
}
|
|
2769
|
+
var trackType = childTrack['dataType'];
|
|
2770
|
+
if (trackType !== 'ActivationTrack' && trackType !== 'TransformTrack' && trackType !== 'SpriteColorTrack') {
|
|
2771
|
+
continue;
|
|
2772
|
+
}
|
|
2773
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(childTrack['clips']), _step1; !(_step1 = _iterator1()).done;){
|
|
2774
|
+
var clip = _step1.value;
|
|
2775
|
+
clip.start = roundNumber(delay, 4);
|
|
2776
|
+
clip.duration = roundNumber(duration, 4);
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
|
|
2781
|
+
/**
|
|
2782
|
+
* Run post-emit mutations on the collector before `assembleScene`.
|
|
2783
|
+
* Order: parenting → mask → visibility. Each step is gated on whether
|
|
2784
|
+
* the pipeline supplied the required tracking state.
|
|
2785
|
+
*/ function applyPostProcess(ir, state) {
|
|
2786
|
+
applyParentingStep(ir, state);
|
|
2787
|
+
applySharedMaskPostProcess(ir, state);
|
|
2788
|
+
applyGeMaskRemapStep(ir, state);
|
|
2789
|
+
applyVisibilityStep(ir, state);
|
|
2790
|
+
}
|
|
2791
|
+
function applyGeMaskRemapStep(ir, state) {
|
|
2792
|
+
// Only ge-sourced compositions carry passthrough mask references that need
|
|
2793
|
+
// remapping. Lottie/dsl masks are built with correct ids by applyMasks and
|
|
2794
|
+
// must not be touched (their reference ids are absent from the ge map, so a
|
|
2795
|
+
// blind remap would wrongly delete them).
|
|
2796
|
+
if (ir.source !== 'ge' || state.geComponentIdToNewId == null) {
|
|
2797
|
+
return;
|
|
2798
|
+
}
|
|
2799
|
+
applyGeMaskRemap(state.collector, state.geComponentIdToNewId);
|
|
2800
|
+
}
|
|
2801
|
+
function applySharedMaskPostProcess(ir, state) {
|
|
2802
|
+
if (state.maskLookup == null || state.ratio == null || state.width == null || state.height == null || state.frameRate == null) {
|
|
2803
|
+
return;
|
|
2804
|
+
}
|
|
2805
|
+
applyMasks(ir, state.collector, state.processedItems, state.ratio, state.width, state.height, state.frameRate, state.maskLookup);
|
|
2806
|
+
}
|
|
2807
|
+
function applyParentingStep(ir, state) {
|
|
2808
|
+
var collector = state.collector, layerToItemId = state.layerToItemId, ratio = state.ratio, width = state.width, height = state.height;
|
|
2809
|
+
if (layerToItemId == null || ratio == null || width == null || height == null) {
|
|
2810
|
+
return;
|
|
2811
|
+
}
|
|
2812
|
+
applyParenting(ir.layers, collector.items, layerToItemId, ratio, width, height);
|
|
2813
|
+
}
|
|
2814
|
+
function applyVisibilityStep(ir, state) {
|
|
2815
|
+
var collector = state.collector, processedItems = state.processedItems, layerToItemId = state.layerToItemId;
|
|
2816
|
+
if (layerToItemId == null) {
|
|
2817
|
+
return;
|
|
2818
|
+
}
|
|
2819
|
+
var transformOnlyParentLinkItemIds = new Set();
|
|
2820
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(ir.layers), _step; !(_step = _iterator()).done;){
|
|
2821
|
+
var layer = _step.value;
|
|
2822
|
+
if (isTransformOnlyParentLink(layer)) {
|
|
2823
|
+
var itemId = layerToItemId[layer.index];
|
|
2824
|
+
if (itemId != null) {
|
|
2825
|
+
transformOnlyParentLinkItemIds.add(itemId);
|
|
2826
|
+
}
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
normalizeChildVisibilityByParentDelays({
|
|
2830
|
+
items: collector.items,
|
|
2831
|
+
miscs: collector.miscs,
|
|
2832
|
+
processedItems: processedItems,
|
|
2833
|
+
transformOnlyParentLinkItemIds: transformOnlyParentLinkItemIds,
|
|
2834
|
+
roundNumber: roundNumber
|
|
2835
|
+
});
|
|
2836
|
+
}
|
|
2837
|
+
|
|
2838
|
+
/**
|
|
2839
|
+
* Convert an IR composition to a GE JSONScene.
|
|
2840
|
+
*
|
|
2841
|
+
* All IR sources (lottie, dsl2ge, future) go through this single unified
|
|
2842
|
+
* pipeline. Source-specific features are gated by data existence (e.g. mask,
|
|
2843
|
+
* precomp, shape layers are absent in dsl IR and naturally skipped);
|
|
2844
|
+
* `ir.source` branches are used only for B-class real semantic differences
|
|
2845
|
+
* that cannot be expressed via data existence.
|
|
2846
|
+
*
|
|
2847
|
+
* The optional `duration` arg is a caller override; lottie2ge currently passes
|
|
2848
|
+
* the duration computed from the raw json upstream. When omitted, the
|
|
2849
|
+
* canonical assembler derives it from `(outPoint - inPoint) / frameRate`.
|
|
2850
|
+
*/ function convertIRToGE(ir, duration) {
|
|
2851
|
+
validateIRCompositionWithWarnings(ir);
|
|
2852
|
+
var width = ir.width, height = ir.height, frameRate = ir.frameRate;
|
|
2853
|
+
var ratio = get2dTo3dRatio(width, height);
|
|
2854
|
+
var collector = {
|
|
2855
|
+
images: [],
|
|
2856
|
+
components: [],
|
|
2857
|
+
items: [],
|
|
2858
|
+
textures: [],
|
|
2859
|
+
miscs: []
|
|
2860
|
+
};
|
|
2861
|
+
var processedItems = [];
|
|
2862
|
+
var layerToItemId = {};
|
|
2863
|
+
var layerToComponentId = {};
|
|
2864
|
+
var textureCache = new Map();
|
|
2865
|
+
var parentIndexSet = new Set();
|
|
2866
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(ir.layers), _step; !(_step = _iterator()).done;){
|
|
2867
|
+
var layer = _step.value;
|
|
2868
|
+
if (layer.parent != null) {
|
|
2869
|
+
parentIndexSet.add(layer.parent.index);
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
var workingIR = _extends({}, ir, {
|
|
2873
|
+
layers: getLayersWithExtendedParentEndFrames(ir.layers, parentIndexSet)
|
|
2874
|
+
});
|
|
2875
|
+
var ctx = {
|
|
2876
|
+
ir: workingIR,
|
|
2877
|
+
collector: collector,
|
|
2878
|
+
processedItems: processedItems,
|
|
2879
|
+
layerToItemId: layerToItemId,
|
|
2880
|
+
layerToComponentId: layerToComponentId,
|
|
2881
|
+
textureCache: textureCache,
|
|
2882
|
+
parentIndexSet: parentIndexSet,
|
|
2883
|
+
ratio: ratio,
|
|
2884
|
+
width: width,
|
|
2885
|
+
height: height,
|
|
2886
|
+
frameRate: frameRate
|
|
2887
|
+
};
|
|
2888
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(workingIR.layers), _step1; !(_step1 = _iterator1()).done;){
|
|
2889
|
+
var layer1 = _step1.value;
|
|
2890
|
+
processLayer(layer1, ctx);
|
|
2891
|
+
}
|
|
2892
|
+
// Build GE1-component-id → regenerated-component-id map for mask reference
|
|
2893
|
+
// remapping (ge2ir round-trip). Keyed by the original GE component id that
|
|
2894
|
+
// ge2ir stored in metadata; value is the component id this layer minted.
|
|
2895
|
+
var geComponentIdToNewId = {};
|
|
2896
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(workingIR.layers), _step2; !(_step2 = _iterator2()).done;){
|
|
2897
|
+
var layer2 = _step2.value;
|
|
2898
|
+
var _readGE2IRMetadata;
|
|
2899
|
+
var geComponentId = (_readGE2IRMetadata = readGE2IRMetadata(workingIR, layer2)) == null ? void 0 : _readGE2IRMetadata.geComponentId;
|
|
2900
|
+
var newId = layerToComponentId[layer2.index];
|
|
2901
|
+
if (geComponentId != null && newId != null) {
|
|
2902
|
+
geComponentIdToNewId[geComponentId] = newId;
|
|
2903
|
+
}
|
|
2904
|
+
}
|
|
2905
|
+
applyPostProcess(workingIR, {
|
|
2906
|
+
collector: collector,
|
|
2907
|
+
processedItems: processedItems,
|
|
2908
|
+
layerToItemId: layerToItemId,
|
|
2909
|
+
ratio: ratio,
|
|
2910
|
+
width: width,
|
|
2911
|
+
height: height,
|
|
2912
|
+
frameRate: frameRate,
|
|
2913
|
+
geComponentIdToNewId: geComponentIdToNewId,
|
|
2914
|
+
maskLookup: {
|
|
2915
|
+
getItemId: function getItemId(idx) {
|
|
2916
|
+
return layerToItemId[idx];
|
|
2917
|
+
},
|
|
2918
|
+
getComponentId: function getComponentId(idx) {
|
|
2919
|
+
return layerToComponentId[idx];
|
|
2920
|
+
},
|
|
2921
|
+
isParentLayer: function isParentLayer(idx) {
|
|
2922
|
+
return parentIndexSet.has(idx);
|
|
2923
|
+
}
|
|
2924
|
+
}
|
|
2925
|
+
});
|
|
2926
|
+
collector.items.reverse();
|
|
2927
|
+
processedItems.reverse();
|
|
2928
|
+
return assembleScene(workingIR, collector, processedItems, duration);
|
|
2929
|
+
}
|
|
2930
|
+
function processLayer(layer, ctx) {
|
|
2931
|
+
if (layer.type === 'null' || layer.type === 'precomp') {
|
|
2932
|
+
processNullLayer(layer, ctx);
|
|
2933
|
+
} else if (ctx.parentIndexSet.has(layer.index)) {
|
|
2934
|
+
processParentLayer(layer, ctx);
|
|
2935
|
+
} else {
|
|
2936
|
+
processVisualLayer(layer, ctx);
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
/**
|
|
2940
|
+
* Extend parent layers' endFrame to cover transform-only children's time spans.
|
|
2941
|
+
*
|
|
2942
|
+
* In Lottie, child layers (linked via layer.parent) inherit the parent's transform
|
|
2943
|
+
* even after the parent becomes invisible. GE requires the parent item to be active
|
|
2944
|
+
* for transform inheritance to work, so we extend the parent's endFrame to cover
|
|
2945
|
+
* the full lifetime of its transform-only children.
|
|
2946
|
+
*
|
|
2947
|
+
* Keyframes beyond the extended endFrame are NOT included — they represent animation
|
|
2948
|
+
* that never plays in Lottie (layer is invisible and has no child needing it).
|
|
2949
|
+
*/ function getLayersWithExtendedParentEndFrames(layers, parentIndexSet) {
|
|
2950
|
+
var clonedLayers = layers.map(function(layer) {
|
|
2951
|
+
return _extends({}, layer, {
|
|
2952
|
+
time: _extends({}, layer.time)
|
|
2953
|
+
});
|
|
2954
|
+
});
|
|
2955
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(clonedLayers), _step; !(_step = _iterator()).done;){
|
|
2956
|
+
var layer = _step.value;
|
|
2957
|
+
if (!parentIndexSet.has(layer.index)) {
|
|
2958
|
+
continue;
|
|
2959
|
+
}
|
|
2960
|
+
var maxEnd = layer.time.endFrame;
|
|
2961
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(clonedLayers), _step1; !(_step1 = _iterator1()).done;){
|
|
2962
|
+
var child = _step1.value;
|
|
2963
|
+
var _child_parent;
|
|
2964
|
+
if (((_child_parent = child.parent) == null ? void 0 : _child_parent.index) === layer.index && child.parent.linkKind === 'transform-only') {
|
|
2965
|
+
if (child.time.endFrame > maxEnd) {
|
|
2966
|
+
maxEnd = child.time.endFrame;
|
|
2967
|
+
}
|
|
2968
|
+
}
|
|
2969
|
+
}
|
|
2970
|
+
if (maxEnd > layer.time.endFrame) {
|
|
2971
|
+
layer.time.endFrame = maxEnd;
|
|
2972
|
+
}
|
|
2973
|
+
}
|
|
2974
|
+
return clonedLayers;
|
|
2975
|
+
}
|
|
2976
|
+
|
|
2977
|
+
function buildPoolIndex(pool) {
|
|
2978
|
+
var map = new Map();
|
|
2979
|
+
if (!Array.isArray(pool)) {
|
|
2980
|
+
return map;
|
|
2981
|
+
}
|
|
2982
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(pool), _step; !(_step = _iterator()).done;){
|
|
2983
|
+
var entry = _step.value;
|
|
2984
|
+
var id = entry['id'];
|
|
2985
|
+
if (typeof id === 'string') {
|
|
2986
|
+
map.set(id, entry);
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
return map;
|
|
2990
|
+
}
|
|
2991
|
+
function resolveDataPath(pool, ref) {
|
|
2992
|
+
if (ref == null || (typeof ref === "undefined" ? "undefined" : _type_of(ref)) !== 'object') {
|
|
2993
|
+
return undefined;
|
|
2994
|
+
}
|
|
2995
|
+
var id = ref['id'];
|
|
2996
|
+
if (typeof id !== 'string') {
|
|
2997
|
+
return undefined;
|
|
2998
|
+
}
|
|
2999
|
+
return pool.get(id);
|
|
3000
|
+
}
|
|
3001
|
+
function resolveDataPathId(ref) {
|
|
3002
|
+
if (ref == null || (typeof ref === "undefined" ? "undefined" : _type_of(ref)) !== 'object') {
|
|
3003
|
+
return undefined;
|
|
3004
|
+
}
|
|
3005
|
+
var id = ref['id'];
|
|
3006
|
+
return typeof id === 'string' ? id : undefined;
|
|
3007
|
+
}
|
|
3008
|
+
|
|
3009
|
+
function reverseEndBehavior(geBehavior) {
|
|
3010
|
+
if (geBehavior == null) {
|
|
3011
|
+
return undefined;
|
|
3012
|
+
}
|
|
3013
|
+
switch(geBehavior){
|
|
3014
|
+
case 0:
|
|
3015
|
+
return IREndBehavior.Stop;
|
|
3016
|
+
case 4:
|
|
3017
|
+
return IREndBehavior.Hold;
|
|
3018
|
+
case 5:
|
|
3019
|
+
return IREndBehavior.Loop;
|
|
3020
|
+
default:
|
|
3021
|
+
return undefined;
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
function reverseCompositionEndBehavior(geBehavior) {
|
|
3025
|
+
return reverseEndBehavior(geBehavior);
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
function buildSceneContext(scene, options) {
|
|
3029
|
+
var _ref, _ref1, _composition_duration, _composition_name;
|
|
3030
|
+
var compositionId = scene['compositionId'];
|
|
3031
|
+
var compositions = scene['compositions'];
|
|
3032
|
+
var composition = compositions == null ? void 0 : compositions.find(function(c) {
|
|
3033
|
+
return c['id'] === compositionId;
|
|
3034
|
+
});
|
|
3035
|
+
if (composition == null) {
|
|
3036
|
+
throw new Error("[ge2ir] composition not found for id: " + compositionId);
|
|
3037
|
+
}
|
|
3038
|
+
var previewSize = composition['previewSize'];
|
|
3039
|
+
var width = (_ref = previewSize == null ? void 0 : previewSize[0]) != null ? _ref : 512;
|
|
3040
|
+
var height = (_ref1 = previewSize == null ? void 0 : previewSize[1]) != null ? _ref1 : 512;
|
|
3041
|
+
var duration = (_composition_duration = composition['duration']) != null ? _composition_duration : 1;
|
|
3042
|
+
var frameRate = options.frameRate;
|
|
3043
|
+
var ratio = get2dTo3dRatio(width, height);
|
|
3044
|
+
var inPoint = 0;
|
|
3045
|
+
var outPoint = Math.round(duration * frameRate);
|
|
3046
|
+
var endBehavior = reverseCompositionEndBehavior(composition['endBehavior']);
|
|
3047
|
+
var backgroundColor;
|
|
3048
|
+
var bg = composition['background'];
|
|
3049
|
+
if (bg != null) {
|
|
3050
|
+
var color = bg['color'];
|
|
3051
|
+
if (color != null && color.length >= 4) {
|
|
3052
|
+
backgroundColor = [
|
|
3053
|
+
color[0],
|
|
3054
|
+
color[1],
|
|
3055
|
+
color[2],
|
|
3056
|
+
color[3]
|
|
3057
|
+
];
|
|
3058
|
+
}
|
|
3059
|
+
}
|
|
3060
|
+
var compositionName = (_composition_name = composition['name']) != null ? _composition_name : 'Untitled';
|
|
3061
|
+
var items = scene['items'];
|
|
3062
|
+
var components = scene['components'];
|
|
3063
|
+
var miscs = scene['miscs'];
|
|
3064
|
+
var images = scene['images'];
|
|
3065
|
+
var textures = scene['textures'];
|
|
3066
|
+
var itemById = buildPoolIndex(items);
|
|
3067
|
+
var componentById = buildPoolIndex(components);
|
|
3068
|
+
var miscById = buildPoolIndex(miscs);
|
|
3069
|
+
var imageById = buildPoolIndex(images);
|
|
3070
|
+
var textureById = buildPoolIndex(textures);
|
|
3071
|
+
var itemIdToTrackId = buildSceneBindings(componentById, miscById, composition);
|
|
3072
|
+
return {
|
|
3073
|
+
width: width,
|
|
3074
|
+
height: height,
|
|
3075
|
+
frameRate: frameRate,
|
|
3076
|
+
ratio: ratio,
|
|
3077
|
+
duration: duration,
|
|
3078
|
+
inPoint: inPoint,
|
|
3079
|
+
outPoint: outPoint,
|
|
3080
|
+
compositionName: compositionName,
|
|
3081
|
+
endBehavior: endBehavior,
|
|
3082
|
+
backgroundColor: backgroundColor,
|
|
3083
|
+
itemById: itemById,
|
|
3084
|
+
componentById: componentById,
|
|
3085
|
+
miscById: miscById,
|
|
3086
|
+
imageById: imageById,
|
|
3087
|
+
textureById: textureById,
|
|
3088
|
+
itemIdToTrackId: itemIdToTrackId
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
function buildSceneBindings(componentById, miscById, composition) {
|
|
3092
|
+
var map = new Map();
|
|
3093
|
+
var compositionComponent = findCompositionComponent(componentById, composition);
|
|
3094
|
+
if (compositionComponent == null) {
|
|
3095
|
+
return map;
|
|
3096
|
+
}
|
|
3097
|
+
var bindings = compositionComponent['sceneBindings'];
|
|
3098
|
+
if (bindings == null) {
|
|
3099
|
+
return map;
|
|
3100
|
+
}
|
|
3101
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(bindings), _step; !(_step = _iterator()).done;){
|
|
3102
|
+
var binding = _step.value;
|
|
3103
|
+
var trackId = resolveDataPathId(binding.key);
|
|
3104
|
+
var itemId = resolveDataPathId(binding.value);
|
|
3105
|
+
if (trackId != null && itemId != null) {
|
|
3106
|
+
map.set(itemId, trackId);
|
|
3107
|
+
}
|
|
3108
|
+
}
|
|
3109
|
+
return map;
|
|
3110
|
+
}
|
|
3111
|
+
function findCompositionComponent(componentById, composition) {
|
|
3112
|
+
var compRefs = composition['components'];
|
|
3113
|
+
if (compRefs == null || compRefs.length === 0) {
|
|
3114
|
+
return undefined;
|
|
3115
|
+
}
|
|
3116
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(compRefs), _step; !(_step = _iterator()).done;){
|
|
3117
|
+
var ref = _step.value;
|
|
3118
|
+
var component = resolveDataPath(componentById, ref);
|
|
3119
|
+
if ((component == null ? void 0 : component['dataType']) === 'CompositionComponent') {
|
|
3120
|
+
return component;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
return undefined;
|
|
3124
|
+
}
|
|
3125
|
+
function getCompositionItemIds(scene) {
|
|
3126
|
+
var compositionId = scene['compositionId'];
|
|
3127
|
+
var compositions = scene['compositions'];
|
|
3128
|
+
var composition = compositions == null ? void 0 : compositions.find(function(c) {
|
|
3129
|
+
return c['id'] === compositionId;
|
|
3130
|
+
});
|
|
3131
|
+
if (composition == null) {
|
|
3132
|
+
return [];
|
|
3133
|
+
}
|
|
3134
|
+
var componentById = buildPoolIndex(scene['components']);
|
|
3135
|
+
var compositionComponent = findCompositionComponent(componentById, composition);
|
|
3136
|
+
if (compositionComponent == null) {
|
|
3137
|
+
return [];
|
|
3138
|
+
}
|
|
3139
|
+
var itemRefs = compositionComponent['items'];
|
|
3140
|
+
if (itemRefs == null) {
|
|
3141
|
+
return [];
|
|
3142
|
+
}
|
|
3143
|
+
return itemRefs.map(function(ref) {
|
|
3144
|
+
return ref.id;
|
|
3145
|
+
}).filter(function(id) {
|
|
3146
|
+
return typeof id === 'string';
|
|
3147
|
+
});
|
|
3148
|
+
}
|
|
3149
|
+
|
|
3150
|
+
function parseTimeline(itemId, ctx) {
|
|
3151
|
+
var trackId = ctx.itemIdToTrackId.get(itemId);
|
|
3152
|
+
if (trackId == null) {
|
|
3153
|
+
return undefined;
|
|
3154
|
+
}
|
|
3155
|
+
var objectBindingTrack = ctx.miscById.get(trackId);
|
|
3156
|
+
if (objectBindingTrack == null) {
|
|
3157
|
+
return undefined;
|
|
3158
|
+
}
|
|
3159
|
+
var childRefs = objectBindingTrack['children'];
|
|
3160
|
+
if (childRefs == null) {
|
|
3161
|
+
return undefined;
|
|
3162
|
+
}
|
|
3163
|
+
var delay = 0;
|
|
3164
|
+
var duration = 0;
|
|
3165
|
+
var endBehavior = 0;
|
|
3166
|
+
var transformAsset;
|
|
3167
|
+
var spriteColorAsset;
|
|
3168
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(childRefs), _step; !(_step = _iterator()).done;){
|
|
3169
|
+
var ref = _step.value;
|
|
3170
|
+
var childTrackId = resolveDataPathId(ref);
|
|
3171
|
+
if (childTrackId == null) {
|
|
3172
|
+
continue;
|
|
3173
|
+
}
|
|
3174
|
+
var childTrack = ctx.miscById.get(childTrackId);
|
|
3175
|
+
if (childTrack == null) {
|
|
3176
|
+
continue;
|
|
3177
|
+
}
|
|
3178
|
+
var dataType = childTrack['dataType'];
|
|
3179
|
+
var clips = childTrack['clips'];
|
|
3180
|
+
if (clips == null || clips.length === 0) {
|
|
3181
|
+
continue;
|
|
3182
|
+
}
|
|
3183
|
+
var clip = clips[0];
|
|
3184
|
+
if (dataType === 'ActivationTrack') {
|
|
3185
|
+
var _clip_start, _clip_duration, _clip_endBehavior;
|
|
3186
|
+
delay = (_clip_start = clip['start']) != null ? _clip_start : 0;
|
|
3187
|
+
duration = (_clip_duration = clip['duration']) != null ? _clip_duration : 0;
|
|
3188
|
+
endBehavior = (_clip_endBehavior = clip['endBehavior']) != null ? _clip_endBehavior : 0;
|
|
3189
|
+
} else if (dataType === 'TransformTrack') {
|
|
3190
|
+
var assetRef = clip['asset'];
|
|
3191
|
+
if (assetRef != null) {
|
|
3192
|
+
transformAsset = resolveDataPath(ctx.miscById, assetRef);
|
|
3193
|
+
}
|
|
3194
|
+
} else if (dataType === 'SpriteColorTrack') {
|
|
3195
|
+
var assetRef1 = clip['asset'];
|
|
3196
|
+
if (assetRef1 != null) {
|
|
3197
|
+
spriteColorAsset = resolveDataPath(ctx.miscById, assetRef1);
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
}
|
|
3201
|
+
return {
|
|
3202
|
+
delay: delay,
|
|
3203
|
+
duration: duration,
|
|
3204
|
+
endBehavior: endBehavior,
|
|
3205
|
+
transformAsset: transformAsset,
|
|
3206
|
+
spriteColorAsset: spriteColorAsset
|
|
3207
|
+
};
|
|
3208
|
+
}
|
|
3209
|
+
|
|
3210
|
+
function convert3dTo2dPoint(x, y, z, width, height) {
|
|
3211
|
+
var ratio = get2dTo3dRatio(width, height);
|
|
3212
|
+
var adaptRatioZ = (DEFAULT_CAMERA_Z - z) / DEFAULT_CAMERA_Z;
|
|
3213
|
+
var effectiveRatio = Math.abs(adaptRatioZ) > 1e-10 ? ratio * adaptRatioZ : ratio;
|
|
3214
|
+
var px = x / effectiveRatio + width / 2;
|
|
3215
|
+
var py = height / 2 - y / effectiveRatio;
|
|
3216
|
+
return [
|
|
3217
|
+
px,
|
|
3218
|
+
py,
|
|
3219
|
+
z
|
|
3220
|
+
];
|
|
3221
|
+
}
|
|
3222
|
+
|
|
3223
|
+
function parseStaticTransform(itemTransform, ctx) {
|
|
3224
|
+
var channels = {};
|
|
3225
|
+
var position = itemTransform['position'];
|
|
3226
|
+
if (position != null) {
|
|
3227
|
+
var _position_z;
|
|
3228
|
+
var pos2d = convert3dTo2dPoint(position.x, position.y, (_position_z = position.z) != null ? _position_z : 0, ctx.width, ctx.height);
|
|
3229
|
+
channels.position = {
|
|
3230
|
+
keyframed: false,
|
|
3231
|
+
value: pos2d
|
|
3232
|
+
};
|
|
3233
|
+
}
|
|
3234
|
+
var scale = itemTransform['scale'];
|
|
3235
|
+
if (scale != null) {
|
|
3236
|
+
var _scale_x, _scale_y, _scale_z;
|
|
3237
|
+
var sv = [
|
|
3238
|
+
(_scale_x = scale.x) != null ? _scale_x : 1,
|
|
3239
|
+
(_scale_y = scale.y) != null ? _scale_y : 1,
|
|
3240
|
+
(_scale_z = scale.z) != null ? _scale_z : 1
|
|
3241
|
+
];
|
|
3242
|
+
var isDefault = Math.abs(sv[0] - 1) < 1e-6 && Math.abs(sv[1] - 1) < 1e-6 && Math.abs(sv[2] - 1) < 1e-6;
|
|
3243
|
+
if (!isDefault) {
|
|
3244
|
+
channels.scale = {
|
|
3245
|
+
keyframed: false,
|
|
3246
|
+
value: sv
|
|
3247
|
+
};
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
var eulerHint = itemTransform['eulerHint'];
|
|
3251
|
+
if (eulerHint != null) {
|
|
3252
|
+
var hasRotation = Math.abs(eulerHint.x) > 1e-6 || Math.abs(eulerHint.y) > 1e-6 || Math.abs(eulerHint.z) > 1e-6;
|
|
3253
|
+
if (hasRotation) {
|
|
3254
|
+
channels.rotation = {
|
|
3255
|
+
keyframed: false,
|
|
3256
|
+
value: [
|
|
3257
|
+
eulerHint.x,
|
|
3258
|
+
eulerHint.y,
|
|
3259
|
+
eulerHint.z
|
|
3260
|
+
]
|
|
3261
|
+
};
|
|
3262
|
+
}
|
|
3263
|
+
}
|
|
3264
|
+
return channels;
|
|
3265
|
+
}
|
|
3266
|
+
|
|
3267
|
+
function inverseLerp(a, b, value) {
|
|
3268
|
+
var range = b - a;
|
|
3269
|
+
if (Math.abs(range) < 1e-10) {
|
|
3270
|
+
return 0;
|
|
3271
|
+
}
|
|
3272
|
+
return (value - a) / range;
|
|
3273
|
+
}
|
|
3274
|
+
function parseBezierKeyframes(curves, startFrame, endFrame) {
|
|
3275
|
+
if (curves.length === 0) {
|
|
3276
|
+
return [];
|
|
3277
|
+
}
|
|
3278
|
+
var segments = extractSegments(curves);
|
|
3279
|
+
if (segments.length === 0) {
|
|
3280
|
+
return [];
|
|
3281
|
+
}
|
|
3282
|
+
var frames = endFrame - startFrame;
|
|
3283
|
+
var keyframes = [];
|
|
3284
|
+
var firstSeg = segments[0];
|
|
3285
|
+
var firstT = firstSeg[0];
|
|
3286
|
+
var firstV = firstSeg[1];
|
|
3287
|
+
if (segments.length > 0) {
|
|
3288
|
+
var _segments_;
|
|
3289
|
+
var hasPrependedHold = segments.length >= 2 && Math.abs(firstV - segments[0][7]) < 1e-6 && Math.abs(firstV - firstSeg[1]) < 1e-6 && Math.abs(firstT) < 1e-10;
|
|
3290
|
+
if (hasPrependedHold && Math.abs(firstSeg[6] - ((_segments_ = segments[1]) == null ? void 0 : _segments_[0])) < 1e-6 && Math.abs(firstV - firstSeg[7]) < 1e-6) {
|
|
3291
|
+
segments.shift();
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
for(var i = 0; i < segments.length; i++){
|
|
3295
|
+
var seg = segments[i];
|
|
3296
|
+
var t0 = seg[0];
|
|
3297
|
+
var v0 = seg[1];
|
|
3298
|
+
var outCpX = seg[2];
|
|
3299
|
+
var outCpY = seg[3];
|
|
3300
|
+
var t1 = seg[6];
|
|
3301
|
+
var v1 = seg[7];
|
|
3302
|
+
var frameTime = t0 * frames + startFrame;
|
|
3303
|
+
var isHold = Math.abs(v0 - v1) < 1e-6 && Math.abs(outCpY - v0) < 1e-6 && Math.abs(seg[5] - v0) < 1e-6;
|
|
3304
|
+
var outTangent = {
|
|
3305
|
+
x: inverseLerp(t0, t1, outCpX),
|
|
3306
|
+
y: inverseLerp(v0, v1, outCpY)
|
|
3307
|
+
};
|
|
3308
|
+
if (i === 0) {
|
|
3309
|
+
keyframes.push(_extends({
|
|
3310
|
+
t: frameTime,
|
|
3311
|
+
value: v0
|
|
3312
|
+
}, isHold ? {
|
|
3313
|
+
hold: true
|
|
3314
|
+
} : {
|
|
3315
|
+
outTangent: outTangent
|
|
3316
|
+
}));
|
|
3317
|
+
} else {
|
|
3318
|
+
var prevSeg = segments[i - 1];
|
|
3319
|
+
var prevInCpX = prevSeg[4];
|
|
3320
|
+
var prevInCpY = prevSeg[5];
|
|
3321
|
+
var prevT0 = prevSeg[0];
|
|
3322
|
+
var prevV0 = prevSeg[1];
|
|
3323
|
+
var prevT1 = prevSeg[6];
|
|
3324
|
+
var prevV1 = prevSeg[7];
|
|
3325
|
+
var inTangent = {
|
|
3326
|
+
x: inverseLerp(prevT0, prevT1, prevInCpX),
|
|
3327
|
+
y: inverseLerp(prevV0, prevV1, prevInCpY)
|
|
3328
|
+
};
|
|
3329
|
+
keyframes.push(_extends({
|
|
3330
|
+
t: frameTime,
|
|
3331
|
+
value: v0,
|
|
3332
|
+
inTangent: inTangent
|
|
3333
|
+
}, isHold ? {
|
|
3334
|
+
hold: true
|
|
3335
|
+
} : {
|
|
3336
|
+
outTangent: outTangent
|
|
3337
|
+
}));
|
|
3338
|
+
}
|
|
3339
|
+
}
|
|
3340
|
+
var lastSeg = segments[segments.length - 1];
|
|
3341
|
+
var lastT1 = lastSeg[6];
|
|
3342
|
+
var lastV1 = lastSeg[7];
|
|
3343
|
+
var lastFrameTime = lastT1 * frames + startFrame;
|
|
3344
|
+
var lastInTangent = {
|
|
3345
|
+
x: inverseLerp(lastSeg[0], lastSeg[6], lastSeg[4]),
|
|
3346
|
+
y: inverseLerp(lastSeg[1], lastSeg[7], lastSeg[5])
|
|
3347
|
+
};
|
|
3348
|
+
keyframes.push({
|
|
3349
|
+
t: lastFrameTime,
|
|
3350
|
+
value: lastV1,
|
|
3351
|
+
inTangent: lastInTangent
|
|
3352
|
+
});
|
|
3353
|
+
return keyframes;
|
|
3354
|
+
}
|
|
3355
|
+
function extractSegments(curves) {
|
|
3356
|
+
var segments = [];
|
|
3357
|
+
for(var i = 0; i < curves.length; i++){
|
|
3358
|
+
var entry = curves[i];
|
|
3359
|
+
var type = entry[0];
|
|
3360
|
+
var data = entry[1];
|
|
3361
|
+
if (type === 3) {
|
|
3362
|
+
// EASE_OUT: [t, v, out_cx, out_cy] — first keyframe of a segment
|
|
3363
|
+
if (i + 1 < curves.length) {
|
|
3364
|
+
var nextEntry = curves[i + 1];
|
|
3365
|
+
var nextType = nextEntry[0];
|
|
3366
|
+
var nextData = nextEntry[1];
|
|
3367
|
+
if (nextType === 2) {
|
|
3368
|
+
// EASE_IN immediately follows: single segment
|
|
3369
|
+
segments.push([
|
|
3370
|
+
data[0],
|
|
3371
|
+
data[1],
|
|
3372
|
+
data[2],
|
|
3373
|
+
data[3],
|
|
3374
|
+
nextData[0],
|
|
3375
|
+
nextData[1],
|
|
3376
|
+
nextData[2],
|
|
3377
|
+
nextData[3]
|
|
3378
|
+
]);
|
|
3379
|
+
} else if (nextType === 1) {
|
|
3380
|
+
// EASE follows
|
|
3381
|
+
segments.push([
|
|
3382
|
+
data[0],
|
|
3383
|
+
data[1],
|
|
3384
|
+
data[2],
|
|
3385
|
+
data[3],
|
|
3386
|
+
nextData[0],
|
|
3387
|
+
nextData[1],
|
|
3388
|
+
nextData[2],
|
|
3389
|
+
nextData[3]
|
|
3390
|
+
]);
|
|
3391
|
+
}
|
|
3392
|
+
}
|
|
3393
|
+
} else if (type === 1 && i + 1 < curves.length) {
|
|
3394
|
+
// EASE: [in_cx, in_cy, t, v, out_cx, out_cy] — middle keyframe
|
|
3395
|
+
var nextEntry1 = curves[i + 1];
|
|
3396
|
+
var nextType1 = nextEntry1[0];
|
|
3397
|
+
var nextData1 = nextEntry1[1];
|
|
3398
|
+
if (nextType1 === 2) {
|
|
3399
|
+
segments.push([
|
|
3400
|
+
data[2],
|
|
3401
|
+
data[3],
|
|
3402
|
+
data[4],
|
|
3403
|
+
data[5],
|
|
3404
|
+
nextData1[0],
|
|
3405
|
+
nextData1[1],
|
|
3406
|
+
nextData1[2],
|
|
3407
|
+
nextData1[3]
|
|
3408
|
+
]);
|
|
3409
|
+
} else if (nextType1 === 1) {
|
|
3410
|
+
segments.push([
|
|
3411
|
+
data[2],
|
|
3412
|
+
data[3],
|
|
3413
|
+
data[4],
|
|
3414
|
+
data[5],
|
|
3415
|
+
nextData1[0],
|
|
3416
|
+
nextData1[1],
|
|
3417
|
+
nextData1[2],
|
|
3418
|
+
nextData1[3]
|
|
3419
|
+
]);
|
|
3420
|
+
}
|
|
3421
|
+
}
|
|
3422
|
+
}
|
|
3423
|
+
return segments;
|
|
3424
|
+
}
|
|
3425
|
+
function parsePositionTimingKeyframes(curves, startFrame, endFrame) {
|
|
3426
|
+
var segments = extractSegments(curves);
|
|
3427
|
+
if (segments.length === 0) {
|
|
3428
|
+
return [];
|
|
3429
|
+
}
|
|
3430
|
+
var frames = endFrame - startFrame;
|
|
3431
|
+
var result = [];
|
|
3432
|
+
for(var i = 0; i < segments.length; i++){
|
|
3433
|
+
var seg = segments[i];
|
|
3434
|
+
var t0 = seg[0];
|
|
3435
|
+
var outCpX = seg[2];
|
|
3436
|
+
var outCpY = seg[3];
|
|
3437
|
+
var t1 = seg[6];
|
|
3438
|
+
var frameTime = t0 * frames + startFrame;
|
|
3439
|
+
var outTangent = {
|
|
3440
|
+
x: inverseLerp(t0, t1, outCpX),
|
|
3441
|
+
y: inverseLerp(t0, t1, outCpY)
|
|
3442
|
+
};
|
|
3443
|
+
if (i === 0) {
|
|
3444
|
+
result.push({
|
|
3445
|
+
t: frameTime,
|
|
3446
|
+
outTangent: outTangent
|
|
3447
|
+
});
|
|
3448
|
+
} else {
|
|
3449
|
+
var prevSeg = segments[i - 1];
|
|
3450
|
+
var inTangent = {
|
|
3451
|
+
x: inverseLerp(prevSeg[0], prevSeg[6], prevSeg[4]),
|
|
3452
|
+
y: inverseLerp(prevSeg[0], prevSeg[6], prevSeg[5])
|
|
3453
|
+
};
|
|
3454
|
+
result.push({
|
|
3455
|
+
t: frameTime,
|
|
3456
|
+
outTangent: outTangent,
|
|
3457
|
+
inTangent: inTangent
|
|
3458
|
+
});
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
var lastSeg = segments[segments.length - 1];
|
|
3462
|
+
var lastFrameTime = lastSeg[6] * frames + startFrame;
|
|
3463
|
+
var lastInTangent = {
|
|
3464
|
+
x: inverseLerp(lastSeg[0], lastSeg[6], lastSeg[4]),
|
|
3465
|
+
y: inverseLerp(lastSeg[0], lastSeg[6], lastSeg[5])
|
|
3466
|
+
};
|
|
3467
|
+
result.push({
|
|
3468
|
+
t: lastFrameTime,
|
|
3469
|
+
inTangent: lastInTangent
|
|
3470
|
+
});
|
|
3471
|
+
return result;
|
|
3472
|
+
}
|
|
3473
|
+
|
|
3474
|
+
function parseTransformAnimation(asset, startFrame, endFrame, ctx) {
|
|
3475
|
+
var channels = {};
|
|
3476
|
+
var posOverLifetime = asset['positionOverLifetime'];
|
|
3477
|
+
if (posOverLifetime != null) {
|
|
3478
|
+
var posAnim = parsePositionAnimation(posOverLifetime, startFrame, endFrame, ctx);
|
|
3479
|
+
if (posAnim != null) {
|
|
3480
|
+
channels.position = posAnim;
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
var rotOverLifetime = asset['rotationOverLifetime'];
|
|
3484
|
+
if (rotOverLifetime != null) {
|
|
3485
|
+
var rotResult = parseRotationAnimation(rotOverLifetime, startFrame, endFrame);
|
|
3486
|
+
if (rotResult.rotation != null) {
|
|
3487
|
+
channels.rotation = rotResult.rotation;
|
|
3488
|
+
}
|
|
3489
|
+
if (rotResult.separatedRotation != null) {
|
|
3490
|
+
channels.separatedRotation = rotResult.separatedRotation;
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
var sizeOverLifetime = asset['sizeOverLifetime'];
|
|
3494
|
+
if (sizeOverLifetime != null) {
|
|
3495
|
+
var scaleAnim = parseScaleAnimation(sizeOverLifetime, startFrame, endFrame);
|
|
3496
|
+
if (scaleAnim != null) {
|
|
3497
|
+
channels.scale = scaleAnim;
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3500
|
+
return channels;
|
|
3501
|
+
}
|
|
3502
|
+
function parseOpacityAnimation(asset, startFrame, endFrame) {
|
|
3503
|
+
var colorOverLifetime = asset['colorOverLifetime'];
|
|
3504
|
+
if (colorOverLifetime == null) {
|
|
3505
|
+
return undefined;
|
|
3506
|
+
}
|
|
3507
|
+
var opacity = colorOverLifetime['opacity'];
|
|
3508
|
+
if (opacity == null || !Array.isArray(opacity) || opacity.length < 2) {
|
|
3509
|
+
return undefined;
|
|
3510
|
+
}
|
|
3511
|
+
var valueType = opacity[0];
|
|
3512
|
+
if (valueType === 0) {
|
|
3513
|
+
return {
|
|
3514
|
+
keyframed: false,
|
|
3515
|
+
value: opacity[1]
|
|
3516
|
+
};
|
|
3517
|
+
}
|
|
3518
|
+
if (valueType === 13) {
|
|
3519
|
+
var curves = opacity[1];
|
|
3520
|
+
var keyframes = parseBezierKeyframes(curves, startFrame, endFrame);
|
|
3521
|
+
if (keyframes.length >= 2) {
|
|
3522
|
+
return {
|
|
3523
|
+
keyframed: true,
|
|
3524
|
+
keyframes: keyframes
|
|
3525
|
+
};
|
|
3526
|
+
}
|
|
3527
|
+
}
|
|
3528
|
+
return undefined;
|
|
3529
|
+
}
|
|
3530
|
+
function parsePositionAnimation(posOverLifetime, startFrame, endFrame, ctx) {
|
|
3531
|
+
var pathData = posOverLifetime['path'];
|
|
3532
|
+
if (pathData == null || !Array.isArray(pathData) || pathData.length < 2) {
|
|
3533
|
+
return undefined;
|
|
3534
|
+
}
|
|
3535
|
+
var valueType = pathData[0];
|
|
3536
|
+
if (valueType !== 22) {
|
|
3537
|
+
return undefined;
|
|
3538
|
+
}
|
|
3539
|
+
var payload = pathData[1];
|
|
3540
|
+
if (!Array.isArray(payload) || payload.length < 2) {
|
|
3541
|
+
return undefined;
|
|
3542
|
+
}
|
|
3543
|
+
var easingData = payload[0];
|
|
3544
|
+
var pathPoints = payload[1];
|
|
3545
|
+
var controlPointsRaw = payload[2];
|
|
3546
|
+
if (!Array.isArray(pathPoints) || pathPoints.length < 2) {
|
|
3547
|
+
return undefined;
|
|
3548
|
+
}
|
|
3549
|
+
var timingKfs = parsePositionTimingKeyframes(easingData, startFrame, endFrame);
|
|
3550
|
+
if (timingKfs.length < 2) {
|
|
3551
|
+
return undefined;
|
|
3552
|
+
}
|
|
3553
|
+
// Detect and skip prepended hold segment
|
|
3554
|
+
var startIdx = 0;
|
|
3555
|
+
if (timingKfs.length > 2) {
|
|
3556
|
+
var firstPP = pathPoints[0];
|
|
3557
|
+
var secondPP = pathPoints[1];
|
|
3558
|
+
if (firstPP != null && secondPP != null && Math.abs(firstPP[0] - secondPP[0]) < 1e-6 && Math.abs(firstPP[1] - secondPP[1]) < 1e-6) {
|
|
3559
|
+
startIdx = 1;
|
|
3560
|
+
}
|
|
3561
|
+
}
|
|
3562
|
+
var keyframes = [];
|
|
3563
|
+
var pendingSpatialIn = new Map();
|
|
3564
|
+
for(var i = startIdx; i < timingKfs.length; i++){
|
|
3565
|
+
var _pp_;
|
|
3566
|
+
var timing = timingKfs[i];
|
|
3567
|
+
var pp = pathPoints[Math.min(i, pathPoints.length - 1)];
|
|
3568
|
+
var pos2d = convert3dTo2dPoint(pp[0], pp[1], (_pp_ = pp[2]) != null ? _pp_ : 0, ctx.width, ctx.height);
|
|
3569
|
+
var kf = {
|
|
3570
|
+
t: timing.t,
|
|
3571
|
+
value: pos2d
|
|
3572
|
+
};
|
|
3573
|
+
if (i > startIdx && timing.inTangent != null) {
|
|
3574
|
+
kf.inTangent = timing.inTangent;
|
|
3575
|
+
}
|
|
3576
|
+
if (i < timingKfs.length - 1 && timing.outTangent != null) {
|
|
3577
|
+
kf.outTangent = timing.outTangent;
|
|
3578
|
+
}
|
|
3579
|
+
var kfIndex = keyframes.length;
|
|
3580
|
+
var pendingSI = pendingSpatialIn.get(kfIndex);
|
|
3581
|
+
if (pendingSI != null) {
|
|
3582
|
+
kf.spatialIn = pendingSI;
|
|
3583
|
+
}
|
|
3584
|
+
if (controlPointsRaw != null && i - startIdx < timingKfs.length - startIdx - 1) {
|
|
3585
|
+
var segIdx = i - startIdx;
|
|
3586
|
+
var cp1Idx = segIdx * 2;
|
|
3587
|
+
var cp2Idx = segIdx * 2 + 1;
|
|
3588
|
+
if (cp1Idx < controlPointsRaw.length && cp2Idx < controlPointsRaw.length) {
|
|
3589
|
+
var _ppStart_, _ppEnd_, _cp1_, _cp2_;
|
|
3590
|
+
var cp1 = controlPointsRaw[cp1Idx];
|
|
3591
|
+
var cp2 = controlPointsRaw[cp2Idx];
|
|
3592
|
+
var ppStart = pathPoints[i];
|
|
3593
|
+
var ppEnd = pathPoints[Math.min(i + 1, pathPoints.length - 1)];
|
|
3594
|
+
var ppStart2d = convert3dTo2dPoint(ppStart[0], ppStart[1], (_ppStart_ = ppStart[2]) != null ? _ppStart_ : 0, ctx.width, ctx.height);
|
|
3595
|
+
var ppEnd2d = convert3dTo2dPoint(ppEnd[0], ppEnd[1], (_ppEnd_ = ppEnd[2]) != null ? _ppEnd_ : 0, ctx.width, ctx.height);
|
|
3596
|
+
var cp1_2d = convert3dTo2dPoint(cp1[0], cp1[1], (_cp1_ = cp1[2]) != null ? _cp1_ : 0, ctx.width, ctx.height);
|
|
3597
|
+
var cp2_2d = convert3dTo2dPoint(cp2[0], cp2[1], (_cp2_ = cp2[2]) != null ? _cp2_ : 0, ctx.width, ctx.height);
|
|
3598
|
+
kf.spatialOut = [
|
|
3599
|
+
cp1_2d[0] - ppStart2d[0],
|
|
3600
|
+
cp1_2d[1] - ppStart2d[1]
|
|
3601
|
+
];
|
|
3602
|
+
pendingSpatialIn.set(kfIndex + 1, [
|
|
3603
|
+
cp2_2d[0] - ppEnd2d[0],
|
|
3604
|
+
cp2_2d[1] - ppEnd2d[1]
|
|
3605
|
+
]);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
keyframes.push(kf);
|
|
3609
|
+
}
|
|
3610
|
+
if (keyframes.length < 2) {
|
|
3611
|
+
return undefined;
|
|
3612
|
+
}
|
|
3613
|
+
return {
|
|
3614
|
+
keyframed: true,
|
|
3615
|
+
keyframes: keyframes
|
|
3616
|
+
};
|
|
3617
|
+
}
|
|
3618
|
+
function parseRotationAnimation(rotOverLifetime, startFrame, endFrame) {
|
|
3619
|
+
var separateAxes = rotOverLifetime['separateAxes'];
|
|
3620
|
+
var xData = rotOverLifetime['x'];
|
|
3621
|
+
var yData = rotOverLifetime['y'];
|
|
3622
|
+
var zData = rotOverLifetime['z'];
|
|
3623
|
+
if (separateAxes === true) {
|
|
3624
|
+
var x = parseScalarChannel(xData, startFrame, endFrame);
|
|
3625
|
+
var y = parseScalarChannel(yData, startFrame, endFrame);
|
|
3626
|
+
var z = parseScalarChannel(zData, startFrame, endFrame);
|
|
3627
|
+
var hasMultiAxis = (x != null ? 1 : 0) + (y != null ? 1 : 0) + (z != null ? 1 : 0) > 1;
|
|
3628
|
+
var hasXOrY = x != null || y != null;
|
|
3629
|
+
if (hasMultiAxis || hasXOrY) {
|
|
3630
|
+
return {
|
|
3631
|
+
separatedRotation: _extends({}, x != null && {
|
|
3632
|
+
x: x
|
|
3633
|
+
}, y != null && {
|
|
3634
|
+
y: y
|
|
3635
|
+
}, z != null && {
|
|
3636
|
+
z: z
|
|
3637
|
+
})
|
|
3638
|
+
};
|
|
3639
|
+
}
|
|
3640
|
+
if (z != null) {
|
|
3641
|
+
return {
|
|
3642
|
+
separatedRotation: {
|
|
3643
|
+
z: z
|
|
3644
|
+
}
|
|
3645
|
+
};
|
|
3646
|
+
}
|
|
3647
|
+
}
|
|
3648
|
+
// Single-axis z rotation (non-separated)
|
|
3649
|
+
if (zData != null) {
|
|
3650
|
+
var z1 = parseScalarChannel(zData, startFrame, endFrame);
|
|
3651
|
+
if (z1 != null) {
|
|
3652
|
+
if (z1.keyframed) {
|
|
3653
|
+
var vecKeyframes = z1.keyframes.map(function(kf) {
|
|
3654
|
+
var result = {
|
|
3655
|
+
t: kf.t,
|
|
3656
|
+
value: [
|
|
3657
|
+
0,
|
|
3658
|
+
0,
|
|
3659
|
+
kf.value
|
|
3660
|
+
]
|
|
3661
|
+
};
|
|
3662
|
+
if (kf.hold != null) {
|
|
3663
|
+
result.hold = kf.hold;
|
|
3664
|
+
}
|
|
3665
|
+
if (kf.inTangent != null) {
|
|
3666
|
+
result.inTangent = kf.inTangent;
|
|
3667
|
+
}
|
|
3668
|
+
if (kf.outTangent != null) {
|
|
3669
|
+
result.outTangent = kf.outTangent;
|
|
3670
|
+
}
|
|
3671
|
+
return result;
|
|
3672
|
+
});
|
|
3673
|
+
return {
|
|
3674
|
+
rotation: {
|
|
3675
|
+
keyframed: true,
|
|
3676
|
+
keyframes: vecKeyframes
|
|
3677
|
+
}
|
|
3678
|
+
};
|
|
3679
|
+
}
|
|
3680
|
+
return {
|
|
3681
|
+
rotation: {
|
|
3682
|
+
keyframed: false,
|
|
3683
|
+
value: [
|
|
3684
|
+
0,
|
|
3685
|
+
0,
|
|
3686
|
+
z1.value
|
|
3687
|
+
]
|
|
3688
|
+
}
|
|
3689
|
+
};
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3692
|
+
return {};
|
|
3693
|
+
}
|
|
3694
|
+
function parseScaleAnimation(sizeOverLifetime, startFrame, endFrame) {
|
|
3695
|
+
var _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8;
|
|
3696
|
+
var xData = sizeOverLifetime['x'];
|
|
3697
|
+
var yData = sizeOverLifetime['y'];
|
|
3698
|
+
var zData = sizeOverLifetime['z'];
|
|
3699
|
+
var x = parseScalarChannel(xData, startFrame, endFrame);
|
|
3700
|
+
var y = parseScalarChannel(yData, startFrame, endFrame);
|
|
3701
|
+
var z = parseScalarChannel(zData, startFrame, endFrame);
|
|
3702
|
+
if (x == null && y == null && z == null) {
|
|
3703
|
+
return undefined;
|
|
3704
|
+
}
|
|
3705
|
+
var xKeyframed = (x == null ? void 0 : x.keyframed) === true;
|
|
3706
|
+
var yKeyframed = (y == null ? void 0 : y.keyframed) === true;
|
|
3707
|
+
var zKeyframed = (z == null ? void 0 : z.keyframed) === true;
|
|
3708
|
+
if (!xKeyframed && !yKeyframed && !zKeyframed) {
|
|
3709
|
+
var _ref9, _ref10, _ref11;
|
|
3710
|
+
return {
|
|
3711
|
+
keyframed: false,
|
|
3712
|
+
value: [
|
|
3713
|
+
(_ref9 = x == null ? void 0 : x.value) != null ? _ref9 : 1,
|
|
3714
|
+
(_ref10 = y == null ? void 0 : y.value) != null ? _ref10 : 1,
|
|
3715
|
+
(_ref11 = z == null ? void 0 : z.value) != null ? _ref11 : 1
|
|
3716
|
+
]
|
|
3717
|
+
};
|
|
3718
|
+
}
|
|
3719
|
+
var xKfs = (_ref = x == null ? void 0 : x.keyframes) != null ? _ref : [
|
|
3720
|
+
{
|
|
3721
|
+
t: startFrame,
|
|
3722
|
+
value: (_ref1 = x == null ? void 0 : x.value) != null ? _ref1 : 1
|
|
3723
|
+
},
|
|
3724
|
+
{
|
|
3725
|
+
t: endFrame,
|
|
3726
|
+
value: (_ref2 = x == null ? void 0 : x.value) != null ? _ref2 : 1
|
|
3727
|
+
}
|
|
3728
|
+
];
|
|
3729
|
+
var yKfs = (_ref3 = y == null ? void 0 : y.keyframes) != null ? _ref3 : [
|
|
3730
|
+
{
|
|
3731
|
+
t: startFrame,
|
|
3732
|
+
value: (_ref4 = y == null ? void 0 : y.value) != null ? _ref4 : 1
|
|
3733
|
+
},
|
|
3734
|
+
{
|
|
3735
|
+
t: endFrame,
|
|
3736
|
+
value: (_ref5 = y == null ? void 0 : y.value) != null ? _ref5 : 1
|
|
3737
|
+
}
|
|
3738
|
+
];
|
|
3739
|
+
var zKfs = (_ref6 = z == null ? void 0 : z.keyframes) != null ? _ref6 : [
|
|
3740
|
+
{
|
|
3741
|
+
t: startFrame,
|
|
3742
|
+
value: (_ref7 = z == null ? void 0 : z.value) != null ? _ref7 : 1
|
|
3743
|
+
},
|
|
3744
|
+
{
|
|
3745
|
+
t: endFrame,
|
|
3746
|
+
value: (_ref8 = z == null ? void 0 : z.value) != null ? _ref8 : 1
|
|
3747
|
+
}
|
|
3748
|
+
];
|
|
3749
|
+
var allTimes = new Set();
|
|
3750
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(xKfs), _step; !(_step = _iterator()).done;){
|
|
3751
|
+
var kf = _step.value;
|
|
3752
|
+
allTimes.add(kf.t);
|
|
3753
|
+
}
|
|
3754
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(yKfs), _step1; !(_step1 = _iterator1()).done;){
|
|
3755
|
+
var kf1 = _step1.value;
|
|
3756
|
+
allTimes.add(kf1.t);
|
|
3757
|
+
}
|
|
3758
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(zKfs), _step2; !(_step2 = _iterator2()).done;){
|
|
3759
|
+
var kf2 = _step2.value;
|
|
3760
|
+
allTimes.add(kf2.t);
|
|
3761
|
+
}
|
|
3762
|
+
var sortedTimes = [].concat(allTimes).sort(function(a, b) {
|
|
3763
|
+
return a - b;
|
|
3764
|
+
});
|
|
3765
|
+
var keyframes = sortedTimes.map(function(t) {
|
|
3766
|
+
var _ref, _ref1, _ref2;
|
|
3767
|
+
var xv = findValueAtTime(xKfs, t, (_ref = x == null ? void 0 : x.value) != null ? _ref : 1);
|
|
3768
|
+
var yv = findValueAtTime(yKfs, t, (_ref1 = y == null ? void 0 : y.value) != null ? _ref1 : 1);
|
|
3769
|
+
var zv = findValueAtTime(zKfs, t, (_ref2 = z == null ? void 0 : z.value) != null ? _ref2 : 1);
|
|
3770
|
+
var kf = {
|
|
3771
|
+
t: t,
|
|
3772
|
+
value: [
|
|
3773
|
+
xv.value,
|
|
3774
|
+
yv.value,
|
|
3775
|
+
zv.value
|
|
3776
|
+
]
|
|
3777
|
+
};
|
|
3778
|
+
if (xv.outTangent != null) {
|
|
3779
|
+
kf.outTangent = xv.outTangent;
|
|
3780
|
+
}
|
|
3781
|
+
if (xv.inTangent != null) {
|
|
3782
|
+
kf.inTangent = xv.inTangent;
|
|
3783
|
+
}
|
|
3784
|
+
if (xv.hold === true) {
|
|
3785
|
+
kf.hold = true;
|
|
3786
|
+
}
|
|
3787
|
+
return kf;
|
|
3788
|
+
});
|
|
3789
|
+
return {
|
|
3790
|
+
keyframed: true,
|
|
3791
|
+
keyframes: keyframes
|
|
3792
|
+
};
|
|
3793
|
+
}
|
|
3794
|
+
function parseScalarChannel(data, startFrame, endFrame) {
|
|
3795
|
+
if (data == null || !Array.isArray(data) || data.length < 2) {
|
|
3796
|
+
return undefined;
|
|
3797
|
+
}
|
|
3798
|
+
var valueType = data[0];
|
|
3799
|
+
if (valueType === 0) {
|
|
3800
|
+
return {
|
|
3801
|
+
keyframed: false,
|
|
3802
|
+
value: data[1]
|
|
3803
|
+
};
|
|
3804
|
+
}
|
|
3805
|
+
if (valueType === 13) {
|
|
3806
|
+
var curves = data[1];
|
|
3807
|
+
var keyframes = parseBezierKeyframes(curves, startFrame, endFrame);
|
|
3808
|
+
if (keyframes.length >= 2) {
|
|
3809
|
+
return {
|
|
3810
|
+
keyframed: true,
|
|
3811
|
+
keyframes: keyframes
|
|
3812
|
+
};
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
return undefined;
|
|
3816
|
+
}
|
|
3817
|
+
function findValueAtTime(keyframes, t, defaultValue) {
|
|
3818
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(keyframes), _step; !(_step = _iterator()).done;){
|
|
3819
|
+
var kf = _step.value;
|
|
3820
|
+
if (Math.abs(kf.t - t) < 1e-6) {
|
|
3821
|
+
return {
|
|
3822
|
+
value: kf.value,
|
|
3823
|
+
outTangent: kf.outTangent,
|
|
3824
|
+
inTangent: kf.inTangent,
|
|
3825
|
+
hold: kf.hold
|
|
3826
|
+
};
|
|
3827
|
+
}
|
|
3828
|
+
}
|
|
3829
|
+
return {
|
|
3830
|
+
value: defaultValue
|
|
3831
|
+
};
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
var IR_BLEND_MODE_BY_GE = {
|
|
3835
|
+
1: IRBlendMode.Add,
|
|
3836
|
+
2: IRBlendMode.Darken,
|
|
3837
|
+
3: IRBlendMode.Lighten,
|
|
3838
|
+
4: IRBlendMode.Difference,
|
|
3839
|
+
5: IRBlendMode.Exclusion,
|
|
3840
|
+
6: IRBlendMode.Multiply,
|
|
3841
|
+
7: IRBlendMode.ColorBurn,
|
|
3842
|
+
8: IRBlendMode.Color,
|
|
3843
|
+
9: IRBlendMode.Screen,
|
|
3844
|
+
10: IRBlendMode.ColorDodge,
|
|
3845
|
+
11: IRBlendMode.Hue,
|
|
3846
|
+
12: IRBlendMode.Saturation,
|
|
3847
|
+
13: IRBlendMode.Overlay,
|
|
3848
|
+
14: IRBlendMode.HardLight,
|
|
3849
|
+
15: IRBlendMode.SoftLight,
|
|
3850
|
+
16: IRBlendMode.Luminosity
|
|
3851
|
+
};
|
|
3852
|
+
function reverseBlendMode(geCode) {
|
|
3853
|
+
if (geCode == null) {
|
|
3854
|
+
return undefined;
|
|
3855
|
+
}
|
|
3856
|
+
return IR_BLEND_MODE_BY_GE[geCode];
|
|
3857
|
+
}
|
|
3858
|
+
|
|
3859
|
+
function parseComponent(item, ctx) {
|
|
3860
|
+
var componentRefs = item['components'];
|
|
3861
|
+
if (componentRefs == null || componentRefs.length === 0) {
|
|
3862
|
+
return undefined;
|
|
3863
|
+
}
|
|
3864
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(componentRefs), _step; !(_step = _iterator()).done;){
|
|
3865
|
+
var ref = _step.value;
|
|
3866
|
+
var compId = resolveDataPathId(ref);
|
|
3867
|
+
if (compId == null) {
|
|
3868
|
+
continue;
|
|
3869
|
+
}
|
|
3870
|
+
var component = ctx.componentById.get(compId);
|
|
3871
|
+
if (component == null) {
|
|
3872
|
+
continue;
|
|
3873
|
+
}
|
|
3874
|
+
var dataType = component['dataType'];
|
|
3875
|
+
var result = void 0;
|
|
3876
|
+
if (dataType === 'SpriteComponent') {
|
|
3877
|
+
result = parseSpriteComponent(component, ctx);
|
|
3878
|
+
} else if (dataType === 'TextComponent') {
|
|
3879
|
+
result = parseTextComponent(component);
|
|
3880
|
+
} else if (dataType === 'ShapeComponent') {
|
|
3881
|
+
result = parseShapeComponent(component, ctx);
|
|
3882
|
+
}
|
|
3883
|
+
if (result == null) {
|
|
3884
|
+
continue;
|
|
3885
|
+
}
|
|
3886
|
+
result.geComponentId = component['id'];
|
|
3887
|
+
var mask = component['mask'];
|
|
3888
|
+
if (mask != null) {
|
|
3889
|
+
result.rawMask = mask;
|
|
3890
|
+
}
|
|
3891
|
+
return result;
|
|
3892
|
+
}
|
|
3893
|
+
return undefined;
|
|
3894
|
+
}
|
|
3895
|
+
function parseSpriteComponent(component, ctx) {
|
|
3896
|
+
var renderer = component['renderer'];
|
|
3897
|
+
var options = component['options'];
|
|
3898
|
+
var asset;
|
|
3899
|
+
var solidColor;
|
|
3900
|
+
var blendMode;
|
|
3901
|
+
var anchorScale;
|
|
3902
|
+
if (renderer != null) {
|
|
3903
|
+
var textureRef = renderer['texture'];
|
|
3904
|
+
if (textureRef != null) {
|
|
3905
|
+
var texture = resolveDataPath(ctx.textureById, textureRef);
|
|
3906
|
+
if (texture != null) {
|
|
3907
|
+
var sourceRef = texture['source'];
|
|
3908
|
+
var image = sourceRef != null ? resolveDataPath(ctx.imageById, sourceRef) : undefined;
|
|
3909
|
+
if (image != null) {
|
|
3910
|
+
asset = {
|
|
3911
|
+
url: image['url']
|
|
3912
|
+
};
|
|
3913
|
+
}
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3916
|
+
blendMode = reverseBlendMode(renderer['blending']);
|
|
3917
|
+
var anchor = renderer['anchor'];
|
|
3918
|
+
if (anchor != null && Array.isArray(anchor) && anchor.length >= 2) {
|
|
3919
|
+
anchorScale = [
|
|
3920
|
+
anchor[0],
|
|
3921
|
+
anchor[1]
|
|
3922
|
+
];
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
if (options != null) {
|
|
3926
|
+
var startColor = options['startColor'];
|
|
3927
|
+
if (startColor != null && startColor.length >= 4) {
|
|
3928
|
+
var isWhite = Math.abs(startColor[0] - 1) < 1e-4 && Math.abs(startColor[1] - 1) < 1e-4 && Math.abs(startColor[2] - 1) < 1e-4 && Math.abs(startColor[3] - 1) < 1e-4;
|
|
3929
|
+
if (!isWhite) {
|
|
3930
|
+
solidColor = [
|
|
3931
|
+
startColor[0],
|
|
3932
|
+
startColor[1],
|
|
3933
|
+
startColor[2],
|
|
3934
|
+
startColor[3]
|
|
3935
|
+
];
|
|
3936
|
+
}
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
var type = asset != null ? 'image' : 'solid';
|
|
3940
|
+
return {
|
|
3941
|
+
type: type,
|
|
3942
|
+
asset: asset,
|
|
3943
|
+
solidColor: solidColor,
|
|
3944
|
+
blendMode: blendMode,
|
|
3945
|
+
anchorScale: anchorScale
|
|
3946
|
+
};
|
|
3947
|
+
}
|
|
3948
|
+
function parseTextComponent(component) {
|
|
3949
|
+
var _options_text, _options_fontSize, _options_fontFamily, _options_fontWeight, _options_fontStyle, _options_letterSpace, _options_autoWidth;
|
|
3950
|
+
var options = component['options'];
|
|
3951
|
+
var renderer = component['renderer'];
|
|
3952
|
+
if (options == null) {
|
|
3953
|
+
return {
|
|
3954
|
+
type: 'text'
|
|
3955
|
+
};
|
|
3956
|
+
}
|
|
3957
|
+
var textColor = options['textColor'];
|
|
3958
|
+
var color = textColor != null && textColor.length >= 4 ? [
|
|
3959
|
+
textColor[0],
|
|
3960
|
+
textColor[1],
|
|
3961
|
+
textColor[2],
|
|
3962
|
+
textColor[3]
|
|
3963
|
+
] : [
|
|
3964
|
+
0,
|
|
3965
|
+
0,
|
|
3966
|
+
0,
|
|
3967
|
+
1
|
|
3968
|
+
];
|
|
3969
|
+
var textAlignNum = options['textAlign'];
|
|
3970
|
+
var textAlign = textAlignNum === 1 ? 'center' : textAlignNum === 2 ? 'right' : 'left';
|
|
3971
|
+
var text = {
|
|
3972
|
+
content: (_options_text = options['text']) != null ? _options_text : '',
|
|
3973
|
+
fontSize: (_options_fontSize = options['fontSize']) != null ? _options_fontSize : 12,
|
|
3974
|
+
color: color,
|
|
3975
|
+
fontFamily: (_options_fontFamily = options['fontFamily']) != null ? _options_fontFamily : 'sans-serif',
|
|
3976
|
+
fontWeight: (_options_fontWeight = options['fontWeight']) != null ? _options_fontWeight : 'normal',
|
|
3977
|
+
textAlign: textAlign,
|
|
3978
|
+
fontStyle: (_options_fontStyle = options['fontStyle']) != null ? _options_fontStyle : 'normal',
|
|
3979
|
+
letterSpacing: (_options_letterSpace = options['letterSpace']) != null ? _options_letterSpace : 0,
|
|
3980
|
+
lineHeight: options['lineHeight'],
|
|
3981
|
+
autoWidth: (_options_autoWidth = options['autoWidth']) != null ? _options_autoWidth : true,
|
|
3982
|
+
width: options['textWidth'],
|
|
3983
|
+
height: options['textHeight']
|
|
3984
|
+
};
|
|
3985
|
+
var blendMode;
|
|
3986
|
+
var anchorScale;
|
|
3987
|
+
if (renderer != null) {
|
|
3988
|
+
blendMode = reverseBlendMode(renderer['blending']);
|
|
3989
|
+
var anchor = renderer['anchor'];
|
|
3990
|
+
if (anchor != null && Array.isArray(anchor) && anchor.length >= 2) {
|
|
3991
|
+
anchorScale = [
|
|
3992
|
+
anchor[0],
|
|
3993
|
+
anchor[1]
|
|
3994
|
+
];
|
|
3995
|
+
}
|
|
3996
|
+
}
|
|
3997
|
+
return {
|
|
3998
|
+
type: 'text',
|
|
3999
|
+
text: text,
|
|
4000
|
+
blendMode: blendMode,
|
|
4001
|
+
anchorScale: anchorScale
|
|
4002
|
+
};
|
|
4003
|
+
}
|
|
4004
|
+
function parseShapeComponent(component, ctx) {
|
|
4005
|
+
var renderer = component['renderer'];
|
|
4006
|
+
var blendMode;
|
|
4007
|
+
if (renderer != null) {
|
|
4008
|
+
blendMode = reverseBlendMode(renderer['blending']);
|
|
4009
|
+
}
|
|
4010
|
+
var shapeData = parseShapeOptions(component, ctx.ratio);
|
|
4011
|
+
return {
|
|
4012
|
+
type: 'shape',
|
|
4013
|
+
shapes: shapeData != null ? [
|
|
4014
|
+
shapeData
|
|
4015
|
+
] : undefined,
|
|
4016
|
+
blendMode: blendMode
|
|
4017
|
+
};
|
|
4018
|
+
}
|
|
4019
|
+
function parseShapeOptions(component, ratio) {
|
|
4020
|
+
var geType = component['type'];
|
|
4021
|
+
var primitiveType = reverseShapePrimitiveType(geType != null ? geType : 0);
|
|
4022
|
+
var xSize = component['xSize'];
|
|
4023
|
+
var ySize = component['ySize'];
|
|
4024
|
+
var size = [
|
|
4025
|
+
xSize != null ? xSize / ratio : 0,
|
|
4026
|
+
ySize != null ? ySize / ratio : 0
|
|
4027
|
+
];
|
|
4028
|
+
var shape = {
|
|
4029
|
+
primitiveType: primitiveType,
|
|
4030
|
+
position: [
|
|
4031
|
+
0,
|
|
4032
|
+
0
|
|
4033
|
+
],
|
|
4034
|
+
size: size,
|
|
4035
|
+
fills: [],
|
|
4036
|
+
strokes: []
|
|
4037
|
+
};
|
|
4038
|
+
var shapeRec = shape;
|
|
4039
|
+
reverseScaledNumber(shapeRec, component, 'xRadius', ratio);
|
|
4040
|
+
reverseScaledNumber(shapeRec, component, 'yRadius', ratio);
|
|
4041
|
+
reverseScaledNumber(shapeRec, component, 'width', ratio);
|
|
4042
|
+
reverseScaledNumber(shapeRec, component, 'height', ratio);
|
|
4043
|
+
reverseScaledNumber(shapeRec, component, 'innerRadius', ratio);
|
|
4044
|
+
reverseScaledNumber(shapeRec, component, 'outerRadius', ratio);
|
|
4045
|
+
reverseScaledNumber(shapeRec, component, 'radius', ratio);
|
|
4046
|
+
reverseRawNumber(shapeRec, component, 'roundness');
|
|
4047
|
+
reverseRawNumber(shapeRec, component, 'pointCount');
|
|
4048
|
+
reverseRawNumber(shapeRec, component, 'innerRoundness');
|
|
4049
|
+
reverseRawNumber(shapeRec, component, 'outerRoundness');
|
|
4050
|
+
var geFills = component['fills'];
|
|
4051
|
+
if (geFills != null) {
|
|
4052
|
+
shape.fills = geFills.map(function(f) {
|
|
4053
|
+
return reverseShapePaint(f, ratio);
|
|
4054
|
+
}).filter(function(f) {
|
|
4055
|
+
return f != null;
|
|
4056
|
+
});
|
|
4057
|
+
}
|
|
4058
|
+
var geStrokes = component['strokes'];
|
|
4059
|
+
if (geStrokes != null) {
|
|
4060
|
+
shape.strokes = geStrokes.map(function(s) {
|
|
4061
|
+
return reverseShapePaint(s, ratio);
|
|
4062
|
+
}).filter(function(s) {
|
|
4063
|
+
return s != null;
|
|
4064
|
+
});
|
|
4065
|
+
}
|
|
4066
|
+
var geStrokeWidth = component['strokeWidth'];
|
|
4067
|
+
if (geStrokeWidth != null) {
|
|
4068
|
+
shape.strokeWidth = geStrokeWidth / ratio;
|
|
4069
|
+
}
|
|
4070
|
+
var geStrokeCap = component['strokeCap'];
|
|
4071
|
+
if (geStrokeCap != null) {
|
|
4072
|
+
shape.strokeCap = reverseLineCap(geStrokeCap);
|
|
4073
|
+
}
|
|
4074
|
+
var geStrokeJoin = component['strokeJoin'];
|
|
4075
|
+
if (geStrokeJoin != null) {
|
|
4076
|
+
shape.strokeJoin = reverseLineJoin(geStrokeJoin);
|
|
4077
|
+
}
|
|
4078
|
+
var geFillRule = component['fillRule'];
|
|
4079
|
+
if (geFillRule != null) {
|
|
4080
|
+
shape.fillRule = reverseShapeFillRule(geFillRule);
|
|
4081
|
+
}
|
|
4082
|
+
var geShapes = component['shapes'];
|
|
4083
|
+
if (geShapes != null) {
|
|
4084
|
+
var paths = reverseCustomPaths(component, ratio);
|
|
4085
|
+
if (paths.length > 0) {
|
|
4086
|
+
shape.customPaths = paths;
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
var trimPath = component['trimPath'];
|
|
4090
|
+
if (trimPath != null) {
|
|
4091
|
+
shape.trimPath = trimPath;
|
|
4092
|
+
}
|
|
4093
|
+
var repeater = component['repeater'];
|
|
4094
|
+
if (repeater != null) {
|
|
4095
|
+
shape.repeater = repeater;
|
|
4096
|
+
}
|
|
4097
|
+
return shape;
|
|
4098
|
+
}
|
|
4099
|
+
var GE_TO_SHAPE_PRIMITIVE_TYPE = {
|
|
4100
|
+
0: IRShapePrimitiveType.Custom,
|
|
4101
|
+
1: IRShapePrimitiveType.Rectangle,
|
|
4102
|
+
2: IRShapePrimitiveType.Ellipse,
|
|
4103
|
+
3: IRShapePrimitiveType.Polygon,
|
|
4104
|
+
4: IRShapePrimitiveType.Star
|
|
4105
|
+
};
|
|
4106
|
+
function reverseShapePrimitiveType(geType) {
|
|
4107
|
+
var _GE_TO_SHAPE_PRIMITIVE_TYPE_geType;
|
|
4108
|
+
return (_GE_TO_SHAPE_PRIMITIVE_TYPE_geType = GE_TO_SHAPE_PRIMITIVE_TYPE[geType]) != null ? _GE_TO_SHAPE_PRIMITIVE_TYPE_geType : IRShapePrimitiveType.Custom;
|
|
4109
|
+
}
|
|
4110
|
+
function reverseShapePaint(paint, ratio) {
|
|
4111
|
+
var geType = paint['type'];
|
|
4112
|
+
if (geType === 0) {
|
|
4113
|
+
var color = paint['color'];
|
|
4114
|
+
if (color == null) {
|
|
4115
|
+
return undefined;
|
|
4116
|
+
}
|
|
4117
|
+
return {
|
|
4118
|
+
type: IRFillType.Solid,
|
|
4119
|
+
color: [
|
|
4120
|
+
color.r,
|
|
4121
|
+
color.g,
|
|
4122
|
+
color.b,
|
|
4123
|
+
color.a
|
|
4124
|
+
]
|
|
4125
|
+
};
|
|
4126
|
+
}
|
|
4127
|
+
if (geType === 1 || geType === 2 || geType === 3) {
|
|
4128
|
+
var typeMap = {
|
|
4129
|
+
1: IRFillType.LinearGradient,
|
|
4130
|
+
2: IRFillType.RadialGradient,
|
|
4131
|
+
3: IRFillType.AngularGradient
|
|
4132
|
+
};
|
|
4133
|
+
var gradientStopsRaw = paint['gradientStops'];
|
|
4134
|
+
var stops = Array.isArray(gradientStopsRaw) && gradientStopsRaw.length >= 2 ? gradientStopsRaw[1] : [];
|
|
4135
|
+
var startPoint = paint['startPoint'];
|
|
4136
|
+
var endPoint = paint['endPoint'];
|
|
4137
|
+
return {
|
|
4138
|
+
type: typeMap[geType],
|
|
4139
|
+
gradientStops: stops,
|
|
4140
|
+
gradientStart: startPoint != null ? [
|
|
4141
|
+
startPoint.x / ratio,
|
|
4142
|
+
-startPoint.y / ratio
|
|
4143
|
+
] : undefined,
|
|
4144
|
+
gradientEnd: endPoint != null ? [
|
|
4145
|
+
endPoint.x / ratio,
|
|
4146
|
+
-endPoint.y / ratio
|
|
4147
|
+
] : undefined
|
|
4148
|
+
};
|
|
4149
|
+
}
|
|
4150
|
+
return undefined;
|
|
4151
|
+
}
|
|
4152
|
+
function reverseLineCap(geCode) {
|
|
4153
|
+
var _map_geCode;
|
|
4154
|
+
var map = {
|
|
4155
|
+
0: IRLineCap.Butt,
|
|
4156
|
+
1: IRLineCap.Round,
|
|
4157
|
+
2: IRLineCap.Square
|
|
4158
|
+
};
|
|
4159
|
+
return (_map_geCode = map[geCode]) != null ? _map_geCode : IRLineCap.Butt;
|
|
4160
|
+
}
|
|
4161
|
+
function reverseLineJoin(geCode) {
|
|
4162
|
+
var _map_geCode;
|
|
4163
|
+
var map = {
|
|
4164
|
+
0: IRLineJoin.Round,
|
|
4165
|
+
1: IRLineJoin.Bevel,
|
|
4166
|
+
2: IRLineJoin.Miter
|
|
4167
|
+
};
|
|
4168
|
+
return (_map_geCode = map[geCode]) != null ? _map_geCode : IRLineJoin.Miter;
|
|
4169
|
+
}
|
|
4170
|
+
function reverseShapeFillRule(geCode) {
|
|
4171
|
+
var _map_geCode;
|
|
4172
|
+
var map = {
|
|
4173
|
+
0: IRShapeFillRule.NonZero,
|
|
4174
|
+
1: IRShapeFillRule.EvenOdd
|
|
4175
|
+
};
|
|
4176
|
+
return (_map_geCode = map[geCode]) != null ? _map_geCode : IRShapeFillRule.NonZero;
|
|
4177
|
+
}
|
|
4178
|
+
function reverseCustomPaths(component, ratio) {
|
|
4179
|
+
var points = component['points'];
|
|
4180
|
+
var easingIns = component['easingIns'];
|
|
4181
|
+
var easingOuts = component['easingOuts'];
|
|
4182
|
+
var shapes = component['shapes'];
|
|
4183
|
+
if (points == null || shapes == null) {
|
|
4184
|
+
return [];
|
|
4185
|
+
}
|
|
4186
|
+
return shapes.map(function(shape) {
|
|
4187
|
+
var pathPoints = [];
|
|
4188
|
+
var pathEasingIns = [];
|
|
4189
|
+
var pathEasingOuts = [];
|
|
4190
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(shape.indexes), _step; !(_step = _iterator()).done;){
|
|
4191
|
+
var idx = _step.value;
|
|
4192
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
4193
|
+
var pt = points[idx.point];
|
|
4194
|
+
var ei = easingIns == null ? void 0 : easingIns[idx.easingIn];
|
|
4195
|
+
var eo = easingOuts == null ? void 0 : easingOuts[idx.easingOut];
|
|
4196
|
+
pathPoints.push({
|
|
4197
|
+
x: pt.x / ratio,
|
|
4198
|
+
y: -pt.y / ratio
|
|
4199
|
+
});
|
|
4200
|
+
pathEasingIns.push({
|
|
4201
|
+
x: ((_ref = ei == null ? void 0 : ei.x) != null ? _ref : 0) / ratio,
|
|
4202
|
+
y: -((_ref1 = ei == null ? void 0 : ei.y) != null ? _ref1 : 0) / ratio
|
|
4203
|
+
});
|
|
4204
|
+
pathEasingOuts.push({
|
|
4205
|
+
x: ((_ref2 = eo == null ? void 0 : eo.x) != null ? _ref2 : 0) / ratio,
|
|
4206
|
+
y: -((_ref3 = eo == null ? void 0 : eo.y) != null ? _ref3 : 0) / ratio
|
|
4207
|
+
});
|
|
4208
|
+
}
|
|
4209
|
+
return {
|
|
4210
|
+
points: pathPoints,
|
|
4211
|
+
easingIns: pathEasingIns,
|
|
4212
|
+
easingOuts: pathEasingOuts,
|
|
4213
|
+
close: shape.close
|
|
4214
|
+
};
|
|
4215
|
+
});
|
|
4216
|
+
}
|
|
4217
|
+
function reverseScaledNumber(shape, component, key, ratio) {
|
|
4218
|
+
var value = component[key];
|
|
4219
|
+
if (typeof value === 'number') {
|
|
4220
|
+
shape[key] = value / ratio;
|
|
4221
|
+
}
|
|
4222
|
+
}
|
|
4223
|
+
function reverseRawNumber(shape, component, key) {
|
|
4224
|
+
var value = component[key];
|
|
4225
|
+
if (typeof value === 'number') {
|
|
4226
|
+
shape[key] = value;
|
|
4227
|
+
}
|
|
4228
|
+
}
|
|
4229
|
+
|
|
4230
|
+
function reverseLayerTiming(delay, duration, frameRate) {
|
|
4231
|
+
var startFrame = Math.round(delay * frameRate * 1000) / 1000;
|
|
4232
|
+
var endFrame = Math.round((delay + duration) * frameRate * 1000) / 1000;
|
|
4233
|
+
return {
|
|
4234
|
+
startFrame: startFrame,
|
|
4235
|
+
endFrame: endFrame
|
|
4236
|
+
};
|
|
4237
|
+
}
|
|
4238
|
+
|
|
4239
|
+
function mergeNullSpritePairs(descriptors, ctx) {
|
|
4240
|
+
var childByParentId = new Map();
|
|
4241
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(descriptors), _step; !(_step = _iterator()).done;){
|
|
4242
|
+
var desc = _step.value;
|
|
4243
|
+
var parentId = desc.item['parentId'];
|
|
4244
|
+
if (parentId != null) {
|
|
4245
|
+
if (!childByParentId.has(parentId)) {
|
|
4246
|
+
childByParentId.set(parentId, []);
|
|
4247
|
+
}
|
|
4248
|
+
childByParentId.get(parentId).push(desc);
|
|
4249
|
+
}
|
|
4250
|
+
}
|
|
4251
|
+
// Pass 1: identify all merge pairs (null parent → sprite child)
|
|
4252
|
+
var mergedChildIds = new Set();
|
|
4253
|
+
var mergeMap = new Map();
|
|
4254
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(descriptors), _step1; !(_step1 = _iterator1()).done;){
|
|
4255
|
+
var desc1 = _step1.value;
|
|
4256
|
+
var isNull = desc1.item['type'] === '3';
|
|
4257
|
+
if (!isNull) {
|
|
4258
|
+
continue;
|
|
4259
|
+
}
|
|
4260
|
+
var children = childByParentId.get(desc1.itemId);
|
|
4261
|
+
if (children == null || children.length === 0) {
|
|
4262
|
+
continue;
|
|
4263
|
+
}
|
|
4264
|
+
// Only merge an UNAMBIGUOUS emitNullSpritePair artifact: a null whose ONLY
|
|
4265
|
+
// child is exactly one same-name visual sprite. ir2ge's emitNullSpritePair
|
|
4266
|
+
// produces precisely this shape (null + one same-name child). If the null
|
|
4267
|
+
// has any OTHER children, it is a genuine Lottie parent null — merging it
|
|
4268
|
+
// into a transformSplit would change the anchor those other children are
|
|
4269
|
+
// parented against, shifting them. Leave such nulls intact.
|
|
4270
|
+
if (children.length !== 1) {
|
|
4271
|
+
continue;
|
|
4272
|
+
}
|
|
4273
|
+
var onlyChild = children[0];
|
|
4274
|
+
var childType = onlyChild.item['type'];
|
|
4275
|
+
var isVisual = childType === '1' || childType === 'text' || childType === 'shape';
|
|
4276
|
+
var sameName = onlyChild.item['name'] === desc1.item['name'];
|
|
4277
|
+
if (!isVisual || !sameName || !hasNoComponents(desc1.item) || !hasVisualComponent(onlyChild, ctx) || !hasSplitPairTiming(desc1, onlyChild, ctx) || !hasParentTransformSignal(desc1, ctx) || !hasNoIndependentChildTransform(onlyChild, ctx)) {
|
|
4278
|
+
continue;
|
|
4279
|
+
}
|
|
4280
|
+
var sameNameChild = onlyChild;
|
|
4281
|
+
mergedChildIds.add(sameNameChild.itemId);
|
|
4282
|
+
mergeMap.set(desc1.itemId, mergeNullAndSprite(desc1, sameNameChild, ctx));
|
|
4283
|
+
}
|
|
4284
|
+
// Pass 2: build result, replacing merged nulls and skipping merged children
|
|
4285
|
+
var result = [];
|
|
4286
|
+
for(var _iterator2 = _create_for_of_iterator_helper_loose(descriptors), _step2; !(_step2 = _iterator2()).done;){
|
|
4287
|
+
var desc2 = _step2.value;
|
|
4288
|
+
if (mergedChildIds.has(desc2.itemId)) {
|
|
4289
|
+
continue;
|
|
4290
|
+
}
|
|
4291
|
+
var merged = mergeMap.get(desc2.itemId);
|
|
4292
|
+
if (merged != null) {
|
|
4293
|
+
result.push(merged);
|
|
4294
|
+
} else {
|
|
4295
|
+
result.push(desc2);
|
|
4296
|
+
}
|
|
4297
|
+
}
|
|
4298
|
+
return result;
|
|
4299
|
+
}
|
|
4300
|
+
function hasNoComponents(item) {
|
|
4301
|
+
var components = item['components'];
|
|
4302
|
+
return !Array.isArray(components) || components.length === 0;
|
|
4303
|
+
}
|
|
4304
|
+
function hasVisualComponent(desc, ctx) {
|
|
4305
|
+
var components = desc.item['components'];
|
|
4306
|
+
if (!Array.isArray(components) || components.length === 0) {
|
|
4307
|
+
return false;
|
|
4308
|
+
}
|
|
4309
|
+
return components.some(function(ref) {
|
|
4310
|
+
var componentId = resolveDataPathId(ref);
|
|
4311
|
+
var component = componentId != null ? ctx.componentById.get(componentId) : undefined;
|
|
4312
|
+
var dataType = component == null ? void 0 : component['dataType'];
|
|
4313
|
+
return dataType === 'SpriteComponent' || dataType === 'TextComponent' || dataType === 'ShapeComponent';
|
|
4314
|
+
});
|
|
4315
|
+
}
|
|
4316
|
+
function hasSplitPairTiming(parent, child, ctx) {
|
|
4317
|
+
var _ref, _ref1;
|
|
4318
|
+
var parentTimeline = parseTimeline(parent.itemId, ctx);
|
|
4319
|
+
var childTimeline = parseTimeline(child.itemId, ctx);
|
|
4320
|
+
var parentEndBehavior = (_ref = parentTimeline == null ? void 0 : parentTimeline.endBehavior) != null ? _ref : readItemEndBehavior(parent.item);
|
|
4321
|
+
var childEndBehavior = (_ref1 = childTimeline == null ? void 0 : childTimeline.endBehavior) != null ? _ref1 : readItemEndBehavior(child.item);
|
|
4322
|
+
if (parentEndBehavior !== 4 || childEndBehavior !== 0) {
|
|
4323
|
+
return false;
|
|
4324
|
+
}
|
|
4325
|
+
if (parentTimeline == null || childTimeline == null) {
|
|
4326
|
+
return true;
|
|
4327
|
+
}
|
|
4328
|
+
return nearlyEqual(parentTimeline.delay, childTimeline.delay) && nearlyEqual(parentTimeline.duration, childTimeline.duration);
|
|
4329
|
+
}
|
|
4330
|
+
function hasParentTransformSignal(desc, ctx) {
|
|
4331
|
+
var timeline = parseTimeline(desc.itemId, ctx);
|
|
4332
|
+
if (hasTransformPayload(timeline == null ? void 0 : timeline.transformAsset)) {
|
|
4333
|
+
return true;
|
|
4334
|
+
}
|
|
4335
|
+
var transform = desc.item['transform'];
|
|
4336
|
+
return isRecord(transform) && (hasNonDefaultScale(transform) || hasNonDefaultEulerHint(transform));
|
|
4337
|
+
}
|
|
4338
|
+
function hasNoIndependentChildTransform(desc, ctx) {
|
|
4339
|
+
var timeline = parseTimeline(desc.itemId, ctx);
|
|
4340
|
+
return (timeline == null ? void 0 : timeline.transformAsset) != null && !hasTransformPayload(timeline.transformAsset);
|
|
4341
|
+
}
|
|
4342
|
+
function hasTransformPayload(asset) {
|
|
4343
|
+
if (asset == null) {
|
|
4344
|
+
return false;
|
|
4345
|
+
}
|
|
4346
|
+
return hasNonEmptyRecord(asset['positionOverLifetime']) || hasNonEmptyRecord(asset['rotationOverLifetime']) || hasNonEmptyRecord(asset['sizeOverLifetime']);
|
|
4347
|
+
}
|
|
4348
|
+
function hasNonDefaultScale(transform) {
|
|
4349
|
+
var scale = transform['scale'];
|
|
4350
|
+
if (!isRecord(scale)) {
|
|
4351
|
+
return false;
|
|
4352
|
+
}
|
|
4353
|
+
var x = typeof scale['x'] === 'number' ? scale['x'] : 1;
|
|
4354
|
+
var y = typeof scale['y'] === 'number' ? scale['y'] : 1;
|
|
4355
|
+
var z = typeof scale['z'] === 'number' ? scale['z'] : 1;
|
|
4356
|
+
return Math.abs(x - 1) > 1e-6 || Math.abs(y - 1) > 1e-6 || Math.abs(z - 1) > 1e-6;
|
|
4357
|
+
}
|
|
4358
|
+
function hasNonDefaultEulerHint(transform) {
|
|
4359
|
+
var eulerHint = transform['eulerHint'];
|
|
4360
|
+
if (!isRecord(eulerHint)) {
|
|
4361
|
+
return false;
|
|
4362
|
+
}
|
|
4363
|
+
var x = typeof eulerHint['x'] === 'number' ? eulerHint['x'] : 0;
|
|
4364
|
+
var y = typeof eulerHint['y'] === 'number' ? eulerHint['y'] : 0;
|
|
4365
|
+
var z = typeof eulerHint['z'] === 'number' ? eulerHint['z'] : 0;
|
|
4366
|
+
return Math.abs(x) > 1e-6 || Math.abs(y) > 1e-6 || Math.abs(z) > 1e-6;
|
|
4367
|
+
}
|
|
4368
|
+
function hasNonEmptyRecord(value) {
|
|
4369
|
+
return isRecord(value) && Object.keys(value).length > 0;
|
|
4370
|
+
}
|
|
4371
|
+
function readItemEndBehavior(item) {
|
|
4372
|
+
var endBehavior = item['endBehavior'];
|
|
4373
|
+
return typeof endBehavior === 'number' ? endBehavior : undefined;
|
|
4374
|
+
}
|
|
4375
|
+
function nearlyEqual(a, b) {
|
|
4376
|
+
return Math.abs(a - b) < 1e-6;
|
|
4377
|
+
}
|
|
4378
|
+
function isRecord(value) {
|
|
4379
|
+
return value != null && (typeof value === "undefined" ? "undefined" : _type_of(value)) === 'object' && !Array.isArray(value);
|
|
4380
|
+
}
|
|
4381
|
+
function mergeNullAndSprite(nullDesc, childDesc, ctx) {
|
|
4382
|
+
var _childDesc_layer_transform;
|
|
4383
|
+
var merged = _extends({}, nullDesc.layer);
|
|
4384
|
+
// Take type from child
|
|
4385
|
+
merged.type = childDesc.layer.type;
|
|
4386
|
+
merged.asset = childDesc.layer.asset;
|
|
4387
|
+
merged.text = childDesc.layer.text;
|
|
4388
|
+
merged.shapes = childDesc.layer.shapes;
|
|
4389
|
+
merged.shapeLayer = childDesc.layer.shapeLayer;
|
|
4390
|
+
merged.solidColor = childDesc.layer.solidColor;
|
|
4391
|
+
merged.blendMode = childDesc.layer.blendMode;
|
|
4392
|
+
merged.transformSplit = true;
|
|
4393
|
+
// Visibility from child
|
|
4394
|
+
merged.visibility = childDesc.layer.visibility;
|
|
4395
|
+
// Compute anchor from child position offset
|
|
4396
|
+
var childTransform = childDesc.item['transform'];
|
|
4397
|
+
var childPosition = childTransform == null ? void 0 : childTransform['position'];
|
|
4398
|
+
var childSize = childTransform == null ? void 0 : childTransform['size'];
|
|
4399
|
+
if (childPosition != null && childSize != null) {
|
|
4400
|
+
var layerWidth = childSize.x / ctx.ratio;
|
|
4401
|
+
var layerHeight = childSize.y / ctx.ratio;
|
|
4402
|
+
var anchorX = -childPosition.x / ctx.ratio + layerWidth / 2;
|
|
4403
|
+
var anchorY = childPosition.y / ctx.ratio + layerHeight / 2;
|
|
4404
|
+
if (merged.transform == null) {
|
|
4405
|
+
merged.transform = {};
|
|
4406
|
+
}
|
|
4407
|
+
merged.transform.anchor = {
|
|
4408
|
+
keyframed: false,
|
|
4409
|
+
value: [
|
|
4410
|
+
anchorX,
|
|
4411
|
+
anchorY,
|
|
4412
|
+
0
|
|
4413
|
+
]
|
|
4414
|
+
};
|
|
4415
|
+
merged.displaySize = {
|
|
4416
|
+
width: layerWidth,
|
|
4417
|
+
height: layerHeight
|
|
4418
|
+
};
|
|
4419
|
+
}
|
|
4420
|
+
// Opacity from child
|
|
4421
|
+
if (((_childDesc_layer_transform = childDesc.layer.transform) == null ? void 0 : _childDesc_layer_transform.opacity) != null) {
|
|
4422
|
+
if (merged.transform == null) {
|
|
4423
|
+
merged.transform = {};
|
|
4424
|
+
}
|
|
4425
|
+
merged.transform.opacity = childDesc.layer.transform.opacity;
|
|
4426
|
+
}
|
|
4427
|
+
// The merged layer renders the child's visual component, but the parent owns
|
|
4428
|
+
// transform animation passthrough. Deep-merge the ge2ir namespace so neither
|
|
4429
|
+
// side overwrites the other's GE round-trip data.
|
|
4430
|
+
if (childDesc.layer.metadata != null) {
|
|
4431
|
+
var _merged_metadata;
|
|
4432
|
+
var parentGE2IR = isRecord((_merged_metadata = merged.metadata) == null ? void 0 : _merged_metadata['ge2ir']) ? merged.metadata['ge2ir'] : undefined;
|
|
4433
|
+
var childGE2IR = isRecord(childDesc.layer.metadata['ge2ir']) ? childDesc.layer.metadata['ge2ir'] : undefined;
|
|
4434
|
+
merged.metadata = _extends({}, merged.metadata, childDesc.layer.metadata);
|
|
4435
|
+
if (parentGE2IR != null || childGE2IR != null) {
|
|
4436
|
+
merged.metadata['ge2ir'] = _extends({}, parentGE2IR != null ? parentGE2IR : {}, childGE2IR != null ? childGE2IR : {});
|
|
4437
|
+
}
|
|
4438
|
+
}
|
|
4439
|
+
return {
|
|
4440
|
+
itemId: nullDesc.itemId,
|
|
4441
|
+
item: nullDesc.item,
|
|
4442
|
+
layer: merged
|
|
4443
|
+
};
|
|
4444
|
+
}
|
|
4445
|
+
function resolveHierarchy(descriptors, ctx) {
|
|
4446
|
+
var idToIndex = new Map();
|
|
4447
|
+
var idToDesc = new Map();
|
|
4448
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(descriptors), _step; !(_step = _iterator()).done;){
|
|
4449
|
+
var desc = _step.value;
|
|
4450
|
+
idToIndex.set(desc.itemId, desc.layer.index);
|
|
4451
|
+
idToDesc.set(desc.itemId, desc);
|
|
4452
|
+
}
|
|
4453
|
+
for(var _iterator1 = _create_for_of_iterator_helper_loose(descriptors), _step1; !(_step1 = _iterator1()).done;){
|
|
4454
|
+
var desc1 = _step1.value;
|
|
4455
|
+
var _desc_layer_transform;
|
|
4456
|
+
var parentId = desc1.item['parentId'];
|
|
4457
|
+
if (parentId == null) {
|
|
4458
|
+
continue;
|
|
4459
|
+
}
|
|
4460
|
+
var parentIndex = idToIndex.get(parentId);
|
|
4461
|
+
var parentDesc = idToDesc.get(parentId);
|
|
4462
|
+
if (parentIndex == null || parentDesc == null) {
|
|
4463
|
+
continue;
|
|
4464
|
+
}
|
|
4465
|
+
desc1.layer.parent = {
|
|
4466
|
+
index: parentIndex,
|
|
4467
|
+
name: parentDesc.layer.name
|
|
4468
|
+
};
|
|
4469
|
+
var parentAnchor = getAnchorFromDesc(parentDesc);
|
|
4470
|
+
var pos = (_desc_layer_transform = desc1.layer.transform) == null ? void 0 : _desc_layer_transform.position;
|
|
4471
|
+
if (pos != null && !pos.keyframed && pos.value != null) {
|
|
4472
|
+
var _pos2d_;
|
|
4473
|
+
var pos2d = pos.value;
|
|
4474
|
+
desc1.layer.transform.position = {
|
|
4475
|
+
keyframed: false,
|
|
4476
|
+
value: [
|
|
4477
|
+
pos2d[0] + (parentAnchor[0] - ctx.width / 2),
|
|
4478
|
+
pos2d[1] + (parentAnchor[1] - ctx.height / 2),
|
|
4479
|
+
(_pos2d_ = pos2d[2]) != null ? _pos2d_ : 0
|
|
4480
|
+
]
|
|
4481
|
+
};
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
function getAnchorFromDesc(desc) {
|
|
4486
|
+
var _desc_layer_transform;
|
|
4487
|
+
var anchor = (_desc_layer_transform = desc.layer.transform) == null ? void 0 : _desc_layer_transform.anchor;
|
|
4488
|
+
if (anchor != null && !anchor.keyframed && Array.isArray(anchor.value) && anchor.value.length >= 2) {
|
|
4489
|
+
return [
|
|
4490
|
+
anchor.value[0],
|
|
4491
|
+
anchor.value[1]
|
|
4492
|
+
];
|
|
4493
|
+
}
|
|
4494
|
+
return [
|
|
4495
|
+
0,
|
|
4496
|
+
0
|
|
4497
|
+
];
|
|
4498
|
+
}
|
|
4499
|
+
|
|
4500
|
+
function convertGEToIR(scene, options) {
|
|
4501
|
+
var ctx = buildSceneContext(scene, options);
|
|
4502
|
+
var itemIds = getCompositionItemIds(scene);
|
|
4503
|
+
// Reverse: GE items are in display order (ir2ge reverses at the end),
|
|
4504
|
+
// IR layers need to be in push order so ir2ge's final reverse restores display order.
|
|
4505
|
+
var reversedItemIds = [].concat(itemIds).reverse();
|
|
4506
|
+
var descriptors = [];
|
|
4507
|
+
var layerIndex = 0;
|
|
4508
|
+
for(var _iterator = _create_for_of_iterator_helper_loose(reversedItemIds), _step; !(_step = _iterator()).done;){
|
|
4509
|
+
var itemId = _step.value;
|
|
4510
|
+
var item = ctx.itemById.get(itemId);
|
|
4511
|
+
if (item == null) {
|
|
4512
|
+
continue;
|
|
4513
|
+
}
|
|
4514
|
+
var layer = parseItemToLayer(item, itemId, layerIndex, ctx);
|
|
4515
|
+
descriptors.push({
|
|
4516
|
+
itemId: itemId,
|
|
4517
|
+
item: item,
|
|
4518
|
+
layer: layer
|
|
4519
|
+
});
|
|
4520
|
+
layerIndex++;
|
|
4521
|
+
}
|
|
4522
|
+
var merged = mergeNullSpritePairs(descriptors, ctx);
|
|
4523
|
+
// Re-index after merge
|
|
4524
|
+
for(var i = 0; i < merged.length; i++){
|
|
4525
|
+
merged[i].layer.index = i;
|
|
4526
|
+
}
|
|
4527
|
+
resolveHierarchy(merged, ctx);
|
|
4528
|
+
var layers = merged.map(function(d) {
|
|
4529
|
+
return d.layer;
|
|
4530
|
+
});
|
|
4531
|
+
return {
|
|
4532
|
+
source: 'ge',
|
|
4533
|
+
name: ctx.compositionName,
|
|
4534
|
+
width: ctx.width,
|
|
4535
|
+
height: ctx.height,
|
|
4536
|
+
frameRate: ctx.frameRate,
|
|
4537
|
+
inPoint: ctx.inPoint,
|
|
4538
|
+
outPoint: ctx.outPoint,
|
|
4539
|
+
backgroundColor: ctx.backgroundColor,
|
|
4540
|
+
endBehavior: ctx.endBehavior,
|
|
4541
|
+
layers: layers
|
|
4542
|
+
};
|
|
4543
|
+
}
|
|
4544
|
+
function parseItemToLayer(item, itemId, index, ctx) {
|
|
4545
|
+
var _item_name, _item_visible, _ref, _item_delay, _ref1, _item_duration;
|
|
4546
|
+
var _item_transform;
|
|
4547
|
+
var name = (_item_name = item['name']) != null ? _item_name : "layer_" + index;
|
|
4548
|
+
var geType = item['type'];
|
|
4549
|
+
var visible = (_item_visible = item['visible']) != null ? _item_visible : true;
|
|
4550
|
+
var rawTransformPassthrough;
|
|
4551
|
+
var timeline = parseTimeline(itemId, ctx);
|
|
4552
|
+
var delay = (_ref = timeline == null ? void 0 : timeline.delay) != null ? _ref : (_item_delay = item['delay']) != null ? _item_delay : 0;
|
|
4553
|
+
var duration = (_ref1 = timeline == null ? void 0 : timeline.duration) != null ? _ref1 : (_item_duration = item['duration']) != null ? _item_duration : 0;
|
|
4554
|
+
var time = reverseLayerTiming(delay, duration, ctx.frameRate);
|
|
4555
|
+
var componentData = parseComponent(item, ctx);
|
|
4556
|
+
var type;
|
|
4557
|
+
if (geType === '3') {
|
|
4558
|
+
type = 'null';
|
|
4559
|
+
} else if ((componentData == null ? void 0 : componentData.type) === 'text' || geType === 'text') {
|
|
4560
|
+
type = 'text';
|
|
4561
|
+
} else if ((componentData == null ? void 0 : componentData.type) === 'shape' || geType === 'shape') {
|
|
4562
|
+
type = 'shape';
|
|
4563
|
+
} else if ((componentData == null ? void 0 : componentData.type) === 'image') {
|
|
4564
|
+
type = 'image';
|
|
4565
|
+
} else if ((componentData == null ? void 0 : componentData.solidColor) != null) {
|
|
4566
|
+
type = 'solid';
|
|
4567
|
+
} else if (geType === '1') {
|
|
4568
|
+
type = 'solid';
|
|
4569
|
+
} else {
|
|
4570
|
+
type = 'null';
|
|
4571
|
+
}
|
|
4572
|
+
// Parse transforms
|
|
4573
|
+
var itemTransform = item['transform'];
|
|
4574
|
+
var transform;
|
|
4575
|
+
if (itemTransform != null) {
|
|
4576
|
+
var staticChannels = parseStaticTransform(itemTransform, ctx);
|
|
4577
|
+
transform = _extends({}, staticChannels);
|
|
4578
|
+
// Text layers carry their pixel-sizing scale on transform.scale
|
|
4579
|
+
// (scale = ratio × displaySize). ir2ge RECOMPUTES this item scale from
|
|
4580
|
+
// displaySize in processVisualLayer, so keeping it in the IR scale channel
|
|
4581
|
+
// would make buildSizeAnim emit a duplicate sizeOverLifetime constant that
|
|
4582
|
+
// double-scales the glyphs (garbled/stretched text). Drop the static scale
|
|
4583
|
+
// for text; genuine text scale animation still rides through
|
|
4584
|
+
// metadata.ge2ir.sizeOverLifetime passthrough.
|
|
4585
|
+
if (type === 'text') {
|
|
4586
|
+
delete transform.scale;
|
|
4587
|
+
}
|
|
4588
|
+
}
|
|
4589
|
+
// Parse animation from timeline tracks — passthrough raw GE animation data
|
|
4590
|
+
// via metadata. Converting to IR keyframes and back would lose data (ir2ge
|
|
4591
|
+
// only handles specific ValueType variants and makes assumptions about
|
|
4592
|
+
// static positions). The raw data is injected verbatim by ir2ge.
|
|
4593
|
+
if ((timeline == null ? void 0 : timeline.transformAsset) != null) {
|
|
4594
|
+
var asset = timeline.transformAsset;
|
|
4595
|
+
var animChannels = parseTransformAnimation(asset, time.startFrame, time.endFrame, ctx);
|
|
4596
|
+
if (transform == null) {
|
|
4597
|
+
transform = {};
|
|
4598
|
+
}
|
|
4599
|
+
// Use parsed IR channels when available (CONSTANT/BEZIER_CURVE types),
|
|
4600
|
+
// but also store raw data for passthrough of unsupported types (LINE_SEGMENTS etc.)
|
|
4601
|
+
if (animChannels.rotation != null) {
|
|
4602
|
+
transform.rotation = animChannels.rotation;
|
|
4603
|
+
}
|
|
4604
|
+
if (animChannels.separatedRotation != null) {
|
|
4605
|
+
transform.separatedRotation = animChannels.separatedRotation;
|
|
4606
|
+
delete transform.rotation;
|
|
4607
|
+
}
|
|
4608
|
+
if (animChannels.scale != null) {
|
|
4609
|
+
transform.scale = animChannels.scale;
|
|
4610
|
+
}
|
|
4611
|
+
// Passthrough raw animation data for channels that can't round-trip through IR
|
|
4612
|
+
var rawPassthrough = {};
|
|
4613
|
+
var posOL = asset['positionOverLifetime'];
|
|
4614
|
+
var rotOL = asset['rotationOverLifetime'];
|
|
4615
|
+
var sizeOL = asset['sizeOverLifetime'];
|
|
4616
|
+
if (posOL != null && posOL['path'] != null) {
|
|
4617
|
+
rawPassthrough.positionOverLifetime = posOL;
|
|
4618
|
+
}
|
|
4619
|
+
if (rotOL != null && Object.keys(rotOL).length > 0) {
|
|
4620
|
+
rawPassthrough.rotationOverLifetime = rotOL;
|
|
4621
|
+
}
|
|
4622
|
+
if (sizeOL != null && Object.keys(sizeOL).length > 0) {
|
|
4623
|
+
rawPassthrough.sizeOverLifetime = sizeOL;
|
|
4624
|
+
}
|
|
4625
|
+
if (Object.keys(rawPassthrough).length > 0) {
|
|
4626
|
+
rawTransformPassthrough = rawPassthrough;
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
// Parse opacity
|
|
4630
|
+
var rawColorOverLifetime;
|
|
4631
|
+
if ((timeline == null ? void 0 : timeline.spriteColorAsset) != null) {
|
|
4632
|
+
var opacity = parseOpacityAnimation(timeline.spriteColorAsset, time.startFrame, time.endFrame);
|
|
4633
|
+
if (opacity != null) {
|
|
4634
|
+
if (transform == null) {
|
|
4635
|
+
transform = {};
|
|
4636
|
+
}
|
|
4637
|
+
transform.opacity = opacity;
|
|
4638
|
+
}
|
|
4639
|
+
var col = timeline.spriteColorAsset['colorOverLifetime'];
|
|
4640
|
+
if (col != null && Object.keys(col).length > 0) {
|
|
4641
|
+
rawColorOverLifetime = col;
|
|
4642
|
+
}
|
|
4643
|
+
}
|
|
4644
|
+
// Anchor from component — default to center (0.5, 0.5) when not explicitly set
|
|
4645
|
+
if (type !== 'null') {
|
|
4646
|
+
var _item_transform1;
|
|
4647
|
+
var itemSize = (_item_transform1 = item['transform']) == null ? void 0 : _item_transform1['size'];
|
|
4648
|
+
if (itemSize != null) {
|
|
4649
|
+
var _ref2;
|
|
4650
|
+
var layerWidth = itemSize.x / ctx.ratio;
|
|
4651
|
+
var layerHeight = itemSize.y / ctx.ratio;
|
|
4652
|
+
var anchorScale = (_ref2 = componentData == null ? void 0 : componentData.anchorScale) != null ? _ref2 : [
|
|
4653
|
+
0.5,
|
|
4654
|
+
0.5
|
|
4655
|
+
];
|
|
4656
|
+
var anchorX = anchorScale[0] * layerWidth;
|
|
4657
|
+
var anchorY = anchorScale[1] * layerHeight;
|
|
4658
|
+
if (transform == null) {
|
|
4659
|
+
transform = {};
|
|
4660
|
+
}
|
|
4661
|
+
transform.anchor = {
|
|
4662
|
+
keyframed: false,
|
|
4663
|
+
value: [
|
|
4664
|
+
anchorX,
|
|
4665
|
+
anchorY,
|
|
4666
|
+
0
|
|
4667
|
+
]
|
|
4668
|
+
};
|
|
4669
|
+
// Reverse the position adjustments ir2ge's processVisualLayer re-applies
|
|
4670
|
+
// for non-centered anchors, so they don't double-apply on round-trip.
|
|
4671
|
+
// Forward order (in 2D-px equivalent): pos += anchorOffset (computeStaticPosition),
|
|
4672
|
+
// then pos += scaleAdjust (applyScalePositionAdjust). We subtract both.
|
|
4673
|
+
var pos = transform.position;
|
|
4674
|
+
if (pos != null && !pos.keyframed && pos.value != null) {
|
|
4675
|
+
var _scale_, _scale_1;
|
|
4676
|
+
var _transform_scale;
|
|
4677
|
+
// anchorOffset = -(anchor - size/2), added to the raw 2D position.
|
|
4678
|
+
var anchorOffsetX = -(anchorX - layerWidth / 2);
|
|
4679
|
+
var anchorOffsetY = -(anchorY - layerHeight / 2);
|
|
4680
|
+
// scaleAdjust (only when static scale != 1 and anchor off-center by >0.5px):
|
|
4681
|
+
// 3D: x += anchorDiffX*(1-sx)*ratio ; y -= anchorDiffY*(1-sy)*ratio
|
|
4682
|
+
// In 2D-px (÷ratio, y-axis flips sign): x2d += anchorDiffX*(1-sx) ;
|
|
4683
|
+
// y2d += anchorDiffY*(1-sy) (the two sign flips cancel).
|
|
4684
|
+
var scale = ((_transform_scale = transform.scale) == null ? void 0 : _transform_scale.keyframed) === false && Array.isArray(transform.scale.value) ? transform.scale.value : [
|
|
4685
|
+
1,
|
|
4686
|
+
1,
|
|
4687
|
+
1
|
|
4688
|
+
];
|
|
4689
|
+
var sx = (_scale_ = scale[0]) != null ? _scale_ : 1;
|
|
4690
|
+
var sy = (_scale_1 = scale[1]) != null ? _scale_1 : 1;
|
|
4691
|
+
var anchorDiffX = anchorX - layerWidth / 2;
|
|
4692
|
+
var anchorDiffY = anchorY - layerHeight / 2;
|
|
4693
|
+
var anchorOffCenter = Math.abs(anchorDiffX) > 0.5 || Math.abs(anchorDiffY) > 0.5;
|
|
4694
|
+
var hasStaticScale = !(sx === 1 && sy === 1);
|
|
4695
|
+
var scaleAdjustX = 0;
|
|
4696
|
+
var scaleAdjustY = 0;
|
|
4697
|
+
if (hasStaticScale && anchorOffCenter && layerWidth > 0 && layerHeight > 0) {
|
|
4698
|
+
scaleAdjustX = anchorDiffX * (1 - sx);
|
|
4699
|
+
scaleAdjustY = anchorDiffY * (1 - sy);
|
|
4700
|
+
}
|
|
4701
|
+
var totalX = anchorOffsetX + scaleAdjustX;
|
|
4702
|
+
var totalY = anchorOffsetY + scaleAdjustY;
|
|
4703
|
+
if (Math.abs(totalX) > 1e-6 || Math.abs(totalY) > 1e-6) {
|
|
4704
|
+
var _pos_value_;
|
|
4705
|
+
transform.position = {
|
|
4706
|
+
keyframed: false,
|
|
4707
|
+
value: [
|
|
4708
|
+
pos.value[0] - totalX,
|
|
4709
|
+
pos.value[1] - totalY,
|
|
4710
|
+
(_pos_value_ = pos.value[2]) != null ? _pos_value_ : 0
|
|
4711
|
+
]
|
|
4712
|
+
};
|
|
4713
|
+
}
|
|
4714
|
+
}
|
|
4715
|
+
}
|
|
4716
|
+
}
|
|
4717
|
+
// Display size from item transform.size
|
|
4718
|
+
var displaySize;
|
|
4719
|
+
var itemSize1 = (_item_transform = item['transform']) == null ? void 0 : _item_transform['size'];
|
|
4720
|
+
if (itemSize1 != null) {
|
|
4721
|
+
displaySize = {
|
|
4722
|
+
width: itemSize1.x / ctx.ratio,
|
|
4723
|
+
height: itemSize1.y / ctx.ratio
|
|
4724
|
+
};
|
|
4725
|
+
}
|
|
4726
|
+
var layer = {
|
|
4727
|
+
index: index,
|
|
4728
|
+
name: name,
|
|
4729
|
+
type: type,
|
|
4730
|
+
time: time,
|
|
4731
|
+
visibility: {
|
|
4732
|
+
hidden: !visible,
|
|
4733
|
+
enabled: visible
|
|
4734
|
+
},
|
|
4735
|
+
transform: transform,
|
|
4736
|
+
displaySize: displaySize
|
|
4737
|
+
};
|
|
4738
|
+
if ((componentData == null ? void 0 : componentData.asset) != null) {
|
|
4739
|
+
layer.asset = componentData.asset;
|
|
4740
|
+
}
|
|
4741
|
+
if ((componentData == null ? void 0 : componentData.solidColor) != null) {
|
|
4742
|
+
layer.solidColor = componentData.solidColor;
|
|
4743
|
+
}
|
|
4744
|
+
if ((componentData == null ? void 0 : componentData.text) != null) {
|
|
4745
|
+
layer.text = componentData.text;
|
|
4746
|
+
}
|
|
4747
|
+
if ((componentData == null ? void 0 : componentData.shapes) != null) {
|
|
4748
|
+
layer.shapes = componentData.shapes;
|
|
4749
|
+
}
|
|
4750
|
+
if ((componentData == null ? void 0 : componentData.blendMode) != null) {
|
|
4751
|
+
layer.blendMode = componentData.blendMode;
|
|
4752
|
+
}
|
|
4753
|
+
var geComponentId = componentData == null ? void 0 : componentData.geComponentId;
|
|
4754
|
+
var rawMask = componentData == null ? void 0 : componentData.rawMask;
|
|
4755
|
+
if (rawTransformPassthrough != null || rawColorOverLifetime != null || geComponentId != null || rawMask != null) {
|
|
4756
|
+
// Mask round-trip: geComponentId is the rendezvous key linking a target's
|
|
4757
|
+
// mask.reference.id (a GE1 component id) to the regenerated GE2 component id.
|
|
4758
|
+
// ir2ge copies ge2ir.geMask onto the rebuilt component and a post-process pass
|
|
4759
|
+
// remaps the stale reference id.
|
|
4760
|
+
var ge2irMetadata = _extends({}, rawTransformPassthrough != null ? rawTransformPassthrough : {}, rawColorOverLifetime != null && {
|
|
4761
|
+
colorOverLifetime: rawColorOverLifetime
|
|
4762
|
+
}, geComponentId != null && {
|
|
4763
|
+
geComponentId: geComponentId
|
|
4764
|
+
}, rawMask != null && {
|
|
4765
|
+
geMask: rawMask
|
|
4766
|
+
});
|
|
4767
|
+
layer.metadata = _extends({}, layer.metadata, {
|
|
4768
|
+
ge2ir: ge2irMetadata
|
|
4769
|
+
});
|
|
4770
|
+
}
|
|
4771
|
+
return layer;
|
|
4772
|
+
}
|
|
4773
|
+
|
|
4774
|
+
/**
|
|
4775
|
+
* Read-side accessors for the `IRLayerNode.specific.lottie` slot.
|
|
4776
|
+
*
|
|
4777
|
+
* The shared generator must not branch on lottie semantics directly — every
|
|
4778
|
+
* lottie-specific read goes through these helpers so the rest of `ir2ge` stays
|
|
4779
|
+
* agnostic to the producing tool.
|
|
4780
|
+
*
|
|
4781
|
+
* `isTransformOnlyParentLink` used to live here, reading
|
|
4782
|
+
* `specific.lottie.explicitParent`. It was promoted to a generic IR field
|
|
4783
|
+
* (`IRLayerReference.linkKind`); the accessor now lives at `./parent-link.ts`.
|
|
4784
|
+
*/ function readLottieSpecific(layer) {
|
|
4785
|
+
var _layer_specific;
|
|
4786
|
+
return (_layer_specific = layer.specific) == null ? void 0 : _layer_specific.lottie;
|
|
4787
|
+
}
|
|
4788
|
+
|
|
4789
|
+
export { DEFAULT_CAMERA_FOV, DEFAULT_CAMERA_Z, DEFAULT_CLIP_MODE, assembleScene, buildTimelineTracks, convert2dTo3dPoint, convertGEToIR, convertIRToGE, createId, estimateTextWidth, get2dTo3dRatio, irPositionKeyframesToGE, irScalarKeyframesToGE, irVectorKeyframesToGE, isTransformOnlyParentLink, lerp, normalizeChildVisibilityByParentDelays, readLottieSpecific, roundNumber, shouldUseKeyframeMode, toDataPath };
|
|
4790
|
+
//# sourceMappingURL=index.mjs.map
|