@clipkit/runtime 1.0.0

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.
Files changed (219) hide show
  1. package/LICENSE +54 -0
  2. package/README.md +98 -0
  3. package/dist/animation/easings.d.ts +9 -0
  4. package/dist/animation/easings.d.ts.map +1 -0
  5. package/dist/animation/easings.js +230 -0
  6. package/dist/animation/easings.js.map +1 -0
  7. package/dist/animation/expr.d.ts +44 -0
  8. package/dist/animation/expr.d.ts.map +1 -0
  9. package/dist/animation/expr.js +236 -0
  10. package/dist/animation/expr.js.map +1 -0
  11. package/dist/animation/keyframes.d.ts +23 -0
  12. package/dist/animation/keyframes.d.ts.map +1 -0
  13. package/dist/animation/keyframes.js +117 -0
  14. package/dist/animation/keyframes.js.map +1 -0
  15. package/dist/animation/motion-path.d.ts +18 -0
  16. package/dist/animation/motion-path.d.ts.map +1 -0
  17. package/dist/animation/motion-path.js +269 -0
  18. package/dist/animation/motion-path.js.map +1 -0
  19. package/dist/animation/noise1d.d.ts +5 -0
  20. package/dist/animation/noise1d.d.ts.map +1 -0
  21. package/dist/animation/noise1d.js +27 -0
  22. package/dist/animation/noise1d.js.map +1 -0
  23. package/dist/animation/presets.d.ts +60 -0
  24. package/dist/animation/presets.d.ts.map +1 -0
  25. package/dist/animation/presets.js +221 -0
  26. package/dist/animation/presets.js.map +1 -0
  27. package/dist/assets/cache.d.ts +18 -0
  28. package/dist/assets/cache.d.ts.map +1 -0
  29. package/dist/assets/cache.js +56 -0
  30. package/dist/assets/cache.js.map +1 -0
  31. package/dist/assets/fonts.d.ts +20 -0
  32. package/dist/assets/fonts.d.ts.map +1 -0
  33. package/dist/assets/fonts.js +127 -0
  34. package/dist/assets/fonts.js.map +1 -0
  35. package/dist/assets/loader.d.ts +18 -0
  36. package/dist/assets/loader.d.ts.map +1 -0
  37. package/dist/assets/loader.js +87 -0
  38. package/dist/assets/loader.js.map +1 -0
  39. package/dist/assets/lut.d.ts +5 -0
  40. package/dist/assets/lut.d.ts.map +1 -0
  41. package/dist/assets/lut.js +77 -0
  42. package/dist/assets/lut.js.map +1 -0
  43. package/dist/assets/media-time.d.ts +31 -0
  44. package/dist/assets/media-time.d.ts.map +1 -0
  45. package/dist/assets/media-time.js +65 -0
  46. package/dist/assets/media-time.js.map +1 -0
  47. package/dist/assets/mp4-frame-source.d.ts +44 -0
  48. package/dist/assets/mp4-frame-source.d.ts.map +1 -0
  49. package/dist/assets/mp4-frame-source.js +387 -0
  50. package/dist/assets/mp4-frame-source.js.map +1 -0
  51. package/dist/audio/encoder.d.ts +31 -0
  52. package/dist/audio/encoder.d.ts.map +1 -0
  53. package/dist/audio/encoder.js +96 -0
  54. package/dist/audio/encoder.js.map +1 -0
  55. package/dist/audio/fades.d.ts +16 -0
  56. package/dist/audio/fades.d.ts.map +1 -0
  57. package/dist/audio/fades.js +43 -0
  58. package/dist/audio/fades.js.map +1 -0
  59. package/dist/audio/limiter.d.ts +8 -0
  60. package/dist/audio/limiter.d.ts.map +1 -0
  61. package/dist/audio/limiter.js +39 -0
  62. package/dist/audio/limiter.js.map +1 -0
  63. package/dist/audio/loader.d.ts +6 -0
  64. package/dist/audio/loader.d.ts.map +1 -0
  65. package/dist/audio/loader.js +42 -0
  66. package/dist/audio/loader.js.map +1 -0
  67. package/dist/audio/mixer.d.ts +17 -0
  68. package/dist/audio/mixer.d.ts.map +1 -0
  69. package/dist/audio/mixer.js +204 -0
  70. package/dist/audio/mixer.js.map +1 -0
  71. package/dist/audio/varispeed.d.ts +24 -0
  72. package/dist/audio/varispeed.d.ts.map +1 -0
  73. package/dist/audio/varispeed.js +114 -0
  74. package/dist/audio/varispeed.js.map +1 -0
  75. package/dist/audio/wav.d.ts +6 -0
  76. package/dist/audio/wav.d.ts.map +1 -0
  77. package/dist/audio/wav.js +62 -0
  78. package/dist/audio/wav.js.map +1 -0
  79. package/dist/backend/backend.d.ts +579 -0
  80. package/dist/backend/backend.d.ts.map +1 -0
  81. package/dist/backend/backend.js +17 -0
  82. package/dist/backend/backend.js.map +1 -0
  83. package/dist/backend/webgl-backend.d.ts +97 -0
  84. package/dist/backend/webgl-backend.d.ts.map +1 -0
  85. package/dist/backend/webgl-backend.js +2142 -0
  86. package/dist/backend/webgl-backend.js.map +1 -0
  87. package/dist/backend/webgpu-backend.d.ts +121 -0
  88. package/dist/backend/webgpu-backend.d.ts.map +1 -0
  89. package/dist/backend/webgpu-backend.js +2481 -0
  90. package/dist/backend/webgpu-backend.js.map +1 -0
  91. package/dist/compositor/bitfont.d.ts +8 -0
  92. package/dist/compositor/bitfont.d.ts.map +1 -0
  93. package/dist/compositor/bitfont.js +52 -0
  94. package/dist/compositor/bitfont.js.map +1 -0
  95. package/dist/compositor/camera.d.ts +5 -0
  96. package/dist/compositor/camera.d.ts.map +1 -0
  97. package/dist/compositor/camera.js +114 -0
  98. package/dist/compositor/camera.js.map +1 -0
  99. package/dist/compositor/color.d.ts +26 -0
  100. package/dist/compositor/color.d.ts.map +1 -0
  101. package/dist/compositor/color.js +189 -0
  102. package/dist/compositor/color.js.map +1 -0
  103. package/dist/compositor/element-renderers/caption.d.ts +4 -0
  104. package/dist/compositor/element-renderers/caption.d.ts.map +1 -0
  105. package/dist/compositor/element-renderers/caption.js +376 -0
  106. package/dist/compositor/element-renderers/caption.js.map +1 -0
  107. package/dist/compositor/element-renderers/group.d.ts +12 -0
  108. package/dist/compositor/element-renderers/group.d.ts.map +1 -0
  109. package/dist/compositor/element-renderers/group.js +259 -0
  110. package/dist/compositor/element-renderers/group.js.map +1 -0
  111. package/dist/compositor/element-renderers/image.d.ts +4 -0
  112. package/dist/compositor/element-renderers/image.d.ts.map +1 -0
  113. package/dist/compositor/element-renderers/image.js +97 -0
  114. package/dist/compositor/element-renderers/image.js.map +1 -0
  115. package/dist/compositor/element-renderers/lit.d.ts +6 -0
  116. package/dist/compositor/element-renderers/lit.d.ts.map +1 -0
  117. package/dist/compositor/element-renderers/lit.js +82 -0
  118. package/dist/compositor/element-renderers/lit.js.map +1 -0
  119. package/dist/compositor/element-renderers/particles.d.ts +4 -0
  120. package/dist/compositor/element-renderers/particles.d.ts.map +1 -0
  121. package/dist/compositor/element-renderers/particles.js +212 -0
  122. package/dist/compositor/element-renderers/particles.js.map +1 -0
  123. package/dist/compositor/element-renderers/shape.d.ts +4 -0
  124. package/dist/compositor/element-renderers/shape.d.ts.map +1 -0
  125. package/dist/compositor/element-renderers/shape.js +171 -0
  126. package/dist/compositor/element-renderers/shape.js.map +1 -0
  127. package/dist/compositor/element-renderers/svg.d.ts +4 -0
  128. package/dist/compositor/element-renderers/svg.d.ts.map +1 -0
  129. package/dist/compositor/element-renderers/svg.js +210 -0
  130. package/dist/compositor/element-renderers/svg.js.map +1 -0
  131. package/dist/compositor/element-renderers/text.d.ts +25 -0
  132. package/dist/compositor/element-renderers/text.d.ts.map +1 -0
  133. package/dist/compositor/element-renderers/text.js +1358 -0
  134. package/dist/compositor/element-renderers/text.js.map +1 -0
  135. package/dist/compositor/element-renderers/video.d.ts +12 -0
  136. package/dist/compositor/element-renderers/video.d.ts.map +1 -0
  137. package/dist/compositor/element-renderers/video.js +109 -0
  138. package/dist/compositor/element-renderers/video.js.map +1 -0
  139. package/dist/compositor/fit.d.ts +18 -0
  140. package/dist/compositor/fit.d.ts.map +1 -0
  141. package/dist/compositor/fit.js +106 -0
  142. package/dist/compositor/fit.js.map +1 -0
  143. package/dist/compositor/lighting.d.ts +63 -0
  144. package/dist/compositor/lighting.d.ts.map +1 -0
  145. package/dist/compositor/lighting.js +141 -0
  146. package/dist/compositor/lighting.js.map +1 -0
  147. package/dist/compositor/mat4.d.ts +88 -0
  148. package/dist/compositor/mat4.d.ts.map +1 -0
  149. package/dist/compositor/mat4.js +245 -0
  150. package/dist/compositor/mat4.js.map +1 -0
  151. package/dist/compositor/project.d.ts +24 -0
  152. package/dist/compositor/project.d.ts.map +1 -0
  153. package/dist/compositor/project.js +105 -0
  154. package/dist/compositor/project.js.map +1 -0
  155. package/dist/compositor/render-context.d.ts +194 -0
  156. package/dist/compositor/render-context.d.ts.map +1 -0
  157. package/dist/compositor/render-context.js +10 -0
  158. package/dist/compositor/render-context.js.map +1 -0
  159. package/dist/compositor/resolve.d.ts +80 -0
  160. package/dist/compositor/resolve.d.ts.map +1 -0
  161. package/dist/compositor/resolve.js +276 -0
  162. package/dist/compositor/resolve.js.map +1 -0
  163. package/dist/compositor/scene.d.ts +10 -0
  164. package/dist/compositor/scene.d.ts.map +1 -0
  165. package/dist/compositor/scene.js +658 -0
  166. package/dist/compositor/scene.js.map +1 -0
  167. package/dist/compositor/transform.d.ts +73 -0
  168. package/dist/compositor/transform.d.ts.map +1 -0
  169. package/dist/compositor/transform.js +229 -0
  170. package/dist/compositor/transform.js.map +1 -0
  171. package/dist/compositor/unit.d.ts +27 -0
  172. package/dist/compositor/unit.d.ts.map +1 -0
  173. package/dist/compositor/unit.js +74 -0
  174. package/dist/compositor/unit.js.map +1 -0
  175. package/dist/encoder/exporter.d.ts +95 -0
  176. package/dist/encoder/exporter.d.ts.map +1 -0
  177. package/dist/encoder/exporter.js +341 -0
  178. package/dist/encoder/exporter.js.map +1 -0
  179. package/dist/encoder/index.d.ts +3 -0
  180. package/dist/encoder/index.d.ts.map +1 -0
  181. package/dist/encoder/index.js +2 -0
  182. package/dist/encoder/index.js.map +1 -0
  183. package/dist/index.d.ts +12 -0
  184. package/dist/index.d.ts.map +1 -0
  185. package/dist/index.js +27 -0
  186. package/dist/index.js.map +1 -0
  187. package/dist/logger.d.ts +13 -0
  188. package/dist/logger.d.ts.map +1 -0
  189. package/dist/logger.js +32 -0
  190. package/dist/logger.js.map +1 -0
  191. package/dist/runtime.d.ts +216 -0
  192. package/dist/runtime.d.ts.map +1 -0
  193. package/dist/runtime.js +1012 -0
  194. package/dist/runtime.js.map +1 -0
  195. package/dist/svg/morph.d.ts +6 -0
  196. package/dist/svg/morph.d.ts.map +1 -0
  197. package/dist/svg/morph.js +62 -0
  198. package/dist/svg/morph.js.map +1 -0
  199. package/dist/svg/svg-renderer.d.ts +18 -0
  200. package/dist/svg/svg-renderer.d.ts.map +1 -0
  201. package/dist/svg/svg-renderer.js +142 -0
  202. package/dist/svg/svg-renderer.js.map +1 -0
  203. package/dist/text/caption-chunk.d.ts +17 -0
  204. package/dist/text/caption-chunk.d.ts.map +1 -0
  205. package/dist/text/caption-chunk.js +76 -0
  206. package/dist/text/caption-chunk.js.map +1 -0
  207. package/dist/text/font-atlas.d.ts +63 -0
  208. package/dist/text/font-atlas.d.ts.map +1 -0
  209. package/dist/text/font-atlas.js +225 -0
  210. package/dist/text/font-atlas.js.map +1 -0
  211. package/dist/text/measure.d.ts +38 -0
  212. package/dist/text/measure.d.ts.map +1 -0
  213. package/dist/text/measure.js +164 -0
  214. package/dist/text/measure.js.map +1 -0
  215. package/dist/text/text-animation.d.ts +52 -0
  216. package/dist/text/text-animation.d.ts.map +1 -0
  217. package/dist/text/text-animation.js +133 -0
  218. package/dist/text/text-animation.js.map +1 -0
  219. package/package.json +47 -0
@@ -0,0 +1,259 @@
1
+ import { interpolateKeyframes } from '../../animation/keyframes.js';
2
+ import { applyModelTransform, mat4Identity, mat4Multiply, mat4TRS, mat4TRS3D, quadWorldTransform } from '../mat4.js';
3
+ import { resolveAnchor, resolveLength } from '../unit.js';
4
+ import { anchorToCenter } from '../transform.js';
5
+ import { applyAnimation, depthOrder, resolve3D, resolveScalePair } from '../resolve.js';
6
+ import { resolveMaterial } from '../lighting.js';
7
+ import { buildLitParams } from './lit.js';
8
+ import { getLogger } from '../../logger.js';
9
+ // A flattened group card lights from its layer pixels, so the albedo
10
+ // color is unused by the lit-textured shader — pass white.
11
+ const WHITE = [1, 1, 1, 1];
12
+ /**
13
+ * Render a group element. Pushes the group's transform / opacity / time
14
+ * scope, then walks children. Stack is restored on return.
15
+ *
16
+ * Layers within a group establish local paint order — children render
17
+ * in descending-layer order (layer 1 on top), just like at the top
18
+ * level.
19
+ */
20
+ export function renderGroupElement(el, ctx) {
21
+ // Time-window check against the local timeline. ctx.time is global;
22
+ // we compare against the group's global start + duration.
23
+ const groupStart = ctx.timeOffset + numberOr(el.time, 0);
24
+ const groupDur = parseDuration(el.duration, ctx.sourceDuration - groupStart);
25
+ if (ctx.time < groupStart || ctx.time > groupStart + groupDur)
26
+ return;
27
+ // §5.8.4 time_remap: the SUBTREE runs on a warped clock. The group's
28
+ // own animations (opacity/rotation/scale below) read REAL time; only
29
+ // children see the warp. ctx.time is swapped while children render.
30
+ const prevGlobalTime = ctx.time;
31
+ const warpedTime = Array.isArray(el.time_remap) && el.time_remap.length > 0
32
+ ? groupStart + Math.max(0, interpolateKeyframes(el.time_remap, ctx.time - groupStart))
33
+ : ctx.time;
34
+ const opacity01 = applyAnimation(el, 'opacity', numberOr(el.opacity, 1), ctx);
35
+ const opFactor = Math.max(0, Math.min(1, opacity01));
36
+ if (opFactor === 0)
37
+ return;
38
+ const { canvas } = ctx;
39
+ const x = resolveLength(el.x, canvas.width, canvas);
40
+ const y = resolveLength(el.y, canvas.height, canvas);
41
+ const width = el.width !== undefined
42
+ ? resolveLength(el.width, canvas.width, canvas)
43
+ : 0;
44
+ const height = el.height !== undefined
45
+ ? resolveLength(el.height, canvas.height, canvas)
46
+ : 0;
47
+ const ax = resolveAnchor(el.x_anchor);
48
+ const ay = resolveAnchor(el.y_anchor);
49
+ const rotation = applyAnimation(el, 'rotation', numberOr(el.rotation ?? el.z_rotation, 0), ctx);
50
+ const { sx, sy } = resolveScalePair(el, ctx);
51
+ // CKP/1.0 3D (§4.4): groups with 3D fields stack a general matrix
52
+ // (plain path) or project their flattened layer's quad (clip/mask).
53
+ const t3d = resolve3D(el, ctx);
54
+ // Render children in descending `layer` order (local paint order,
55
+ // layer 1 on top). The plain-group path below re-orders by depth
56
+ // (`z`) when ctx.depthSort is set; the flattened layer keeps this
57
+ // layer order (its children are coplanar in the flat layer).
58
+ const sortedChildren = [...el.elements].sort((a, b) => numberOr(b.layer, Number.MAX_SAFE_INTEGER) - numberOr(a.layer, Number.MAX_SAFE_INTEGER));
59
+ const dispatch = ctx
60
+ ._dispatch;
61
+ const prevMatrix = ctx.modelMatrix;
62
+ const prevWorld = ctx.worldMatrix;
63
+ const prevOpacity = ctx.opacityFactor;
64
+ const prevTime = ctx.timeOffset;
65
+ const prevSurfW = ctx.surfaceWidth;
66
+ const prevSurfH = ctx.surfaceHeight;
67
+ // ── Layered paths (clip and/or mask): render children into an
68
+ // offscreen layer the size of the group's box, optionally render the
69
+ // mask elements into a second layer, then composite with the group's
70
+ // transform + opacity. Layer bounds do the clipping (mask implies
71
+ // clip — both layers are box-sized).
72
+ if (el.clip === true || el.mask) {
73
+ if (width <= 0 || height <= 0) {
74
+ getLogger().warn('group clip/mask requires explicit width and height — skipping');
75
+ }
76
+ else {
77
+ const renderIntoLayer = (key, elements) => {
78
+ let entry = ctx.groupTargets.get(key);
79
+ if (entry && (entry.width !== width || entry.height !== height)) {
80
+ ctx.backend.destroyRenderTarget(entry.target);
81
+ entry = undefined;
82
+ }
83
+ if (!entry) {
84
+ entry = { target: ctx.backend.createRenderTarget(width, height), width, height };
85
+ ctx.groupTargets.set(key, entry);
86
+ }
87
+ // Stamp on EVERY acquire (reuse path included) for frame-boundary LRU.
88
+ entry.lastTouched = ctx.frameIndex;
89
+ ctx.backend.pushTarget(entry.target, [0, 0, 0, 0]);
90
+ // try/finally so a throw while rendering a child can't leave the surface
91
+ // stack unbalanced and blacken the rest of the frame (EXPORT-FLOW §4A).
92
+ try {
93
+ // Inside the layer: identity transform (child coordinates are
94
+ // relative to the group's top-left, which is the layer origin),
95
+ // full opacity (the group's opacity applies at composite).
96
+ ctx.modelMatrix = mat4Identity();
97
+ ctx.worldMatrix = mat4Identity();
98
+ ctx.opacityFactor = 1;
99
+ ctx.timeOffset = groupStart;
100
+ ctx.time = warpedTime;
101
+ ctx.surfaceWidth = width;
102
+ ctx.surfaceHeight = height;
103
+ const ordered = [...elements].sort((a, b) => numberOr(b.layer, Number.MAX_SAFE_INTEGER) - numberOr(a.layer, Number.MAX_SAFE_INTEGER));
104
+ for (const child of ordered) {
105
+ if (child.visible === false)
106
+ continue;
107
+ if (!isActiveInGroup(child, ctx.time, groupStart, groupDur))
108
+ continue;
109
+ dispatch?.(child, ctx);
110
+ }
111
+ }
112
+ finally {
113
+ ctx.backend.popTarget();
114
+ }
115
+ ctx.modelMatrix = prevMatrix;
116
+ ctx.worldMatrix = prevWorld;
117
+ ctx.opacityFactor = prevOpacity;
118
+ ctx.timeOffset = prevTime;
119
+ ctx.time = prevGlobalTime;
120
+ ctx.surfaceWidth = prevSurfW;
121
+ ctx.surfaceHeight = prevSurfH;
122
+ return entry;
123
+ };
124
+ const baseKey = el.id ?? '__group_layer__';
125
+ const content = renderIntoLayer(baseKey, sortedChildren);
126
+ const maskLayer = el.mask ? renderIntoLayer(`${baseKey}::mask`, el.mask.elements) : null;
127
+ // Composite like a textured leaf element. With 3D on the group
128
+ // (or an un-flattened 3D ancestor) the LAYER's quad is projected
129
+ // by the full matrix chain — the §4.4.3 flattening rule and the
130
+ // "tilted UI card" shot.
131
+ const { cx, cy } = anchorToCenter(x, y, width, height, ax, ay);
132
+ const matrixPath = t3d !== null || !prevMatrix.aff;
133
+ const w = applyModelTransform(prevMatrix, prevOpacity, cx, cy, rotation, opacity01, width * sx, height * sy);
134
+ const transform = matrixPath
135
+ ? quadWorldTransform(prevMatrix, cx, cy, width * sx, height * sy, rotation, 0, 0, t3d)
136
+ : undefined;
137
+ const tintA = Math.max(0, Math.min(1, w.opacity01));
138
+ const tint = [tintA, tintA, tintA, tintA];
139
+ if (maskLayer && el.mask) {
140
+ ctx.backend.drawMaskedQuad({
141
+ cx: w.cx,
142
+ cy: w.cy,
143
+ width: matrixPath ? width * sx : w.width,
144
+ height: matrixPath ? height * sy : w.height,
145
+ rotation: w.rotation,
146
+ transform,
147
+ content: content.target.texture,
148
+ mask: maskLayer.target.texture,
149
+ mode: el.mask.mode,
150
+ tint,
151
+ blend: el.blend_mode,
152
+ });
153
+ }
154
+ else {
155
+ // A rounded clip box (rounded card clipping its content): mask the
156
+ // composited layer to a rounded rect. border_radius is in the
157
+ // group's local px, so it scales with the quad's x-scale.
158
+ const cornerRadius = typeof el.border_radius === 'number' && el.border_radius > 0
159
+ ? el.border_radius * sx
160
+ : undefined;
161
+ // §4.8 PBR: a material on the group shades the WHOLE flattened
162
+ // card as one lit plane (albedo = the layer's pixels). World quad
163
+ // from the camera-free matrix so the sheen is view-dependent.
164
+ const material = resolveMaterial(el, ctx.time);
165
+ const litLayer = material
166
+ ? buildLitParams(ctx, quadWorldTransform(prevWorld, cx, cy, width * sx, height * sy, rotation, 0, 0, t3d), material, WHITE)
167
+ : null;
168
+ ctx.backend.drawTexturedQuad({
169
+ cx: w.cx,
170
+ cy: w.cy,
171
+ width: matrixPath ? width * sx : w.width,
172
+ height: matrixPath ? height * sy : w.height,
173
+ rotation: w.rotation,
174
+ transform,
175
+ texture: content.target.texture,
176
+ tint,
177
+ cornerRadius,
178
+ blend: el.blend_mode,
179
+ lit: litLayer ?? undefined,
180
+ });
181
+ }
182
+ return;
183
+ }
184
+ }
185
+ // ── Unclipped path: compose the group's local matrix with the
186
+ // current model matrix and render children directly.
187
+ // blend_mode applies when compositing a group's FLATTENED layer; an
188
+ // unlayered group never rasterizes, so there's nothing to blend (§4.5).
189
+ if (el.blend_mode && el.blend_mode !== 'normal') {
190
+ getLogger().warn('group blend_mode requires clip: true or mask — ignored; children composite with their own blend modes');
191
+ }
192
+ // 3D groups stack a general matrix — children live in the group's 3D
193
+ // space (nested rotations compose; flattening only at layer
194
+ // boundaries, §4.4.3).
195
+ // Position the group's box via its anchor (default top-left), but pivot
196
+ // rotation/scale around the box CENTER — the same model as leaf elements
197
+ // (anchor = position only; transforms pivot center). Identical to the old
198
+ // anchor-as-pivot math when the group isn't rotated/scaled. See
199
+ // ANCHOR-CONVENTION-PLAN.md.
200
+ const { cx, cy } = anchorToCenter(x, y, width, height, ax, ay);
201
+ const localMatrix = t3d
202
+ ? mat4TRS3D(cx, cy, t3d.z, width, height, 0.5, 0.5, rotation, t3d.yRot, t3d.xRot, sx, sy)
203
+ : mat4TRS(cx, cy, width, height, 0.5, 0.5, rotation, sx, sy);
204
+ ctx.modelMatrix = mat4Multiply(prevMatrix, localMatrix);
205
+ ctx.worldMatrix = mat4Multiply(prevWorld, localMatrix);
206
+ ctx.opacityFactor = prevOpacity * opFactor;
207
+ ctx.timeOffset = groupStart;
208
+ ctx.time = warpedTime;
209
+ // §4.4.3: under a camera, plain-group children paint back-to-front by
210
+ // camera depth (computed against the just-composed model matrix so the
211
+ // group's own 3D transform is included). Flattened groups (the clip/
212
+ // mask path above) keep layer order — their children are coplanar in
213
+ // the flat layer.
214
+ const drawOrder = ctx.depthSort ? depthOrder(sortedChildren, ctx) : sortedChildren;
215
+ for (const child of drawOrder) {
216
+ if (child.visible === false)
217
+ continue;
218
+ if (!isActiveInGroup(child, ctx.time, groupStart, groupDur))
219
+ continue;
220
+ // Lazy import would create a cycle; the dispatch is reachable via
221
+ // the parent module passing dispatchElement in. Inline the dispatch
222
+ // here by calling back through ctx-attached function set in scene.ts.
223
+ dispatch?.(child, ctx);
224
+ }
225
+ ctx.modelMatrix = prevMatrix;
226
+ ctx.worldMatrix = prevWorld;
227
+ ctx.opacityFactor = prevOpacity;
228
+ ctx.timeOffset = prevTime;
229
+ ctx.time = prevGlobalTime;
230
+ }
231
+ function numberOr(value, fallback) {
232
+ if (typeof value === 'number' && Number.isFinite(value))
233
+ return value;
234
+ if (typeof value === 'string') {
235
+ const n = parseFloat(value);
236
+ if (Number.isFinite(n))
237
+ return n;
238
+ }
239
+ return fallback;
240
+ }
241
+ function parseDuration(v, fallback) {
242
+ if (v === 'auto' || v === 'end' || v == null)
243
+ return fallback;
244
+ if (typeof v === 'number' && Number.isFinite(v))
245
+ return v;
246
+ if (typeof v === 'string') {
247
+ const n = parseFloat(v);
248
+ if (Number.isFinite(n))
249
+ return n;
250
+ }
251
+ return fallback;
252
+ }
253
+ function isActiveInGroup(el, globalTime, groupStart, groupDur) {
254
+ const localStart = numberOr(el.time, 0);
255
+ const start = groupStart + localStart;
256
+ const dur = parseDuration(el.duration, groupDur - localStart);
257
+ return globalTime >= start && globalTime <= start + dur;
258
+ }
259
+ //# sourceMappingURL=group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group.js","sourceRoot":"","sources":["../../../src/compositor/element-renderers/group.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,qEAAqE;AACrE,2DAA2D;AAC3D,MAAM,KAAK,GAA8C,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAEtE;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAgB,EAAE,GAAkB;IACrE,oEAAoE;IACpE,0DAA0D;IAC1D,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC,CAAC;IAC7E,IAAI,GAAG,CAAC,IAAI,GAAG,UAAU,IAAI,GAAG,CAAC,IAAI,GAAG,UAAU,GAAG,QAAQ;QAAE,OAAO;IAEtE,qEAAqE;IACrE,qEAAqE;IACrE,oEAAoE;IACpE,MAAM,cAAc,GAAG,GAAG,CAAC,IAAI,CAAC;IAChC,MAAM,UAAU,GACd,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;QACtD,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,oBAAoB,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC,CAAC;QACtF,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAEf,MAAM,SAAS,GAAG,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IACrD,IAAI,QAAQ,KAAK,CAAC;QAAE,OAAO;IAE3B,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;IACvB,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAU,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,CAAC,CAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,KAAK,SAAS;QAClC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,KAAc,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC;QACxD,CAAC,CAAC,CAAC,CAAC;IACN,MAAM,MAAM,GAAG,EAAE,CAAC,MAAM,KAAK,SAAS;QACpC,CAAC,CAAC,aAAa,CAAC,EAAE,CAAC,MAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;QAC1D,CAAC,CAAC,CAAC,CAAC;IACN,MAAM,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,aAAa,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,cAAc,CAAC,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC,QAAQ,IAAK,EAA+B,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9H,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,kEAAkE;IAClE,oEAAoE;IACpE,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAE/B,kEAAkE;IAClE,iEAAiE;IACjE,kEAAkE;IAClE,6DAA6D;IAC7D,MAAM,cAAc,GAAG,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC1C,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAClG,CAAC;IAEF,MAAM,QAAQ,GAAI,GAAiF;SAChG,SAAS,CAAC;IAEb,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC;IAClC,MAAM,WAAW,GAAG,GAAG,CAAC,aAAa,CAAC;IACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC;IAChC,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,CAAC;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,aAAa,CAAC;IAEpC,+DAA+D;IAC/D,qEAAqE;IACrE,qEAAqE;IACrE,kEAAkE;IAClE,qCAAqC;IACrC,IAAI,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QAChC,IAAI,KAAK,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAC9B,SAAS,EAAE,CAAC,IAAI,CAAC,+DAA+D,CAAC,CAAC;QACpF,CAAC;aAAM,CAAC;YACN,MAAM,eAAe,GAAG,CAAC,GAAW,EAAE,QAA4B,EAAmB,EAAE;gBACrF,IAAI,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACtC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC;oBAChE,GAAG,CAAC,OAAO,CAAC,mBAAmB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;oBAC9C,KAAK,GAAG,SAAS,CAAC;gBACpB,CAAC;gBACD,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;oBACjF,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACnC,CAAC;gBACD,uEAAuE;gBACvE,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,UAAU,CAAC;gBACnC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACnD,yEAAyE;gBACzE,wEAAwE;gBACxE,IAAI,CAAC;oBACH,8DAA8D;oBAC9D,gEAAgE;oBAChE,2DAA2D;oBAC3D,GAAG,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC;oBACjC,GAAG,CAAC,WAAW,GAAG,YAAY,EAAE,CAAC;oBACjC,GAAG,CAAC,aAAa,GAAG,CAAC,CAAC;oBACtB,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC;oBAC5B,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;oBACtB,GAAG,CAAC,YAAY,GAAG,KAAK,CAAC;oBACzB,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC;oBAC3B,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAClG,CAAC;oBACF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;wBAC5B,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK;4BAAE,SAAS;wBACtC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC;4BAAE,SAAS;wBACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBACzB,CAAC;gBACH,CAAC;wBAAS,CAAC;oBACT,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC1B,CAAC;gBACD,GAAG,CAAC,WAAW,GAAG,UAAU,CAAC;gBAC7B,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;gBAC5B,GAAG,CAAC,aAAa,GAAG,WAAW,CAAC;gBAChC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC;gBAC1B,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC;gBAC1B,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC7B,GAAG,CAAC,aAAa,GAAG,SAAS,CAAC;gBAC9B,OAAO,KAAK,CAAC;YACf,CAAC,CAAC;YAEF,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,IAAI,iBAAiB,CAAC;YAC3C,MAAM,OAAO,GAAG,eAAe,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,OAAO,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAEzF,+DAA+D;YAC/D,iEAAiE;YACjE,gEAAgE;YAChE,yBAAyB;YACzB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;YAC/D,MAAM,UAAU,GAAG,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;YACnD,MAAM,CAAC,GAAG,mBAAmB,CAC3B,UAAU,EAAE,WAAW,EACvB,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,CACrD,CAAC;YACF,MAAM,SAAS,GAAG,UAAU;gBAC1B,CAAC,CAAC,kBAAkB,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC;gBACtF,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;YACpD,MAAM,IAAI,GAA8C,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACrF,IAAI,SAAS,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;gBACzB,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC;oBACzB,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;oBACxC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;oBAC3C,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,SAAS;oBACT,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;oBAC/B,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,OAAO;oBAC9B,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI;oBAClB,IAAI;oBACJ,KAAK,EAAE,EAAE,CAAC,UAAU;iBACrB,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,mEAAmE;gBACnE,8DAA8D;gBAC9D,0DAA0D;gBAC1D,MAAM,YAAY,GAChB,OAAO,EAAE,CAAC,aAAa,KAAK,QAAQ,IAAI,EAAE,CAAC,aAAa,GAAG,CAAC;oBAC1D,CAAC,CAAC,EAAE,CAAC,aAAa,GAAG,EAAE;oBACvB,CAAC,CAAC,SAAS,CAAC;gBAChB,+DAA+D;gBAC/D,kEAAkE;gBAClE,8DAA8D;gBAC9D,MAAM,QAAQ,GAAG,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;gBAC/C,MAAM,QAAQ,GAAG,QAAQ;oBACvB,CAAC,CAAC,cAAc,CACZ,GAAG,EACH,kBAAkB,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,EAAE,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EACnF,QAAQ,EACR,KAAK,CACN;oBACH,CAAC,CAAC,IAAI,CAAC;gBACT,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC;oBAC3B,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;oBACxC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM;oBAC3C,QAAQ,EAAE,CAAC,CAAC,QAAQ;oBACpB,SAAS;oBACT,OAAO,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO;oBAC/B,IAAI;oBACJ,YAAY;oBACZ,KAAK,EAAE,EAAE,CAAC,UAAU;oBACpB,GAAG,EAAE,QAAQ,IAAI,SAAS;iBAC3B,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,qDAAqD;IACrD,oEAAoE;IACpE,wEAAwE;IACxE,IAAI,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAChD,SAAS,EAAE,CAAC,IAAI,CAAC,uGAAuG,CAAC,CAAC;IAC5H,CAAC;IACD,qEAAqE;IACrE,4DAA4D;IAC5D,uBAAuB;IACvB,wEAAwE;IACxE,yEAAyE;IACzE,0EAA0E;IAC1E,gEAAgE;IAChE,6BAA6B;IAC7B,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,GAAG;QACrB,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC;QACzF,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAE/D,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACxD,GAAG,CAAC,WAAW,GAAG,YAAY,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACvD,GAAG,CAAC,aAAa,GAAG,WAAW,GAAG,QAAQ,CAAC;IAC3C,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC;IAC5B,GAAG,CAAC,IAAI,GAAG,UAAU,CAAC;IAEtB,sEAAsE;IACtE,uEAAuE;IACvE,qEAAqE;IACrE,qEAAqE;IACrE,kBAAkB;IAClB,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC;IAEnF,KAAK,MAAM,KAAK,IAAI,SAAS,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,OAAO,KAAK,KAAK;YAAE,SAAS;QACtC,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,CAAC;YAAE,SAAS;QACtE,kEAAkE;QAClE,oEAAoE;QACpE,sEAAsE;QACtE,QAAQ,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,GAAG,CAAC,WAAW,GAAG,UAAU,CAAC;IAC7B,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,aAAa,GAAG,WAAW,CAAC;IAChC,GAAG,CAAC,UAAU,GAAG,QAAQ,CAAC;IAC1B,GAAG,CAAC,IAAI,GAAG,cAAc,CAAC;AAC5B,CAAC;AAED,SAAS,QAAQ,CAAC,KAAc,EAAE,QAAgB;IAChD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,CAAU,EAAE,QAAgB;IACjD,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,QAAQ,CAAC;IAC9D,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC;IAC1D,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe,CACtB,EAAW,EACX,UAAkB,EAClB,UAAkB,EAClB,QAAgB;IAEhB,MAAM,UAAU,GAAG,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,MAAM,KAAK,GAAG,UAAU,GAAG,UAAU,CAAC;IACtC,MAAM,GAAG,GAAG,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,CAAC,CAAC;IAC9D,OAAO,UAAU,IAAI,KAAK,IAAI,UAAU,IAAI,KAAK,GAAG,GAAG,CAAC;AAC1D,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { ImageElement } from '@clipkit/protocol';
2
+ import type { RenderContext } from '../render-context.js';
3
+ export declare function renderImageElement(element: ImageElement, ctx: RenderContext): void;
4
+ //# sourceMappingURL=image.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.d.ts","sourceRoot":"","sources":["../../../src/compositor/element-renderers/image.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAM1D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAsFlF"}
@@ -0,0 +1,97 @@
1
+ import { applyModelTransform, quadWorldTransform } from '../mat4.js';
2
+ import { resolveAnchor, resolveLength } from '../unit.js';
3
+ import { anchorToCenter } from '../transform.js';
4
+ import { applyAnimation, applyAspectRatio, resolve3D, resolveScalePair, resolveSkewPair } from '../resolve.js';
5
+ import { computeObjectFit } from '../fit.js';
6
+ import { resolveMaterial } from '../lighting.js';
7
+ import { buildLitParams } from './lit.js';
8
+ // Textured surfaces light from the texture's own pixels, so the albedo
9
+ // color is unused by the lit-textured shader — pass white.
10
+ const WHITE = [1, 1, 1, 1];
11
+ export function renderImageElement(element, ctx) {
12
+ const { canvas, backend, images } = ctx;
13
+ const sourceUrl = String(element.source ?? '');
14
+ if (!sourceUrl)
15
+ return;
16
+ const asset = images.get(sourceUrl);
17
+ if (!asset) {
18
+ // Asset not preloaded — silently skip this frame. Caller should have
19
+ // awaited preload() before rendering.
20
+ return;
21
+ }
22
+ const x = applyAnimation(element, 'x', resolveLength(element.x, canvas.width, canvas), ctx);
23
+ const y = applyAnimation(element, 'y', resolveLength(element.y, canvas.height, canvas), ctx);
24
+ const { sx, sy } = resolveScalePair(element, ctx);
25
+ const box = applyAspectRatio(element, applyAnimation(element, 'width', resolveLength(element.width, canvas.width, canvas, asset.bitmap.width), ctx), applyAnimation(element, 'height', resolveLength(element.height, canvas.height, canvas, asset.bitmap.height), ctx));
26
+ const width = sx * box.width;
27
+ const height = sy * box.height;
28
+ const rotation = applyAnimation(element, 'rotation', numberOr(element.rotation ?? element.z_rotation, 0), ctx);
29
+ const opacity01 = applyAnimation(element, 'opacity', numberOr(element.opacity, 1), ctx);
30
+ const xAnchor = resolveAnchor(element.x_anchor);
31
+ const yAnchor = resolveAnchor(element.y_anchor);
32
+ const { cx, cy } = anchorToCenter(x, y, width, height, xAnchor, yAnchor);
33
+ const w = applyModelTransform(ctx.modelMatrix, ctx.opacityFactor, cx, cy, rotation, opacity01, width, height);
34
+ const opacity = Math.max(0, Math.min(1, w.opacity01));
35
+ const tint = [opacity, opacity, opacity, opacity];
36
+ // CKP/1.0 3D (§4.4): full-matrix hand-off. Fit math runs in LOCAL
37
+ // pixels (the projection scales everything uniformly afterwards).
38
+ const t3d = resolve3D(element, ctx);
39
+ const matrixPath = t3d !== null || !ctx.modelMatrix.aff;
40
+ // object-fit: crop (cover/none) or letterbox (contain) the media
41
+ // within the element box. Default cover. The optional source crop
42
+ // (§5.3) selects a normalized sub-rectangle of the media first.
43
+ const fitted = computeObjectFit(element.fit, matrixPath ? width : w.width, matrixPath ? height : w.height, asset.bitmap.width, asset.bitmap.height, resolveCrop(element, ctx));
44
+ const { skewX, skewY } = resolveSkewPair(element, ctx);
45
+ // §4.8 PBR: a material + scene lights/environment shade the image as a
46
+ // textured surface (albedo = its own pixels). Built from the camera-
47
+ // free world quad so the highlight/reflection is view-dependent.
48
+ const material = resolveMaterial(element, ctx.time);
49
+ const lit = material
50
+ ? buildLitParams(ctx, quadWorldTransform(ctx.worldMatrix, cx, cy, fitted.drawWidth, fitted.drawHeight, rotation, skewX, skewY, t3d), material, WHITE)
51
+ : null;
52
+ backend.drawTexturedQuad({
53
+ cx: w.cx,
54
+ cy: w.cy,
55
+ width: fitted.drawWidth,
56
+ height: fitted.drawHeight,
57
+ rotation: w.rotation,
58
+ skewX,
59
+ skewY,
60
+ transform: matrixPath
61
+ ? quadWorldTransform(ctx.modelMatrix, cx, cy, fitted.drawWidth, fitted.drawHeight, rotation, skewX, skewY, t3d)
62
+ : undefined,
63
+ texture: asset.texture,
64
+ uvRect: fitted.uvRect,
65
+ tint,
66
+ cornerRadius: numberOr(element.border_radius, 0),
67
+ blend: element.blend_mode,
68
+ lit: lit ?? undefined,
69
+ });
70
+ }
71
+ // Source crop (§5.3): resolve the normalized sub-rect, with each component
72
+ // keyframeable. Returns undefined for the common no-crop case so the fit
73
+ // math takes its identity fast path.
74
+ const CROP_PROPS = ['crop_x', 'crop_y', 'crop_width', 'crop_height'];
75
+ function resolveCrop(element, ctx) {
76
+ const hasField = CROP_PROPS.some((p) => element[p] !== undefined);
77
+ const hasAnim = (element.keyframe_animations ?? []).some((k) => CROP_PROPS.includes(k.property));
78
+ if (!hasField && !hasAnim)
79
+ return undefined;
80
+ return {
81
+ x: applyAnimation(element, 'crop_x', numberOr(element.crop_x, 0), ctx),
82
+ y: applyAnimation(element, 'crop_y', numberOr(element.crop_y, 0), ctx),
83
+ width: applyAnimation(element, 'crop_width', numberOr(element.crop_width, 1), ctx),
84
+ height: applyAnimation(element, 'crop_height', numberOr(element.crop_height, 1), ctx),
85
+ };
86
+ }
87
+ function numberOr(value, fallback) {
88
+ if (typeof value === 'number' && Number.isFinite(value))
89
+ return value;
90
+ if (typeof value === 'string') {
91
+ const n = parseFloat(value);
92
+ if (Number.isFinite(n))
93
+ return n;
94
+ }
95
+ return fallback;
96
+ }
97
+ //# sourceMappingURL=image.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image.js","sourceRoot":"","sources":["../../../src/compositor/element-renderers/image.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { LitParams } from '../../backend/backend.js';
2
+ import type { RGBA } from '../color.js';
3
+ import type { ResolvedMaterial } from '../lighting.js';
4
+ import type { RenderContext } from '../render-context.js';
5
+ export declare function buildLitParams(ctx: RenderContext, worldQuadMatrix: ArrayLike<number>, material: ResolvedMaterial | null, albedo: RGBA, strokeAlbedo?: RGBA): LitParams | null;
6
+ //# sourceMappingURL=lit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lit.d.ts","sourceRoot":"","sources":["../../../src/compositor/element-renderers/lit.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,wBAAgB,cAAc,CAC5B,GAAG,EAAE,aAAa,EAClB,eAAe,EAAE,SAAS,CAAC,MAAM,CAAC,EAClC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,EACjC,MAAM,EAAE,IAAI,EACZ,YAAY,CAAC,EAAE,IAAI,GAClB,SAAS,GAAG,IAAI,CAsElB"}
@@ -0,0 +1,82 @@
1
+ // Shared builder for a draw's PBR `LitParams` (§4.8). Given the element's
2
+ // world (pre-camera) quad matrix and resolved material, splits the scene
3
+ // lights into ambient + directional and derives the world face normal.
4
+ // Used by shape/image/group renderers; returns null when there's nothing
5
+ // to light (no material or no lights → unlit fast path).
6
+ export function buildLitParams(ctx, worldQuadMatrix, material, albedo, strokeAlbedo) {
7
+ // Lit if there's a material AND something to shade with — direct
8
+ // lights and/or an environment to reflect. No material, or neither
9
+ // lights nor environment ⇒ unlit fast path.
10
+ if (!material || (ctx.lights.length === 0 && !ctx.environment))
11
+ return null;
12
+ const m = worldQuadMatrix;
13
+ // Column 2 of the unit-quad→world matrix is the face normal direction;
14
+ // columns 0/1 are the tangent (+U) / bitangent (+V) for normal mapping.
15
+ let nx = m[8], ny = m[9], nz = m[10];
16
+ const nl = Math.hypot(nx, ny, nz) || 1;
17
+ nx /= nl;
18
+ ny /= nl;
19
+ nz /= nl;
20
+ // §4.8 Phase 2 normal map: resolve the texture + world TBN basis.
21
+ let normalMap;
22
+ if (material.normalMap && material.normalScale > 0) {
23
+ const asset = ctx.images.get(material.normalMap);
24
+ if (asset) {
25
+ let tx = m[0], ty = m[1], tz = m[2];
26
+ const tl = Math.hypot(tx, ty, tz) || 1;
27
+ tx /= tl;
28
+ ty /= tl;
29
+ tz /= tl;
30
+ let bx = m[4], by = m[5], bz = m[6];
31
+ const bl = Math.hypot(bx, by, bz) || 1;
32
+ bx /= bl;
33
+ by /= bl;
34
+ bz /= bl;
35
+ normalMap = {
36
+ texture: asset.texture,
37
+ scale: material.normalScale,
38
+ tangent: [tx, ty, tz],
39
+ bitangent: [bx, by, bz],
40
+ };
41
+ }
42
+ }
43
+ const ambient = [0, 0, 0];
44
+ const lightDirs = [];
45
+ const lightColors = [];
46
+ for (const l of ctx.lights) {
47
+ if (l.ambient) {
48
+ ambient[0] += l.color[0];
49
+ ambient[1] += l.color[1];
50
+ ambient[2] += l.color[2];
51
+ }
52
+ else if (lightDirs.length < 4) {
53
+ lightDirs.push(l.dir);
54
+ lightColors.push(l.color);
55
+ }
56
+ }
57
+ const env = ctx.environment
58
+ ? {
59
+ stopColors: ctx.environment.stops.map((s) => s.color),
60
+ stopOffsets: ctx.environment.stops.map((s) => s.offset),
61
+ avg: ctx.environment.avg,
62
+ image: ctx.environment.image ? ctx.images.get(ctx.environment.image)?.texture : undefined,
63
+ }
64
+ : undefined;
65
+ return {
66
+ albedo,
67
+ strokeAlbedo,
68
+ roughness: material.roughness,
69
+ metalness: material.metalness,
70
+ reflectivity: material.reflectivity,
71
+ emissive: material.emissive,
72
+ worldMatrix: worldQuadMatrix,
73
+ normal: [nx, ny, nz],
74
+ eye: ctx.eye,
75
+ ambient,
76
+ lightDirs,
77
+ lightColors,
78
+ env,
79
+ normalMap,
80
+ };
81
+ }
82
+ //# sourceMappingURL=lit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lit.js","sourceRoot":"","sources":["../../../src/compositor/element-renderers/lit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ParticlesElement } from '@clipkit/protocol';
2
+ import type { RenderContext } from '../render-context.js';
3
+ export declare function renderParticlesElement(element: ParticlesElement, ctx: RenderContext): void;
4
+ //# sourceMappingURL=particles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"particles.d.ts","sourceRoot":"","sources":["../../../src/compositor/element-renderers/particles.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAkB,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAM1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,EAAE,aAAa,GAAG,IAAI,CAmK1F"}