@make-pictures/kits 0.0.0-stage → 2.0.1

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -2
  3. package/dist/chunk-3SUIELJV.mjs +601 -0
  4. package/dist/chunk-4Z3G6FPZ.mjs +485 -0
  5. package/dist/chunk-AHA23PHC.mjs +678 -0
  6. package/dist/chunk-CW623YVB.mjs +1124 -0
  7. package/dist/chunk-NNA7XXQB.mjs +1059 -0
  8. package/dist/chunk-S4CHTWOS.mjs +1237 -0
  9. package/dist/chunk-WAA7P5FT.mjs +912 -0
  10. package/dist/data-storytelling/AnimatedBarRace.d.ts +37 -0
  11. package/dist/data-storytelling/MetricComparisonCard.d.ts +29 -0
  12. package/dist/data-storytelling/TimelineTrack.d.ts +29 -0
  13. package/dist/data-storytelling/index.cjs +1224 -0
  14. package/dist/data-storytelling/index.d.ts +3 -0
  15. package/dist/data-storytelling/index.mjs +10 -0
  16. package/dist/index.cjs +6010 -0
  17. package/dist/index.d.ts +7 -0
  18. package/dist/index.mjs +108 -0
  19. package/dist/isometric-3d/IsometricStudioEnvironment.d.ts +8 -0
  20. package/dist/isometric-3d/Stylized3DCharacter.d.ts +29 -0
  21. package/dist/isometric-3d/index.cjs +611 -0
  22. package/dist/isometric-3d/index.d.ts +2 -0
  23. package/dist/isometric-3d/index.mjs +8 -0
  24. package/dist/kinetic-typography/AnimatedMetricCounter.d.ts +36 -0
  25. package/dist/kinetic-typography/ImpactKeywordCard.d.ts +31 -0
  26. package/dist/kinetic-typography/WordByWordStage.d.ts +47 -0
  27. package/dist/kinetic-typography/index.cjs +665 -0
  28. package/dist/kinetic-typography/index.d.ts +3 -0
  29. package/dist/kinetic-typography/index.mjs +14 -0
  30. package/dist/motion-diagrams-2d/CameraRig.d.ts +34 -0
  31. package/dist/motion-diagrams-2d/CodePayloadToast.d.ts +14 -0
  32. package/dist/motion-diagrams-2d/DataFlowEdge.d.ts +24 -0
  33. package/dist/motion-diagrams-2d/NodeBox.d.ts +65 -0
  34. package/dist/motion-diagrams-2d/SystemNode.d.ts +21 -0
  35. package/dist/motion-diagrams-2d/index.cjs +1137 -0
  36. package/dist/motion-diagrams-2d/index.d.ts +5 -0
  37. package/dist/motion-diagrams-2d/index.mjs +28 -0
  38. package/dist/paper-diorama-3d/ImageCutout3D.d.ts +47 -0
  39. package/dist/paper-diorama-3d/PaperCutout3D.d.ts +62 -0
  40. package/dist/paper-diorama-3d/PaperPopUpBook3D.d.ts +51 -0
  41. package/dist/paper-diorama-3d/PaperStageLighting3D.d.ts +12 -0
  42. package/dist/paper-diorama-3d/index.cjs +1087 -0
  43. package/dist/paper-diorama-3d/index.d.ts +4 -0
  44. package/dist/paper-diorama-3d/index.mjs +34 -0
  45. package/dist/product-frames/BrowserFrame.d.ts +28 -0
  46. package/dist/product-frames/PhoneFrame.d.ts +23 -0
  47. package/dist/product-frames/ScreenSpotlightOverlay.d.ts +34 -0
  48. package/dist/product-frames/frameMedia.d.ts +24 -0
  49. package/dist/product-frames/index.cjs +507 -0
  50. package/dist/product-frames/index.d.ts +8 -0
  51. package/dist/product-frames/index.mjs +12 -0
  52. package/dist/vfx/CinematicLensOverlay.d.ts +29 -0
  53. package/dist/vfx/ParticleField.d.ts +18 -0
  54. package/dist/vfx/SceneTransition.d.ts +24 -0
  55. package/dist/vfx/StagePostProcessing3D.d.ts +44 -0
  56. package/dist/vfx/index.cjs +933 -0
  57. package/dist/vfx/index.d.ts +4 -0
  58. package/dist/vfx/index.mjs +14 -0
  59. package/package.json +95 -4
@@ -0,0 +1,933 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // packages/kits/src/vfx/index.ts
31
+ var vfx_exports = {};
32
+ __export(vfx_exports, {
33
+ CinematicLensOverlay: () => CinematicLensOverlay,
34
+ ContactShadowDisc3D: () => ContactShadowDisc3D,
35
+ ParticleField: () => ParticleField,
36
+ SceneTransition: () => SceneTransition,
37
+ StagePostProcessing3D: () => StagePostProcessing3D
38
+ });
39
+ module.exports = __toCommonJS(vfx_exports);
40
+
41
+ // packages/kits/src/vfx/CinematicLensOverlay.tsx
42
+ var import_react = require("react");
43
+ var import_remotion = require("remotion");
44
+ var import_camera = require("@make-pictures/core");
45
+ var import_prng = require("@make-pictures/core");
46
+ var import_jsx_runtime = require("react/jsx-runtime");
47
+ function clamp(v, min, max) {
48
+ return Math.max(min, Math.min(max, v));
49
+ }
50
+ var CinematicLensOverlay = ({
51
+ vignetteIntensity = 0.36,
52
+ grainOpacity = 0.045,
53
+ chromaticAberration,
54
+ velocityAberrationScale = 0.85,
55
+ warmLightLeak = 0.16,
56
+ lightLeakColor = "#F59E0B",
57
+ seed = 77,
58
+ zIndex = 60
59
+ }) => {
60
+ const frame = (0, import_remotion.useCurrentFrame)();
61
+ const { fps, width, height } = (0, import_remotion.useVideoConfig)();
62
+ const telemetry = (0, import_camera.useDirectorCameraTelemetry)();
63
+ const leakTraits = (0, import_react.useMemo)(() => {
64
+ const rand = (0, import_prng.createSeededRandom)(`lens-leak:${seed}`);
65
+ return {
66
+ phaseA: rand() * Math.PI * 2,
67
+ phaseB: rand() * Math.PI * 2,
68
+ baseX: 8 + rand() * 14,
69
+ baseY: 6 + rand() * 14
70
+ };
71
+ }, [seed]);
72
+ const vig = clamp(vignetteIntensity, 0, 1);
73
+ const grain = clamp(grainOpacity, 0, 0.18);
74
+ const leak = clamp(warmLightLeak, 0, 1);
75
+ const rawCa = typeof chromaticAberration === "number" ? chromaticAberration : telemetry.velocity * velocityAberrationScale;
76
+ const ca = clamp(rawCa, 0, 1);
77
+ const f60 = frame * (60 / Math.max(1, fps));
78
+ const leakPulse = 0.72 + 0.28 * (0.5 * Math.sin(f60 * 0.032 + leakTraits.phaseA) + 0.5 * Math.cos(f60 * 0.045 + leakTraits.phaseB));
79
+ const leakX = leakTraits.baseX + Math.sin(f60 * 0.031 + leakTraits.phaseA) * 5;
80
+ const leakY = leakTraits.baseY + Math.cos(f60 * 0.037 + leakTraits.phaseB) * 4;
81
+ const grainSeed = (Math.abs(Math.floor(frame)) + Math.abs(seed)) % 97 + 1;
82
+ const filterId = `mp-film-grain-${Math.abs(seed)}`;
83
+ const fringePx = Math.round(ca * Math.max(width, height) * 0.018);
84
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
85
+ import_remotion.AbsoluteFill,
86
+ {
87
+ style: {
88
+ pointerEvents: "none",
89
+ overflow: "hidden",
90
+ zIndex
91
+ },
92
+ children: [
93
+ ca > 0.015 && fringePx > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
94
+ import_remotion.AbsoluteFill,
95
+ {
96
+ style: {
97
+ mixBlendMode: "screen",
98
+ opacity: clamp(ca * 0.78, 0, 0.72),
99
+ boxShadow: `
100
+ inset ${fringePx}px 0 ${fringePx * 2}px -${Math.max(1, Math.floor(fringePx * 0.35))}px rgba(255, 42, 84, 0.62),
101
+ inset -${fringePx}px 0 ${fringePx * 2}px -${Math.max(1, Math.floor(fringePx * 0.35))}px rgba(0, 240, 255, 0.62)
102
+ `
103
+ }
104
+ }
105
+ ),
106
+ leak > 5e-3 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
107
+ import_remotion.AbsoluteFill,
108
+ {
109
+ style: {
110
+ mixBlendMode: "screen",
111
+ opacity: clamp(leak * leakPulse, 0, 0.85),
112
+ backgroundImage: `
113
+ radial-gradient(ellipse 52% 44% at ${leakX.toFixed(2)}% ${leakY.toFixed(2)}%, ${lightLeakColor}66 0%, ${lightLeakColor}22 46%, transparent 78%),
114
+ radial-gradient(ellipse 40% 36% at ${(100 - leakX * 0.7).toFixed(2)}% ${(96 - leakY * 0.6).toFixed(2)}%, #FB718538 0%, transparent 72%)
115
+ `
116
+ }
117
+ }
118
+ ),
119
+ vig > 5e-3 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
120
+ import_remotion.AbsoluteFill,
121
+ {
122
+ style: {
123
+ backgroundImage: `radial-gradient(ellipse 76% 74% at 50% 50%, transparent 48%, rgba(9, 10, 18, ${(vig * 0.42).toFixed(3)}) 80%, rgba(5, 6, 12, ${(vig * 0.82).toFixed(3)}) 100%)`
124
+ }
125
+ }
126
+ ),
127
+ grain > 2e-3 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
128
+ "svg",
129
+ {
130
+ width: "100%",
131
+ height: "100%",
132
+ style: {
133
+ position: "absolute",
134
+ inset: 0,
135
+ opacity: grain,
136
+ mixBlendMode: "overlay",
137
+ pointerEvents: "none"
138
+ },
139
+ children: [
140
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("filter", { id: filterId, x: "0%", y: "0%", width: "100%", height: "100%", children: [
141
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
142
+ "feTurbulence",
143
+ {
144
+ type: "fractalNoise",
145
+ baseFrequency: "0.78",
146
+ numOctaves: 2,
147
+ seed: grainSeed,
148
+ stitchTiles: "stitch"
149
+ }
150
+ ),
151
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("feColorMatrix", { type: "saturate", values: "0" })
152
+ ] }) }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { width: "100%", height: "100%", filter: `url(#${filterId})` })
154
+ ]
155
+ }
156
+ )
157
+ ]
158
+ }
159
+ );
160
+ };
161
+
162
+ // packages/kits/src/vfx/ParticleField.tsx
163
+ var import_react2 = require("react");
164
+ var import_remotion2 = require("remotion");
165
+ var import_tokens = require("@make-pictures/core");
166
+ var import_prng2 = require("@make-pictures/core");
167
+ var import_jsx_runtime2 = require("react/jsx-runtime");
168
+ var CONFETTI_PALETTE = [
169
+ "#2563EB",
170
+ "#FF2A85",
171
+ "#10B981",
172
+ "#F59E0B",
173
+ "#38BDF8",
174
+ "#7209B7"
175
+ ];
176
+ function wrap01(v) {
177
+ const m = v % 1;
178
+ return m < 0 ? m + 1 : m;
179
+ }
180
+ function defaultCountForPreset(preset) {
181
+ switch (preset) {
182
+ case "dust-motes":
183
+ return 34;
184
+ case "snow":
185
+ return 48;
186
+ case "rain":
187
+ return 64;
188
+ case "sparks":
189
+ return 38;
190
+ case "confetti":
191
+ return 52;
192
+ case "speed-lines":
193
+ return 28;
194
+ }
195
+ }
196
+ function defaultColorForPreset(preset) {
197
+ switch (preset) {
198
+ case "dust-motes":
199
+ return "#FDE68A";
200
+ case "snow":
201
+ return "#FFFFFF";
202
+ case "rain":
203
+ return "#BAE6FD";
204
+ case "sparks":
205
+ return "#FB923C";
206
+ case "confetti":
207
+ return "#FF2A85";
208
+ case "speed-lines":
209
+ return "#E0E7FF";
210
+ }
211
+ }
212
+ var ParticleField = ({
213
+ preset = "dust-motes",
214
+ count,
215
+ color,
216
+ seed = 108,
217
+ intensity = 1,
218
+ cleanFrameZero = true,
219
+ zIndex = 20
220
+ }) => {
221
+ const frame = (0, import_remotion2.useCurrentFrame)();
222
+ const { fps, width, height } = (0, import_remotion2.useVideoConfig)();
223
+ const resolvedCount = Math.max(
224
+ 0,
225
+ Math.round((count ?? defaultCountForPreset(preset)) * Math.max(0.25, intensity))
226
+ );
227
+ const baseColor = color ?? defaultColorForPreset(preset);
228
+ const descriptors = (0, import_react2.useMemo)(() => {
229
+ const list = [];
230
+ for (let i = 0; i < resolvedCount; i++) {
231
+ const rand = (0, import_prng2.createSeededRandom)(`particle:${preset}:${seed}:${i}`);
232
+ const depth = 0.35 + rand() * 0.65;
233
+ const u0 = rand();
234
+ const v0 = rand();
235
+ const swayPhase = rand() * Math.PI * 2;
236
+ let rot0 = rand() * 360;
237
+ let speedU = 0;
238
+ let speedV = 0;
239
+ let swayAmp = 0;
240
+ let swayFreq = 0.035;
241
+ let size = 4;
242
+ let baseOpacity = 0.5;
243
+ let rotSpeed = 0;
244
+ let itemColor = baseColor;
245
+ if (preset === "dust-motes") {
246
+ speedU = (rand() - 0.5) * 0.025 * depth;
247
+ speedV = -(0.018 + rand() * 0.028) * depth;
248
+ swayAmp = 14 + rand() * 24;
249
+ swayFreq = 0.031 + rand() * 0.02;
250
+ size = (2.2 + rand() * 5.2) * depth;
251
+ baseOpacity = 0.22 + rand() * 0.45;
252
+ } else if (preset === "snow") {
253
+ speedU = (rand() - 0.35) * 0.04 * depth;
254
+ speedV = (0.085 + rand() * 0.095) * depth;
255
+ swayAmp = 18 + rand() * 28;
256
+ swayFreq = 0.032 + rand() * 0.02;
257
+ size = (2.8 + rand() * 5.5) * depth;
258
+ baseOpacity = 0.38 + rand() * 0.5;
259
+ } else if (preset === "rain") {
260
+ speedU = -0.18 * depth;
261
+ speedV = (0.95 + rand() * 0.45) * depth;
262
+ size = (26 + rand() * 36) * depth;
263
+ baseOpacity = 0.2 + rand() * 0.34;
264
+ rot0 = 11;
265
+ } else if (preset === "sparks") {
266
+ speedU = (rand() - 0.42) * 0.11 * depth;
267
+ speedV = -(0.22 + rand() * 0.28) * depth;
268
+ swayAmp = 16 + rand() * 30;
269
+ swayFreq = 0.042 + rand() * 0.012;
270
+ size = (2.4 + rand() * 4.2) * depth;
271
+ baseOpacity = 0.55 + rand() * 0.42;
272
+ itemColor = color ?? (rand() > 0.45 ? "#FB923C" : rand() > 0.5 ? "#FDE047" : "#F43F5E");
273
+ } else if (preset === "confetti") {
274
+ speedU = (rand() - 0.5) * 0.07;
275
+ speedV = (0.16 + rand() * 0.16) * depth;
276
+ swayAmp = 24 + rand() * 34;
277
+ swayFreq = 0.036 + rand() * 0.018;
278
+ size = (8 + rand() * 8) * (0.65 + depth * 0.35);
279
+ baseOpacity = 0.78 + rand() * 0.22;
280
+ rotSpeed = (rand() > 0.5 ? 1 : -1) * (95 + rand() * 130);
281
+ itemColor = color ?? CONFETTI_PALETTE[Math.floor(rand() * CONFETTI_PALETTE.length)];
282
+ } else if (preset === "speed-lines") {
283
+ speedU = -(1.45 + rand() * 0.95) * depth;
284
+ speedV = 0;
285
+ size = (120 + rand() * 220) * depth;
286
+ baseOpacity = 0.14 + rand() * 0.32;
287
+ }
288
+ list.push({
289
+ index: i,
290
+ u0,
291
+ v0,
292
+ speedU,
293
+ speedV,
294
+ swayAmp,
295
+ swayFreq,
296
+ swayPhase,
297
+ size,
298
+ baseOpacity,
299
+ rot0,
300
+ rotSpeed,
301
+ color: itemColor,
302
+ depth
303
+ });
304
+ }
305
+ return list;
306
+ }, [preset, resolvedCount, seed, baseColor, color]);
307
+ const enterOpacity = cleanFrameZero ? (0, import_remotion2.spring)({
308
+ frame: frame - 2,
309
+ fps,
310
+ config: import_tokens.SPRING_PRESETS.smooth
311
+ }) : 1;
312
+ if (enterOpacity <= 5e-3 || resolvedCount === 0 || intensity <= 0) {
313
+ return null;
314
+ }
315
+ const tSec = frame / Math.max(1, fps);
316
+ const f60 = frame * (60 / Math.max(1, fps));
317
+ const margin = 80;
318
+ const spanW = width + margin * 2;
319
+ const spanH = height + margin * 2;
320
+ const ampOpacity = Math.min(1.35, Math.max(0, intensity));
321
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
322
+ import_remotion2.AbsoluteFill,
323
+ {
324
+ style: {
325
+ pointerEvents: "none",
326
+ overflow: "hidden",
327
+ opacity: enterOpacity,
328
+ zIndex
329
+ },
330
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
331
+ "svg",
332
+ {
333
+ width,
334
+ height,
335
+ viewBox: `0 0 ${width} ${height}`,
336
+ style: { display: "block", width: "100%", height: "100%" },
337
+ children: descriptors.map((p) => {
338
+ const u = wrap01(p.u0 + p.speedU * tSec);
339
+ const v = wrap01(p.v0 + p.speedV * tSec);
340
+ const sway = Math.sin(f60 * p.swayFreq + p.swayPhase) * p.swayAmp;
341
+ const x = -margin + u * spanW + (preset === "speed-lines" ? 0 : sway);
342
+ const y = -margin + v * spanH + (preset === "dust-motes" ? sway * 0.35 : 0);
343
+ const edgeFadeV = v < 0.08 ? v / 0.08 : v > 0.92 ? (1 - v) / 0.08 : 1;
344
+ const twinkle = preset === "dust-motes" || preset === "sparks" ? 0.65 + 0.35 * Math.sin(f60 * 0.045 + p.swayPhase) : 1;
345
+ const alpha = Math.min(
346
+ 1,
347
+ p.baseOpacity * ampOpacity * edgeFadeV * twinkle
348
+ );
349
+ if (alpha <= 0.01) return null;
350
+ if (preset === "rain") {
351
+ const rad = p.rot0 * Math.PI / 180;
352
+ const dx = -Math.sin(rad) * p.size;
353
+ const dy = Math.cos(rad) * p.size;
354
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
355
+ "line",
356
+ {
357
+ x1: x,
358
+ y1: y,
359
+ x2: x + dx,
360
+ y2: y + dy,
361
+ stroke: p.color,
362
+ strokeWidth: 1.4 * p.depth + 0.5,
363
+ strokeLinecap: "round",
364
+ opacity: alpha
365
+ },
366
+ p.index
367
+ );
368
+ }
369
+ if (preset === "speed-lines") {
370
+ const edgeFadeU = u < 0.1 ? u / 0.1 : u > 0.9 ? (1 - u) / 0.1 : 1;
371
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
372
+ "line",
373
+ {
374
+ x1: x,
375
+ y1: y,
376
+ x2: x + p.size,
377
+ y2: y,
378
+ stroke: p.color,
379
+ strokeWidth: 1.6 + p.depth * 2.2,
380
+ strokeLinecap: "round",
381
+ opacity: alpha * edgeFadeU
382
+ },
383
+ p.index
384
+ );
385
+ }
386
+ if (preset === "confetti") {
387
+ const rot = p.rot0 + p.rotSpeed * tSec;
388
+ const tumbleScaleY = Math.max(
389
+ 0.22,
390
+ Math.abs(Math.cos(f60 * 0.052 + p.swayPhase))
391
+ );
392
+ const w = p.size;
393
+ const h = p.size * 0.58;
394
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
395
+ "rect",
396
+ {
397
+ x: -w / 2,
398
+ y: -h / 2,
399
+ width: w,
400
+ height: h,
401
+ rx: 1.8,
402
+ fill: p.color,
403
+ opacity: alpha,
404
+ transform: `translate(${x.toFixed(2)}, ${y.toFixed(2)}) rotate(${rot.toFixed(1)}) scale(1, ${tumbleScaleY.toFixed(2)})`
405
+ },
406
+ p.index
407
+ );
408
+ }
409
+ if (preset === "sparks") {
410
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { opacity: alpha, children: [
411
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: x, cy: y, r: p.size * 2.3, fill: p.color, opacity: 0.24 }),
412
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: x, cy: y, r: p.size, fill: "#FFFBEB" })
413
+ ] }, p.index);
414
+ }
415
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("g", { opacity: alpha, children: [
416
+ preset === "dust-motes" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: x, cy: y, r: p.size * 2.2, fill: p.color, opacity: 0.2 }),
417
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: x, cy: y, r: p.size, fill: p.color })
418
+ ] }, p.index);
419
+ })
420
+ }
421
+ )
422
+ }
423
+ );
424
+ };
425
+
426
+ // packages/kits/src/vfx/StagePostProcessing3D.tsx
427
+ var import_react3 = require("react");
428
+ var import_fiber = require("@react-three/fiber");
429
+ var import_remotion3 = require("remotion");
430
+ var THREE = __toESM(require("three"), 1);
431
+ var import_prng3 = require("@make-pictures/core");
432
+ var import_jsx_runtime3 = require("react/jsx-runtime");
433
+ var radialShadowTextureCache = /* @__PURE__ */ new Map();
434
+ var spotlightBeamTextureCache = /* @__PURE__ */ new Map();
435
+ function getRadialDiscTexture(colorHex) {
436
+ if (typeof document === "undefined") return null;
437
+ const cached = radialShadowTextureCache.get(colorHex);
438
+ if (cached) return cached;
439
+ const canvas = document.createElement("canvas");
440
+ canvas.width = 256;
441
+ canvas.height = 256;
442
+ const ctx = canvas.getContext("2d");
443
+ if (ctx) {
444
+ const grad = ctx.createRadialGradient(128, 128, 8, 128, 128, 124);
445
+ grad.addColorStop(0, colorHex);
446
+ grad.addColorStop(0.45, colorHex);
447
+ grad.addColorStop(1, "rgba(0,0,0,0)");
448
+ ctx.fillStyle = grad;
449
+ ctx.fillRect(0, 0, 256, 256);
450
+ }
451
+ if (ctx) {
452
+ const img = ctx.getImageData(0, 0, 256, 256);
453
+ const data = img.data;
454
+ for (let y = 0; y < 256; y++) {
455
+ for (let x = 0; x < 256; x++) {
456
+ const dx = (x - 128) / 124;
457
+ const dy = (y - 128) / 124;
458
+ const r2 = dx * dx + dy * dy;
459
+ const idx = (y * 256 + x) * 4;
460
+ if (r2 >= 1) {
461
+ data[idx + 3] = 0;
462
+ } else {
463
+ const smooth = Math.pow(1 - r2, 2.2);
464
+ data[idx + 3] = Math.round(smooth * 255);
465
+ }
466
+ }
467
+ }
468
+ ctx.putImageData(img, 0, 0);
469
+ }
470
+ const tex = new THREE.CanvasTexture(canvas);
471
+ tex.needsUpdate = true;
472
+ radialShadowTextureCache.set(colorHex, tex);
473
+ return tex;
474
+ }
475
+ function getVolumetricConeTexture(key) {
476
+ if (typeof document === "undefined") return null;
477
+ const cached = spotlightBeamTextureCache.get(key);
478
+ if (cached) return cached;
479
+ const canvas = document.createElement("canvas");
480
+ canvas.width = 128;
481
+ canvas.height = 256;
482
+ const ctx = canvas.getContext("2d");
483
+ if (ctx) {
484
+ const grad = ctx.createLinearGradient(0, 0, 0, 256);
485
+ grad.addColorStop(0, "rgba(255, 255, 255, 0.0)");
486
+ grad.addColorStop(0.14, "rgba(255, 255, 255, 0.92)");
487
+ grad.addColorStop(0.58, "rgba(255, 255, 255, 0.45)");
488
+ grad.addColorStop(1, "rgba(255, 255, 255, 0.0)");
489
+ ctx.fillStyle = grad;
490
+ ctx.fillRect(0, 0, 128, 256);
491
+ }
492
+ const tex = new THREE.CanvasTexture(canvas);
493
+ tex.needsUpdate = true;
494
+ spotlightBeamTextureCache.set(key, tex);
495
+ return tex;
496
+ }
497
+ var ContactShadowDisc3D = ({
498
+ position = [0, 0.012, 0],
499
+ radius = 0.85,
500
+ opacity = 0.3,
501
+ color = "#0F172A",
502
+ scaleX = 1,
503
+ scaleZ = 1
504
+ }) => {
505
+ const tex = (0, import_react3.useMemo)(() => getRadialDiscTexture(color), [color]);
506
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
507
+ "mesh",
508
+ {
509
+ position,
510
+ rotation: [-Math.PI / 2, 0, 0],
511
+ scale: [scaleX, scaleZ, 1],
512
+ renderOrder: 1,
513
+ children: [
514
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [radius * 2, radius * 2] }),
515
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
516
+ "meshBasicMaterial",
517
+ {
518
+ map: tex ?? void 0,
519
+ color,
520
+ transparent: true,
521
+ opacity,
522
+ depthWrite: false,
523
+ polygonOffset: true,
524
+ polygonOffsetFactor: -2
525
+ }
526
+ )
527
+ ]
528
+ }
529
+ );
530
+ };
531
+ var StagePostProcessing3D = ({
532
+ fogColor = "#F8F9FF",
533
+ fogDensity = 0.02,
534
+ spotlightBeams = true,
535
+ beamColor = "#FFF7ED",
536
+ beamOpacity = 0.075,
537
+ beamOrigin = [-4.2, 8.2, 2.8],
538
+ beamTarget = [0, 0, 0],
539
+ depthHaze = true,
540
+ hazeColor = "#E0E7FF",
541
+ hazeOpacity = 0.16,
542
+ seed = 303
543
+ }) => {
544
+ const scene = (0, import_fiber.useThree)((state) => state.scene);
545
+ const frame = (0, import_remotion3.useCurrentFrame)();
546
+ const { fps } = (0, import_remotion3.useVideoConfig)();
547
+ (0, import_react3.useLayoutEffect)(() => {
548
+ const previousFog = scene.fog;
549
+ if (fogDensity > 0) {
550
+ scene.fog = new THREE.FogExp2(fogColor, fogDensity);
551
+ } else {
552
+ scene.fog = null;
553
+ }
554
+ return () => {
555
+ scene.fog = previousFog;
556
+ };
557
+ }, [scene, fogColor, fogDensity]);
558
+ const beamCount = typeof spotlightBeams === "number" ? Math.max(0, Math.min(6, Math.round(spotlightBeams))) : spotlightBeams ? 2 : 0;
559
+ const beams = (0, import_react3.useMemo)(() => {
560
+ if (beamCount === 0) return [];
561
+ const rand = (0, import_prng3.createSeededRandom)(`beams3d:${seed}`);
562
+ const list = [];
563
+ for (let i = 0; i < beamCount; i++) {
564
+ const spreadX = i === 0 ? 0 : (i % 2 === 1 ? 1 : -1) * (3.6 + rand() * 1.8);
565
+ const targetSpreadX = i === 0 ? 0 : spreadX * 0.32;
566
+ list.push({
567
+ origin: [
568
+ beamOrigin[0] + spreadX,
569
+ beamOrigin[1] + (i === 0 ? 0 : rand() * 0.8),
570
+ beamOrigin[2] - i * 0.9
571
+ ],
572
+ target: [
573
+ beamTarget[0] + targetSpreadX,
574
+ beamTarget[1],
575
+ beamTarget[2] - i * 0.35
576
+ ],
577
+ topRadius: 0.28 + rand() * 0.12,
578
+ bottomRadius: 2.15 + rand() * 0.65,
579
+ phase: rand() * Math.PI * 2
580
+ });
581
+ }
582
+ return list;
583
+ }, [beamCount, beamOrigin, beamTarget, seed]);
584
+ const motes = (0, import_react3.useMemo)(() => {
585
+ const rand = (0, import_prng3.createSeededRandom)(`motes3d:${seed}`);
586
+ return Array.from({ length: 16 }, (_, idx) => ({
587
+ id: idx,
588
+ baseX: (rand() - 0.5) * 7.2,
589
+ baseY: 0.6 + rand() * 4.2,
590
+ baseZ: (rand() - 0.4) * 5.2,
591
+ radius: 0.024 + rand() * 0.032,
592
+ phase: rand() * Math.PI * 2,
593
+ freq: 0.031 + rand() * 0.02
594
+ }));
595
+ }, [seed]);
596
+ const coneTex = (0, import_react3.useMemo)(() => getVolumetricConeTexture("default"), []);
597
+ const hazeTex = (0, import_react3.useMemo)(() => getRadialDiscTexture("#FFFFFF"), []);
598
+ const f60 = frame * (60 / Math.max(1, fps));
599
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("group", { name: "stage-post-processing-3d", children: [
600
+ beams.map((b, idx) => {
601
+ const dir = new THREE.Vector3(
602
+ b.target[0] - b.origin[0],
603
+ b.target[1] - b.origin[1],
604
+ b.target[2] - b.origin[2]
605
+ );
606
+ const len = Math.max(0.5, dir.length());
607
+ const mid = [
608
+ (b.origin[0] + b.target[0]) * 0.5,
609
+ (b.origin[1] + b.target[1]) * 0.5,
610
+ (b.origin[2] + b.target[2]) * 0.5
611
+ ];
612
+ const quat = new THREE.Quaternion().setFromUnitVectors(
613
+ new THREE.Vector3(0, -1, 0),
614
+ dir.clone().normalize()
615
+ );
616
+ const euler = new THREE.Euler().setFromQuaternion(quat);
617
+ const breathe = 0.86 + 0.14 * Math.sin(f60 * 0.033 + b.phase);
618
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
619
+ "mesh",
620
+ {
621
+ position: mid,
622
+ rotation: [euler.x, euler.y, euler.z],
623
+ renderOrder: 10,
624
+ children: [
625
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
626
+ "cylinderGeometry",
627
+ {
628
+ args: [b.topRadius, b.bottomRadius, len, 32, 1, true]
629
+ }
630
+ ),
631
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
632
+ "meshBasicMaterial",
633
+ {
634
+ map: coneTex ?? void 0,
635
+ color: beamColor,
636
+ transparent: true,
637
+ opacity: beamOpacity * breathe,
638
+ blending: THREE.AdditiveBlending,
639
+ depthWrite: false,
640
+ side: THREE.DoubleSide
641
+ }
642
+ )
643
+ ]
644
+ },
645
+ `beam-${idx}`
646
+ );
647
+ }),
648
+ beamCount > 0 && motes.map((m) => {
649
+ const x = m.baseX + Math.sin(f60 * m.freq + m.phase) * 0.22;
650
+ const y = m.baseY + Math.cos(f60 * (m.freq * 0.85) + m.phase) * 0.18;
651
+ const z = m.baseZ + Math.sin(f60 * 0.03 + m.phase * 1.3) * 0.16;
652
+ const twinkle = 0.45 + 0.55 * Math.sin(f60 * 0.042 + m.phase);
653
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [x, y, z], renderOrder: 11, children: [
654
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("sphereGeometry", { args: [m.radius, 10, 10] }),
655
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
656
+ "meshBasicMaterial",
657
+ {
658
+ color: beamColor,
659
+ transparent: true,
660
+ opacity: Math.min(0.65, beamOpacity * 5.2 * twinkle),
661
+ blending: THREE.AdditiveBlending,
662
+ depthWrite: false
663
+ }
664
+ )
665
+ ] }, `mote-${m.id}`);
666
+ }),
667
+ depthHaze && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
668
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [-2.2, 2.8, -5.8], renderOrder: 2, children: [
669
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [14, 7.5] }),
670
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
671
+ "meshBasicMaterial",
672
+ {
673
+ map: hazeTex ?? void 0,
674
+ color: hazeColor,
675
+ transparent: true,
676
+ opacity: hazeOpacity,
677
+ depthWrite: false
678
+ }
679
+ )
680
+ ] }),
681
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [2.4, 3.2, -7.6], renderOrder: 2, children: [
682
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [16, 8.5] }),
683
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
684
+ "meshBasicMaterial",
685
+ {
686
+ map: hazeTex ?? void 0,
687
+ color: hazeColor,
688
+ transparent: true,
689
+ opacity: hazeOpacity * 0.78,
690
+ depthWrite: false
691
+ }
692
+ )
693
+ ] })
694
+ ] })
695
+ ] });
696
+ };
697
+
698
+ // packages/kits/src/vfx/SceneTransition.tsx
699
+ var import_remotion4 = require("remotion");
700
+ var import_tokens2 = require("@make-pictures/core");
701
+ var import_jsx_runtime4 = require("react/jsx-runtime");
702
+ var SceneTransition = ({
703
+ atFrame,
704
+ durationInFrames = 28,
705
+ type = "iris-wipe",
706
+ accentColor = import_tokens2.STUDIO_THEME.colors.brand[600],
707
+ backdropColor = "#0F172A",
708
+ direction = "left",
709
+ seed = 51,
710
+ zIndex = 80
711
+ }) => {
712
+ const frame = (0, import_remotion4.useCurrentFrame)();
713
+ const { width, height } = (0, import_remotion4.useVideoConfig)();
714
+ const dur = Math.max(6, durationInFrames);
715
+ const half = dur / 2;
716
+ const startFrame = atFrame - half;
717
+ const endFrame = atFrame + half;
718
+ if (frame <= startFrame || frame >= endFrame) {
719
+ return null;
720
+ }
721
+ const u = (frame - startFrame) / dur;
722
+ const coverProgress = u <= 0.5 ? (0, import_remotion4.interpolate)(u, [0, 0.5], [0, 1], {
723
+ easing: import_remotion4.Easing.inOut(import_remotion4.Easing.cubic),
724
+ extrapolateLeft: "clamp",
725
+ extrapolateRight: "clamp"
726
+ }) : (0, import_remotion4.interpolate)(u, [0.5, 1], [1, 0], {
727
+ easing: import_remotion4.Easing.inOut(import_remotion4.Easing.cubic),
728
+ extrapolateLeft: "clamp",
729
+ extrapolateRight: "clamp"
730
+ });
731
+ const diagRadius = Math.hypot(width, height) * 0.55;
732
+ if (type === "flash-cut") {
733
+ const flashOpacity = u <= 0.5 ? Math.pow(u * 2, 2.2) : Math.pow(Math.max(0, 1 - (u - 0.5) * 2), 1.65);
734
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
735
+ import_remotion4.AbsoluteFill,
736
+ {
737
+ style: {
738
+ pointerEvents: "none",
739
+ zIndex,
740
+ opacity: flashOpacity,
741
+ background: `radial-gradient(circle at 50% 50%, #FFFFFF 0%, #FFFBEB 45%, ${accentColor} 100%)`
742
+ }
743
+ }
744
+ );
745
+ }
746
+ if (type === "whip-pan") {
747
+ const sweep = (0, import_remotion4.interpolate)(u, [0, 1], [-1.25, 1.25], {
748
+ easing: import_remotion4.Easing.inOut(import_remotion4.Easing.cubic)
749
+ });
750
+ const isHorizontal = direction === "left" || direction === "right";
751
+ const sign = direction === "left" || direction === "up" ? -1 : 1;
752
+ const tx = isHorizontal ? sweep * sign * width : 0;
753
+ const ty = !isHorizontal ? sweep * sign * height : 0;
754
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
755
+ import_remotion4.AbsoluteFill,
756
+ {
757
+ style: {
758
+ pointerEvents: "none",
759
+ overflow: "hidden",
760
+ zIndex
761
+ },
762
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
763
+ "div",
764
+ {
765
+ style: {
766
+ position: "absolute",
767
+ left: -width * 0.35,
768
+ top: -height * 0.35,
769
+ width: width * 1.7,
770
+ height: height * 1.7,
771
+ transform: `translate3d(${tx}px, ${ty}px, 0) skewX(${isHorizontal ? -10 * sign : 0}deg)`,
772
+ background: isHorizontal ? `linear-gradient(90deg, transparent 0%, ${accentColor} 16%, ${backdropColor} 32%, ${backdropColor} 68%, ${accentColor} 84%, transparent 100%)` : `linear-gradient(180deg, transparent 0%, ${accentColor} 16%, ${backdropColor} 32%, ${backdropColor} 68%, ${accentColor} 84%, transparent 100%)`,
773
+ boxShadow: `0 0 80px ${accentColor}88`
774
+ }
775
+ }
776
+ )
777
+ }
778
+ );
779
+ }
780
+ if (type === "paper-curtain") {
781
+ const slidePct = (1 - coverProgress) * 104;
782
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
783
+ import_remotion4.AbsoluteFill,
784
+ {
785
+ style: {
786
+ pointerEvents: "none",
787
+ overflow: "hidden",
788
+ zIndex
789
+ },
790
+ children: [
791
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
792
+ "div",
793
+ {
794
+ style: {
795
+ position: "absolute",
796
+ left: 0,
797
+ top: 0,
798
+ width: "53%",
799
+ height: "100%",
800
+ backgroundColor: "#FFFBEB",
801
+ borderRight: `14px solid ${accentColor}`,
802
+ boxShadow: "18px 0 48px rgba(15, 23, 42, 0.35)",
803
+ transform: `translate3d(${-slidePct}%, 0, 0)`
804
+ }
805
+ }
806
+ ),
807
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
808
+ "div",
809
+ {
810
+ style: {
811
+ position: "absolute",
812
+ right: 0,
813
+ top: 0,
814
+ width: "53%",
815
+ height: "100%",
816
+ backgroundColor: "#FEF3C7",
817
+ borderLeft: `14px solid ${accentColor}`,
818
+ boxShadow: "-18px 0 48px rgba(15, 23, 42, 0.35)",
819
+ transform: `translate3d(${slidePct}%, 0, 0)`
820
+ }
821
+ }
822
+ )
823
+ ]
824
+ }
825
+ );
826
+ }
827
+ if (type === "ink-wash") {
828
+ const filterId = `mp-ink-wash-${Math.abs(seed)}`;
829
+ const blobRadius = coverProgress * diagRadius * 1.22;
830
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
831
+ import_remotion4.AbsoluteFill,
832
+ {
833
+ style: {
834
+ pointerEvents: "none",
835
+ overflow: "hidden",
836
+ zIndex
837
+ },
838
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width, height, viewBox: `0 0 ${width} ${height}`, children: [
839
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("filter", { id: filterId, x: "-20%", y: "-20%", width: "140%", height: "140%", children: [
840
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
841
+ "feTurbulence",
842
+ {
843
+ type: "fractalNoise",
844
+ baseFrequency: "0.012",
845
+ numOctaves: 3,
846
+ seed: Math.abs(seed) % 97,
847
+ result: "noise"
848
+ }
849
+ ),
850
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
851
+ "feDisplacementMap",
852
+ {
853
+ in: "SourceGraphic",
854
+ in2: "noise",
855
+ scale: Math.round(140 * Math.sin(Math.PI * u)),
856
+ xChannelSelector: "R",
857
+ yChannelSelector: "G"
858
+ }
859
+ )
860
+ ] }) }),
861
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("g", { filter: `url(#${filterId})`, children: [
862
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
863
+ "circle",
864
+ {
865
+ cx: width / 2,
866
+ cy: height / 2,
867
+ r: blobRadius + 18,
868
+ fill: accentColor
869
+ }
870
+ ),
871
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
872
+ "circle",
873
+ {
874
+ cx: width / 2,
875
+ cy: height / 2,
876
+ r: blobRadius,
877
+ fill: backdropColor
878
+ }
879
+ )
880
+ ] })
881
+ ] })
882
+ }
883
+ );
884
+ }
885
+ const holeRadius = Math.max(0, (1 - coverProgress) * diagRadius);
886
+ const maskId = `mp-iris-mask-${Math.abs(seed)}-${atFrame}`;
887
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
888
+ import_remotion4.AbsoluteFill,
889
+ {
890
+ style: {
891
+ pointerEvents: "none",
892
+ overflow: "hidden",
893
+ zIndex
894
+ },
895
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { width, height, viewBox: `0 0 ${width} ${height}`, children: [
896
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("defs", { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("mask", { id: maskId, children: [
897
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { x: 0, y: 0, width, height, fill: "white" }),
898
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
899
+ "circle",
900
+ {
901
+ cx: width / 2,
902
+ cy: height / 2,
903
+ r: holeRadius,
904
+ fill: "black"
905
+ }
906
+ )
907
+ ] }) }),
908
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
909
+ "rect",
910
+ {
911
+ x: 0,
912
+ y: 0,
913
+ width,
914
+ height,
915
+ fill: backdropColor,
916
+ mask: `url(#${maskId})`
917
+ }
918
+ ),
919
+ holeRadius > 2 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
920
+ "circle",
921
+ {
922
+ cx: width / 2,
923
+ cy: height / 2,
924
+ r: holeRadius,
925
+ fill: "none",
926
+ stroke: accentColor,
927
+ strokeWidth: 10
928
+ }
929
+ )
930
+ ] })
931
+ }
932
+ );
933
+ };