@make-pictures/kits 0.0.0-stage → 2.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 (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,1087 @@
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/paper-diorama-3d/index.ts
31
+ var paper_diorama_3d_exports = {};
32
+ __export(paper_diorama_3d_exports, {
33
+ ImageCutout3D: () => ImageCutout3D,
34
+ PaperBookPageTurn3D: () => PaperBookPageTurn3D,
35
+ PaperCameraRig3D: () => PaperCameraRig3D,
36
+ PaperCloudCutout3D: () => PaperCloudCutout3D,
37
+ PaperCutout3D: () => PaperCutout3D,
38
+ PaperMountainBackdrop3D: () => PaperMountainBackdrop3D,
39
+ PaperPineTree3D: () => PaperPineTree3D,
40
+ PaperStageLighting3D: () => PaperStageLighting3D,
41
+ PopUpBookBase3D: () => PopUpBookBase3D,
42
+ PopUpHinge3D: () => PopUpHinge3D,
43
+ buildPaperCutoutCompositeKey: () => buildPaperCutoutCompositeKey,
44
+ getFloorTexture: () => getFloorTexture,
45
+ getPaperTextureCacheStats: () => getPaperTextureCacheStats,
46
+ prunePaperTextureCache: () => prunePaperTextureCache,
47
+ serializePaperCutoutDeps: () => serializePaperCutoutDeps
48
+ });
49
+ module.exports = __toCommonJS(paper_diorama_3d_exports);
50
+
51
+ // packages/kits/src/paper-diorama-3d/PaperCutout3D.tsx
52
+ var import_react = require("react");
53
+ var THREE = __toESM(require("three"), 1);
54
+ var import_core = require("@make-pictures/core");
55
+ var import_jsx_runtime = require("react/jsx-runtime");
56
+ var MAX_CACHED_CUTOUTS = 64;
57
+ var TEXTURE_CACHE = /* @__PURE__ */ new Map();
58
+ var scheduledPruneTimer = null;
59
+ function touchCacheEntry(compositeKey, entry) {
60
+ TEXTURE_CACHE.delete(compositeKey);
61
+ TEXTURE_CACHE.set(compositeKey, entry);
62
+ }
63
+ function disposeCacheEntry(entry) {
64
+ if (entry.disposed) return;
65
+ entry.disposed = true;
66
+ entry.frontTexture.dispose();
67
+ entry.backTexture.dispose();
68
+ entry.depthMaterial.dispose();
69
+ }
70
+ function prunePaperTextureCache(maxEntries = MAX_CACHED_CUTOUTS) {
71
+ if (TEXTURE_CACHE.size <= maxEntries) return 0;
72
+ let evicted = 0;
73
+ for (const [key, entry] of TEXTURE_CACHE.entries()) {
74
+ if (TEXTURE_CACHE.size <= maxEntries) break;
75
+ if (entry.refCount <= 0) {
76
+ TEXTURE_CACHE.delete(key);
77
+ disposeCacheEntry(entry);
78
+ evicted += 1;
79
+ }
80
+ }
81
+ return evicted;
82
+ }
83
+ function scheduleCachePrune() {
84
+ if (scheduledPruneTimer !== null) return;
85
+ scheduledPruneTimer = setTimeout(() => {
86
+ scheduledPruneTimer = null;
87
+ prunePaperTextureCache();
88
+ }, 60);
89
+ }
90
+ function getPaperTextureCacheStats() {
91
+ let activeCount = 0;
92
+ for (const entry of TEXTURE_CACHE.values()) {
93
+ if (entry.refCount > 0) activeCount += 1;
94
+ }
95
+ return {
96
+ size: TEXTURE_CACHE.size,
97
+ activeCount,
98
+ maxEntries: MAX_CACHED_CUTOUTS
99
+ };
100
+ }
101
+ var DRAW_FN_HASH_CACHE = /* @__PURE__ */ new WeakMap();
102
+ function getDrawFunctionHash(draw) {
103
+ const cached = DRAW_FN_HASH_CACHE.get(draw);
104
+ if (cached !== void 0) return cached;
105
+ const computed = (0, import_core.hashToHex)(draw.toString());
106
+ DRAW_FN_HASH_CACHE.set(draw, computed);
107
+ return computed;
108
+ }
109
+ function serializePaperCutoutDeps(cacheDeps) {
110
+ return cacheDeps && cacheDeps.length > 0 ? cacheDeps.map((d) => String(d ?? "")).join("") : "";
111
+ }
112
+ function buildPaperCutoutCompositeKey(cacheKey, pixelWidth, pixelHeight, whiteBorderPx, fontRevision, draw, cacheDeps) {
113
+ const depsSignature = serializePaperCutoutDeps(cacheDeps);
114
+ const fnHash = getDrawFunctionHash(draw);
115
+ const codeAndDepsHash = depsSignature ? (0, import_core.hashToHex)(`${fnHash}${depsSignature}`) : fnHash;
116
+ return `${cacheKey}|${pixelWidth}x${pixelHeight}|b${whiteBorderPx}|f${fontRevision}|h${codeAndDepsHash}`;
117
+ }
118
+ function getOrCreatePaperCutoutTextures(compositeKey, seedKey, pixelWidth, pixelHeight, whiteBorderPx, draw) {
119
+ const existing = TEXTURE_CACHE.get(compositeKey);
120
+ if (existing && !existing.disposed) {
121
+ touchCacheEntry(compositeKey, existing);
122
+ return existing;
123
+ }
124
+ const artCanvas = document.createElement("canvas");
125
+ artCanvas.width = pixelWidth;
126
+ artCanvas.height = pixelHeight;
127
+ const artCtx = artCanvas.getContext("2d");
128
+ artCtx.lineCap = "round";
129
+ artCtx.lineJoin = "round";
130
+ draw(artCtx, pixelWidth, pixelHeight);
131
+ const whiteStampCanvas = document.createElement("canvas");
132
+ whiteStampCanvas.width = pixelWidth;
133
+ whiteStampCanvas.height = pixelHeight;
134
+ const whiteCtx = whiteStampCanvas.getContext("2d");
135
+ whiteCtx.drawImage(artCanvas, 0, 0);
136
+ whiteCtx.globalCompositeOperation = "source-in";
137
+ whiteCtx.fillStyle = "#FFFDF7";
138
+ whiteCtx.fillRect(0, 0, pixelWidth, pixelHeight);
139
+ const edgeStampCanvas = document.createElement("canvas");
140
+ edgeStampCanvas.width = pixelWidth;
141
+ edgeStampCanvas.height = pixelHeight;
142
+ const edgeCtx = edgeStampCanvas.getContext("2d");
143
+ edgeCtx.drawImage(artCanvas, 0, 0);
144
+ edgeCtx.globalCompositeOperation = "source-in";
145
+ edgeCtx.fillStyle = "#573B26";
146
+ edgeCtx.fillRect(0, 0, pixelWidth, pixelHeight);
147
+ const frontCanvas = document.createElement("canvas");
148
+ frontCanvas.width = pixelWidth;
149
+ frontCanvas.height = pixelHeight;
150
+ const frontCtx = frontCanvas.getContext("2d");
151
+ if (whiteBorderPx > 0) {
152
+ const outerRadius = whiteBorderPx + 3.5;
153
+ const steps = 20;
154
+ for (let i = 0; i < steps; i++) {
155
+ const angle = i / steps * Math.PI * 2;
156
+ frontCtx.drawImage(
157
+ edgeStampCanvas,
158
+ Math.cos(angle) * outerRadius,
159
+ Math.sin(angle) * outerRadius
160
+ );
161
+ }
162
+ for (const r of [whiteBorderPx, whiteBorderPx * 0.55]) {
163
+ for (let i = 0; i < steps; i++) {
164
+ const angle = i / steps * Math.PI * 2;
165
+ frontCtx.drawImage(
166
+ whiteStampCanvas,
167
+ Math.cos(angle) * r,
168
+ Math.sin(angle) * r
169
+ );
170
+ }
171
+ }
172
+ }
173
+ frontCtx.drawImage(artCanvas, 0, 0);
174
+ const rng = (0, import_core.createSeededRandom)(`${seedKey}:${pixelWidth}x${pixelHeight}`);
175
+ frontCtx.save();
176
+ frontCtx.globalCompositeOperation = "source-atop";
177
+ for (let i = 0; i < 220; i++) {
178
+ const gx = rng() * pixelWidth;
179
+ const gy = rng() * pixelHeight;
180
+ const fiberLen = 12 + rng() * 14;
181
+ const fiberH = 1.2 + rng() * 1.1;
182
+ const tilt = (rng() - 0.5) * 0.36;
183
+ frontCtx.save();
184
+ frontCtx.translate(gx, gy);
185
+ frontCtx.rotate(tilt);
186
+ frontCtx.fillStyle = i % 2 === 0 ? "rgba(255, 253, 245, 0.036)" : "rgba(120, 53, 15, 0.028)";
187
+ frontCtx.fillRect(-fiberLen * 0.5, -fiberH * 0.5, fiberLen, fiberH);
188
+ frontCtx.restore();
189
+ }
190
+ frontCtx.restore();
191
+ const backCanvas = document.createElement("canvas");
192
+ backCanvas.width = pixelWidth;
193
+ backCanvas.height = pixelHeight;
194
+ const backCtx = backCanvas.getContext("2d");
195
+ backCtx.drawImage(frontCanvas, 0, 0);
196
+ backCtx.globalCompositeOperation = "source-in";
197
+ backCtx.fillStyle = "#E6D7C3";
198
+ backCtx.fillRect(0, 0, pixelWidth, pixelHeight);
199
+ backCtx.globalCompositeOperation = "source-over";
200
+ artCanvas.width = 0;
201
+ artCanvas.height = 0;
202
+ whiteStampCanvas.width = 0;
203
+ whiteStampCanvas.height = 0;
204
+ edgeStampCanvas.width = 0;
205
+ edgeStampCanvas.height = 0;
206
+ const frontTexture = new THREE.CanvasTexture(frontCanvas);
207
+ frontTexture.colorSpace = THREE.SRGBColorSpace;
208
+ frontTexture.anisotropy = 8;
209
+ frontTexture.needsUpdate = true;
210
+ const backTexture = new THREE.CanvasTexture(backCanvas);
211
+ backTexture.colorSpace = THREE.SRGBColorSpace;
212
+ backTexture.anisotropy = 4;
213
+ backTexture.needsUpdate = true;
214
+ const depthMaterial = new THREE.MeshDepthMaterial({
215
+ depthPacking: THREE.RGBADepthPacking,
216
+ map: frontTexture,
217
+ alphaTest: 0.38
218
+ });
219
+ const result = {
220
+ frontTexture,
221
+ backTexture,
222
+ depthMaterial,
223
+ refCount: 0,
224
+ disposed: false
225
+ };
226
+ TEXTURE_CACHE.set(compositeKey, result);
227
+ prunePaperTextureCache();
228
+ return result;
229
+ }
230
+ var PaperCutout3D = ({
231
+ cacheKey,
232
+ cacheDeps,
233
+ pixelWidth = 512,
234
+ pixelHeight = 512,
235
+ width,
236
+ height,
237
+ draw,
238
+ whiteBorderPx = 14,
239
+ position = [0, 0, 0],
240
+ rotation = [0, 0, 0],
241
+ scale = 1,
242
+ anchor = "bottom",
243
+ thickness = 0.038,
244
+ castShadow = true,
245
+ receiveShadow = true,
246
+ emissive = "#000000",
247
+ emissiveIntensity = 0,
248
+ opacity = 1
249
+ }) => {
250
+ const fontRevision = (0, import_core.useStudioFontsReady)();
251
+ const depsSignature = serializePaperCutoutDeps(cacheDeps);
252
+ const drawFnHash = getDrawFunctionHash(draw);
253
+ const compositeKey = (0, import_react.useMemo)(() => {
254
+ const codeAndDepsHash = depsSignature ? (0, import_core.hashToHex)(`${drawFnHash}${depsSignature}`) : drawFnHash;
255
+ return `${cacheKey}|${pixelWidth}x${pixelHeight}|b${whiteBorderPx}|f${fontRevision}|h${codeAndDepsHash}`;
256
+ }, [
257
+ cacheKey,
258
+ pixelWidth,
259
+ pixelHeight,
260
+ whiteBorderPx,
261
+ fontRevision,
262
+ drawFnHash,
263
+ depsSignature
264
+ ]);
265
+ const cachedEntry = (0, import_react.useMemo)(
266
+ () => getOrCreatePaperCutoutTextures(
267
+ compositeKey,
268
+ cacheKey,
269
+ pixelWidth,
270
+ pixelHeight,
271
+ whiteBorderPx,
272
+ draw
273
+ ),
274
+ // eslint-disable-next-line react-hooks/exhaustive-deps
275
+ [compositeKey]
276
+ );
277
+ (0, import_react.useEffect)(() => {
278
+ cachedEntry.refCount += 1;
279
+ touchCacheEntry(compositeKey, cachedEntry);
280
+ return () => {
281
+ cachedEntry.refCount = Math.max(0, cachedEntry.refCount - 1);
282
+ scheduleCachePrune();
283
+ };
284
+ }, [compositeKey, cachedEntry]);
285
+ const { frontTexture, backTexture, depthMaterial } = cachedEntry;
286
+ const yOffset = anchor === "bottom" ? height / 2 : anchor === "top" ? -height / 2 : 0;
287
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("group", { position, rotation, scale, children: [
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
289
+ "mesh",
290
+ {
291
+ position: [0, yOffset, 0],
292
+ castShadow,
293
+ receiveShadow,
294
+ customDepthMaterial: depthMaterial,
295
+ children: [
296
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("planeGeometry", { args: [width, height] }),
297
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
298
+ "meshStandardMaterial",
299
+ {
300
+ map: frontTexture,
301
+ transparent: true,
302
+ alphaTest: 0.35,
303
+ opacity,
304
+ roughness: 0.86,
305
+ metalness: 0.04,
306
+ emissive,
307
+ emissiveIntensity,
308
+ side: THREE.DoubleSide
309
+ }
310
+ )
311
+ ]
312
+ }
313
+ ),
314
+ thickness > 5e-3 && opacity > 0.5 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
315
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
316
+ "mesh",
317
+ {
318
+ position: [0, yOffset, -thickness * 0.5],
319
+ receiveShadow,
320
+ children: [
321
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("planeGeometry", { args: [width, height] }),
322
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
323
+ "meshStandardMaterial",
324
+ {
325
+ map: backTexture,
326
+ transparent: true,
327
+ alphaTest: 0.38,
328
+ roughness: 0.94,
329
+ metalness: 0,
330
+ side: THREE.DoubleSide
331
+ }
332
+ )
333
+ ]
334
+ }
335
+ ),
336
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
337
+ "mesh",
338
+ {
339
+ position: [0, yOffset, -thickness],
340
+ castShadow,
341
+ receiveShadow,
342
+ customDepthMaterial: depthMaterial,
343
+ children: [
344
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("planeGeometry", { args: [width, height] }),
345
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
346
+ "meshStandardMaterial",
347
+ {
348
+ map: frontTexture,
349
+ transparent: true,
350
+ alphaTest: 0.38,
351
+ roughness: 0.9,
352
+ metalness: 0.02,
353
+ side: THREE.DoubleSide
354
+ }
355
+ )
356
+ ]
357
+ }
358
+ )
359
+ ] })
360
+ ] });
361
+ };
362
+ var PopUpHinge3D = ({
363
+ foldProgress,
364
+ position = [0, 0, 0],
365
+ foldDirection = 1,
366
+ children
367
+ }) => {
368
+ const clamped = Math.max(0, Math.min(1.05, foldProgress));
369
+ const theta = (1 - Math.min(1, clamped)) * (Math.PI * 0.46) * foldDirection;
370
+ const c = Math.cos(theta);
371
+ const s = Math.sin(theta);
372
+ const posX = position[0];
373
+ const posY = position[1];
374
+ const posZ = position[2];
375
+ const foldMatrix = (0, import_react.useMemo)(() => {
376
+ const m = new THREE.Matrix4();
377
+ m.set(
378
+ 1,
379
+ 0,
380
+ 0,
381
+ posX,
382
+ 0,
383
+ c,
384
+ 0,
385
+ posY,
386
+ 0,
387
+ -s,
388
+ 1,
389
+ posZ,
390
+ 0,
391
+ 0,
392
+ 0,
393
+ 1
394
+ );
395
+ return m;
396
+ }, [c, s, posX, posY, posZ]);
397
+ if (clamped <= 0.01) return null;
398
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("group", { matrixAutoUpdate: false, matrix: foldMatrix, children });
399
+ };
400
+
401
+ // packages/kits/src/paper-diorama-3d/ImageCutout3D.tsx
402
+ var import_react2 = require("react");
403
+ var import_remotion = require("remotion");
404
+ var import_core2 = require("@make-pictures/core");
405
+ var import_jsx_runtime2 = require("react/jsx-runtime");
406
+ var IMAGE_ELEMENT_CACHE = /* @__PURE__ */ new Map();
407
+ var IMAGE_LOAD_TIMEOUT_MS = 6e3;
408
+ var ImageCutout3D = ({
409
+ src,
410
+ cacheKey,
411
+ width,
412
+ height,
413
+ pixelWidth = 512,
414
+ pixelHeight = 512,
415
+ whiteBorderPx = 14,
416
+ paddingPx,
417
+ objectFit = "contain",
418
+ position = [0, 0, 0],
419
+ rotation = [0, 0, 0],
420
+ scale = 1,
421
+ anchor = "bottom",
422
+ thickness = 0.038,
423
+ castShadow = true,
424
+ receiveShadow = true,
425
+ emissive = "#000000",
426
+ emissiveIntensity = 0,
427
+ opacity = 1
428
+ }) => {
429
+ const safePadding = paddingPx ?? Math.max(24, whiteBorderPx + 14);
430
+ const resolvedCacheKey = cacheKey ?? `img-cutout-${(0, import_core2.hashToHex)(src)}`;
431
+ const [loadedImage, setLoadedImage] = (0, import_react2.useState)(
432
+ () => IMAGE_ELEMENT_CACHE.get(src) ?? null
433
+ );
434
+ const [loadFailed, setLoadFailed] = (0, import_react2.useState)(false);
435
+ const [delayHandle] = (0, import_react2.useState)(() => {
436
+ if (typeof Image === "undefined" || IMAGE_ELEMENT_CACHE.has(src)) {
437
+ return null;
438
+ }
439
+ try {
440
+ return (0, import_remotion.delayRender)(`Loading ImageCutout3D (${src.slice(0, 64)})`);
441
+ } catch {
442
+ return null;
443
+ }
444
+ });
445
+ (0, import_react2.useEffect)(() => {
446
+ let released = false;
447
+ const release = () => {
448
+ if (!released && delayHandle !== null) {
449
+ released = true;
450
+ try {
451
+ (0, import_remotion.continueRender)(delayHandle);
452
+ } catch {
453
+ }
454
+ }
455
+ };
456
+ const cached = IMAGE_ELEMENT_CACHE.get(src);
457
+ if (cached) {
458
+ setLoadedImage(cached);
459
+ setLoadFailed(false);
460
+ release();
461
+ return;
462
+ }
463
+ if (typeof Image === "undefined") {
464
+ release();
465
+ return;
466
+ }
467
+ let cancelled = false;
468
+ const img = new Image();
469
+ img.crossOrigin = "anonymous";
470
+ img.decoding = "async";
471
+ const timeout = setTimeout(() => {
472
+ if (cancelled) return;
473
+ setLoadFailed(true);
474
+ release();
475
+ }, IMAGE_LOAD_TIMEOUT_MS);
476
+ img.onload = () => {
477
+ clearTimeout(timeout);
478
+ IMAGE_ELEMENT_CACHE.set(src, img);
479
+ if (!cancelled) {
480
+ setLoadedImage(img);
481
+ setLoadFailed(false);
482
+ }
483
+ release();
484
+ };
485
+ img.onerror = () => {
486
+ clearTimeout(timeout);
487
+ if (!cancelled) {
488
+ setLoadFailed(true);
489
+ }
490
+ release();
491
+ };
492
+ img.src = src;
493
+ return () => {
494
+ cancelled = true;
495
+ clearTimeout(timeout);
496
+ release();
497
+ };
498
+ }, [src, delayHandle]);
499
+ const drawImageCutout = (0, import_react2.useCallback)(
500
+ (ctx, w, h) => {
501
+ const innerW = Math.max(16, w - safePadding * 2);
502
+ const innerH = Math.max(16, h - safePadding * 2);
503
+ if (loadedImage && loadedImage.naturalWidth > 0 && loadedImage.naturalHeight > 0) {
504
+ const natW = loadedImage.naturalWidth;
505
+ const natH = loadedImage.naturalHeight;
506
+ let drawW = innerW;
507
+ let drawH = innerH;
508
+ let drawX = safePadding;
509
+ let drawY = safePadding;
510
+ if (objectFit === "contain") {
511
+ const fitScale = Math.min(innerW / natW, innerH / natH);
512
+ drawW = natW * fitScale;
513
+ drawH = natH * fitScale;
514
+ drawX = (w - drawW) / 2;
515
+ drawY = anchor === "bottom" ? h - safePadding - drawH : (h - drawH) / 2;
516
+ } else if (objectFit === "cover") {
517
+ const coverScale = Math.max(innerW / natW, innerH / natH);
518
+ drawW = natW * coverScale;
519
+ drawH = natH * coverScale;
520
+ drawX = (w - drawW) / 2;
521
+ drawY = (h - drawH) / 2;
522
+ ctx.save();
523
+ ctx.beginPath();
524
+ ctx.rect(safePadding, safePadding, innerW, innerH);
525
+ ctx.clip();
526
+ ctx.drawImage(loadedImage, drawX, drawY, drawW, drawH);
527
+ ctx.restore();
528
+ return;
529
+ }
530
+ ctx.drawImage(loadedImage, drawX, drawY, drawW, drawH);
531
+ return;
532
+ }
533
+ if (loadFailed) {
534
+ ctx.fillStyle = "#F1F5F9";
535
+ ctx.strokeStyle = "#94A3B8";
536
+ ctx.lineWidth = 6;
537
+ ctx.beginPath();
538
+ ctx.roundRect(safePadding, safePadding, innerW, innerH, 24);
539
+ ctx.fill();
540
+ ctx.stroke();
541
+ }
542
+ },
543
+ [loadedImage, loadFailed, safePadding, objectFit, anchor]
544
+ );
545
+ if (!loadedImage && !loadFailed) {
546
+ return null;
547
+ }
548
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
549
+ PaperCutout3D,
550
+ {
551
+ cacheKey: resolvedCacheKey,
552
+ cacheDeps: [
553
+ src,
554
+ loadedImage ? 1 : 0,
555
+ loadFailed ? 1 : 0,
556
+ safePadding,
557
+ objectFit,
558
+ anchor
559
+ ],
560
+ pixelWidth,
561
+ pixelHeight,
562
+ width,
563
+ height,
564
+ draw: drawImageCutout,
565
+ whiteBorderPx,
566
+ position,
567
+ rotation,
568
+ scale,
569
+ anchor,
570
+ thickness,
571
+ castShadow,
572
+ receiveShadow,
573
+ emissive,
574
+ emissiveIntensity,
575
+ opacity
576
+ }
577
+ );
578
+ };
579
+
580
+ // packages/kits/src/paper-diorama-3d/PaperPopUpBook3D.tsx
581
+ var import_react3 = require("react");
582
+ var THREE2 = __toESM(require("three"), 1);
583
+ var import_jsx_runtime3 = require("react/jsx-runtime");
584
+ var MAX_FLOOR_TEXTURES = 8;
585
+ var FLOOR_TEX_CACHE = /* @__PURE__ */ new Map();
586
+ function getFloorTexture(theme) {
587
+ const existing = FLOOR_TEX_CACHE.get(theme);
588
+ if (existing) {
589
+ FLOOR_TEX_CACHE.delete(theme);
590
+ FLOOR_TEX_CACHE.set(theme, existing);
591
+ return existing;
592
+ }
593
+ const canvas = document.createElement("canvas");
594
+ canvas.width = 1024;
595
+ canvas.height = 1024;
596
+ const ctx = canvas.getContext("2d");
597
+ if (theme === "mint-plains") {
598
+ const grad = ctx.createLinearGradient(0, 0, 0, 1024);
599
+ grad.addColorStop(0, "#A7F3D0");
600
+ grad.addColorStop(0.55, "#6EE7B7");
601
+ grad.addColorStop(1, "#A7F3D0");
602
+ ctx.fillStyle = grad;
603
+ ctx.fillRect(0, 0, 1024, 1024);
604
+ ctx.fillStyle = "#FDE68A";
605
+ ctx.beginPath();
606
+ ctx.moveTo(410, 0);
607
+ ctx.lineTo(614, 0);
608
+ ctx.lineTo(760, 1024);
609
+ ctx.lineTo(264, 1024);
610
+ ctx.closePath();
611
+ ctx.fill();
612
+ ctx.strokeStyle = "#F59E0B";
613
+ ctx.lineWidth = 6;
614
+ ctx.setLineDash([18, 14]);
615
+ ctx.stroke();
616
+ ctx.setLineDash([]);
617
+ } else if (theme === "checkerboard-tile") {
618
+ ctx.fillStyle = "#FFFBEB";
619
+ ctx.fillRect(0, 0, 1024, 1024);
620
+ const cols = 12;
621
+ const rows = 12;
622
+ const cw = 1024 / cols;
623
+ const rh = 1024 / rows;
624
+ for (let r = 0; r < rows; r++) {
625
+ for (let c = 0; c < cols; c++) {
626
+ if ((r + c) % 2 === 0) {
627
+ ctx.fillStyle = "#334155";
628
+ ctx.fillRect(c * cw, r * rh, cw, rh);
629
+ } else {
630
+ ctx.fillStyle = "#FEF3C7";
631
+ ctx.fillRect(c * cw, r * rh, cw, rh);
632
+ }
633
+ }
634
+ }
635
+ } else if (theme === "warm-parquet") {
636
+ ctx.fillStyle = "#B45309";
637
+ ctx.fillRect(0, 0, 1024, 1024);
638
+ for (let r = 0; r < 16; r++) {
639
+ ctx.fillStyle = r % 2 === 0 ? "#92400E" : "#B45309";
640
+ ctx.fillRect(0, r * 64, 1024, 62);
641
+ ctx.strokeStyle = "#78350F";
642
+ ctx.lineWidth = 3;
643
+ ctx.beginPath();
644
+ ctx.moveTo(0, r * 64);
645
+ ctx.lineTo(1024, r * 64);
646
+ ctx.stroke();
647
+ }
648
+ ctx.fillStyle = "#881337";
649
+ ctx.fillRect(140, 180, 744, 660);
650
+ ctx.strokeStyle = "#FBBF24";
651
+ ctx.lineWidth = 14;
652
+ ctx.strokeRect(164, 204, 696, 612);
653
+ } else {
654
+ const grad = ctx.createLinearGradient(0, 0, 0, 1024);
655
+ grad.addColorStop(0, "#A7F3D0");
656
+ grad.addColorStop(0.62, "#6EE7B7");
657
+ grad.addColorStop(0.63, "#D97706");
658
+ grad.addColorStop(1, "#92400E");
659
+ ctx.fillStyle = grad;
660
+ ctx.fillRect(0, 0, 1024, 1024);
661
+ }
662
+ ctx.strokeStyle = "#FFFDF7";
663
+ ctx.lineWidth = 28;
664
+ ctx.strokeRect(14, 14, 996, 996);
665
+ ctx.strokeStyle = "#D6C4A8";
666
+ ctx.lineWidth = 6;
667
+ ctx.strokeRect(28, 28, 968, 968);
668
+ const tex = new THREE2.CanvasTexture(canvas);
669
+ tex.colorSpace = THREE2.SRGBColorSpace;
670
+ tex.anisotropy = 8;
671
+ tex.needsUpdate = true;
672
+ if (FLOOR_TEX_CACHE.size >= MAX_FLOOR_TEXTURES) {
673
+ const oldestKey = FLOOR_TEX_CACHE.keys().next().value;
674
+ if (oldestKey !== void 0) {
675
+ const oldestTex = FLOOR_TEX_CACHE.get(oldestKey);
676
+ FLOOR_TEX_CACHE.delete(oldestKey);
677
+ oldestTex?.dispose();
678
+ }
679
+ }
680
+ FLOOR_TEX_CACHE.set(theme, tex);
681
+ return tex;
682
+ }
683
+ var PaperBookPageTurn3D = ({
684
+ pageTurnProgress,
685
+ nextFloorTheme,
686
+ spreadWidth = 23.4,
687
+ spreadDepth = 15.4
688
+ }) => {
689
+ const nextFloorTex = (0, import_react3.useMemo)(
690
+ () => getFloorTexture(nextFloorTheme),
691
+ [nextFloorTheme]
692
+ );
693
+ const isTurning = pageTurnProgress > 0.01 && pageTurnProgress < 0.99;
694
+ if (!isTurning) {
695
+ return null;
696
+ }
697
+ const halfW = spreadWidth / 2;
698
+ const smoothP = 0.5 - 0.5 * Math.cos(pageTurnProgress * Math.PI);
699
+ const rollX = halfW - smoothP * spreadWidth;
700
+ const unrolledWidth = Math.max(0.05, halfW - rollX);
701
+ const unrolledCenterX = rollX + unrolledWidth / 2;
702
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("group", { children: [
703
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
704
+ "mesh",
705
+ {
706
+ position: [unrolledCenterX, 0.015, -0.5],
707
+ rotation: [-Math.PI / 2, 0, 0],
708
+ scale: [unrolledWidth, spreadDepth, 1],
709
+ receiveShadow: true,
710
+ children: [
711
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [1, 1] }),
712
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
713
+ "meshStandardMaterial",
714
+ {
715
+ map: nextFloorTex,
716
+ roughness: 0.88,
717
+ metalness: 0.02
718
+ }
719
+ )
720
+ ]
721
+ }
722
+ ),
723
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
724
+ "mesh",
725
+ {
726
+ position: [rollX, 0.024, -0.5],
727
+ scale: [0.18, 0.018, spreadDepth + 0.02],
728
+ receiveShadow: true,
729
+ children: [
730
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("boxGeometry", { args: [1, 1, 1] }),
731
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
732
+ "meshStandardMaterial",
733
+ {
734
+ color: "#FFFDF7",
735
+ roughness: 0.85,
736
+ metalness: 0.02
737
+ }
738
+ )
739
+ ]
740
+ }
741
+ ),
742
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
743
+ "mesh",
744
+ {
745
+ position: [rollX + 0.12, 0.026, -0.5],
746
+ scale: [0.06, 0.018, spreadDepth - 0.02],
747
+ children: [
748
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("boxGeometry", { args: [1, 1, 1] }),
749
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
750
+ "meshStandardMaterial",
751
+ {
752
+ color: "#FBBF24",
753
+ roughness: 0.4,
754
+ metalness: 0.45
755
+ }
756
+ )
757
+ ]
758
+ }
759
+ )
760
+ ] });
761
+ };
762
+ var PopUpBookBase3D = ({ floorTheme, nextFloorTheme, pageTurnProgress = 0 }) => {
763
+ const floorTex = (0, import_react3.useMemo)(() => getFloorTexture(floorTheme), [floorTheme]);
764
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("group", { children: [
765
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
766
+ "mesh",
767
+ {
768
+ position: [0, -0.42, 0],
769
+ rotation: [-Math.PI / 2, 0, 0],
770
+ receiveShadow: true,
771
+ children: [
772
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [64, 48] }),
773
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meshStandardMaterial", { color: "#3B1D0A", roughness: 0.92 })
774
+ ]
775
+ }
776
+ ),
777
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [0, -0.22, -0.5], receiveShadow: true, castShadow: true, children: [
778
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("boxGeometry", { args: [24.6, 0.18, 16.6] }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meshStandardMaterial", { color: "#7C2D12", roughness: 0.8, metalness: 0.08 })
780
+ ] }),
781
+ [
782
+ [-11.9, -8],
783
+ [11.9, -8],
784
+ [-11.9, 7],
785
+ [11.9, 7]
786
+ ].map(([cx, cz], i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [cx, -0.12, cz], children: [
787
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("boxGeometry", { args: [0.8, 0.06, 0.8] }),
788
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
789
+ "meshStandardMaterial",
790
+ {
791
+ color: "#FBBF24",
792
+ roughness: 0.35,
793
+ metalness: 0.65
794
+ }
795
+ )
796
+ ] }, i)),
797
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("mesh", { position: [0, -0.08, -0.5], receiveShadow: true, castShadow: true, children: [
798
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("boxGeometry", { args: [23.6, 0.16, 15.6] }),
799
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("meshStandardMaterial", { color: "#F5EFE6", roughness: 0.9 })
800
+ ] }),
801
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
802
+ "mesh",
803
+ {
804
+ position: [0, 5e-3, -0.5],
805
+ rotation: [-Math.PI / 2, 0, 0],
806
+ receiveShadow: true,
807
+ children: [
808
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("planeGeometry", { args: [23.4, 15.4] }),
809
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
810
+ "meshStandardMaterial",
811
+ {
812
+ map: floorTex,
813
+ roughness: 0.88,
814
+ metalness: 0.02
815
+ }
816
+ )
817
+ ]
818
+ }
819
+ ),
820
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
821
+ PaperBookPageTurn3D,
822
+ {
823
+ pageTurnProgress,
824
+ nextFloorTheme: nextFloorTheme ?? floorTheme
825
+ }
826
+ )
827
+ ] });
828
+ };
829
+ var PaperCloudCutout3D = ({ position, scale = 1, tint = "#FCE7F3", idSuffix = "pink" }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
830
+ PaperCutout3D,
831
+ {
832
+ cacheKey: `paper-cloud-${idSuffix}`,
833
+ cacheDeps: [tint],
834
+ width: 2.6 * scale,
835
+ height: 1.3 * scale,
836
+ pixelWidth: 512,
837
+ pixelHeight: 256,
838
+ whiteBorderPx: 16,
839
+ position,
840
+ anchor: "center",
841
+ thickness: 0.045,
842
+ draw: (ctx) => {
843
+ ctx.fillStyle = tint;
844
+ ctx.strokeStyle = "#F472B6";
845
+ ctx.lineWidth = 6;
846
+ ctx.beginPath();
847
+ ctx.moveTo(90, 195);
848
+ ctx.lineTo(422, 195);
849
+ ctx.bezierCurveTo(468, 195, 472, 130, 420, 122);
850
+ ctx.bezierCurveTo(412, 65, 340, 48, 300, 82);
851
+ ctx.bezierCurveTo(272, 22, 178, 26, 156, 88);
852
+ ctx.bezierCurveTo(108, 74, 62, 112, 76, 152);
853
+ ctx.bezierCurveTo(42, 158, 48, 195, 90, 195);
854
+ ctx.closePath();
855
+ ctx.fill();
856
+ ctx.stroke();
857
+ ctx.fillStyle = "rgba(244, 114, 182, 0.18)";
858
+ ctx.beginPath();
859
+ ctx.ellipse(256, 172, 145, 16, 0, 0, Math.PI * 2);
860
+ ctx.fill();
861
+ }
862
+ }
863
+ );
864
+ var PaperPineTree3D = ({ position, scale = 1 }) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
865
+ PaperCutout3D,
866
+ {
867
+ cacheKey: "paper-pine-tree",
868
+ width: 1.35 * scale,
869
+ height: 2.1 * scale,
870
+ pixelWidth: 256,
871
+ pixelHeight: 384,
872
+ whiteBorderPx: 14,
873
+ position,
874
+ anchor: "bottom",
875
+ thickness: 0.04,
876
+ draw: (ctx) => {
877
+ ctx.fillStyle = "#78350F";
878
+ ctx.fillRect(108, 285, 40, 75);
879
+ const tiers = [
880
+ { yTop: 155, yBot: 295, halfW: 92, color: "#059669" },
881
+ { yTop: 92, yBot: 215, halfW: 76, color: "#10B981" },
882
+ { yTop: 36, yBot: 145, halfW: 56, color: "#34D399" }
883
+ ];
884
+ for (const t of tiers) {
885
+ ctx.fillStyle = t.color;
886
+ ctx.strokeStyle = "#065F46";
887
+ ctx.lineWidth = 5;
888
+ ctx.beginPath();
889
+ ctx.moveTo(128, t.yTop);
890
+ ctx.lineTo(128 + t.halfW, t.yBot);
891
+ ctx.lineTo(128 - t.halfW, t.yBot);
892
+ ctx.closePath();
893
+ ctx.fill();
894
+ ctx.stroke();
895
+ }
896
+ }
897
+ }
898
+ );
899
+ var PaperMountainBackdrop3D = ({ position = [0, 0, -5.2], scale = 1 }) => {
900
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("group", { position, scale, children: [
901
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
902
+ PaperCutout3D,
903
+ {
904
+ cacheKey: "paper-mountain-west",
905
+ width: 4.6,
906
+ height: 3.8,
907
+ pixelWidth: 512,
908
+ pixelHeight: 420,
909
+ whiteBorderPx: 14,
910
+ position: [-3.2, 0, -0.9],
911
+ thickness: 0.05,
912
+ draw: (ctx) => {
913
+ ctx.fillStyle = "#C4B5FD";
914
+ ctx.strokeStyle = "#7C3AED";
915
+ ctx.lineWidth = 6;
916
+ ctx.beginPath();
917
+ ctx.moveTo(256, 36);
918
+ ctx.lineTo(480, 396);
919
+ ctx.lineTo(32, 396);
920
+ ctx.closePath();
921
+ ctx.fill();
922
+ ctx.stroke();
923
+ ctx.fillStyle = "#F5F3FF";
924
+ ctx.beginPath();
925
+ ctx.moveTo(256, 36);
926
+ ctx.lineTo(340, 185);
927
+ ctx.lineTo(276, 155);
928
+ ctx.lineTo(234, 195);
929
+ ctx.lineTo(172, 185);
930
+ ctx.closePath();
931
+ ctx.fill();
932
+ }
933
+ }
934
+ ),
935
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
936
+ PaperCutout3D,
937
+ {
938
+ cacheKey: "paper-mountain-east",
939
+ width: 4.8,
940
+ height: 4,
941
+ pixelWidth: 512,
942
+ pixelHeight: 420,
943
+ whiteBorderPx: 14,
944
+ position: [3.4, 0, -0.8],
945
+ thickness: 0.05,
946
+ draw: (ctx) => {
947
+ ctx.fillStyle = "#A5B4FC";
948
+ ctx.strokeStyle = "#4F46E5";
949
+ ctx.lineWidth = 6;
950
+ ctx.beginPath();
951
+ ctx.moveTo(256, 30);
952
+ ctx.lineTo(484, 396);
953
+ ctx.lineTo(28, 396);
954
+ ctx.closePath();
955
+ ctx.fill();
956
+ ctx.stroke();
957
+ ctx.fillStyle = "#EEF2FF";
958
+ ctx.beginPath();
959
+ ctx.moveTo(256, 30);
960
+ ctx.lineTo(348, 180);
961
+ ctx.lineTo(282, 152);
962
+ ctx.lineTo(222, 188);
963
+ ctx.lineTo(164, 178);
964
+ ctx.closePath();
965
+ ctx.fill();
966
+ }
967
+ }
968
+ ),
969
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
970
+ PaperCutout3D,
971
+ {
972
+ cacheKey: "paper-mountain-center",
973
+ width: 5.4,
974
+ height: 4.8,
975
+ pixelWidth: 560,
976
+ pixelHeight: 500,
977
+ whiteBorderPx: 16,
978
+ position: [0, 0, 0],
979
+ thickness: 0.055,
980
+ draw: (ctx) => {
981
+ ctx.fillStyle = "#60A5FA";
982
+ ctx.strokeStyle = "#1D4ED8";
983
+ ctx.lineWidth = 7;
984
+ ctx.beginPath();
985
+ ctx.moveTo(280, 28);
986
+ ctx.lineTo(528, 476);
987
+ ctx.lineTo(32, 476);
988
+ ctx.closePath();
989
+ ctx.fill();
990
+ ctx.stroke();
991
+ ctx.fillStyle = "#FFFFFF";
992
+ ctx.beginPath();
993
+ ctx.moveTo(280, 28);
994
+ ctx.lineTo(384, 216);
995
+ ctx.lineTo(318, 178);
996
+ ctx.lineTo(280, 224);
997
+ ctx.lineTo(236, 182);
998
+ ctx.lineTo(176, 216);
999
+ ctx.closePath();
1000
+ ctx.fill();
1001
+ }
1002
+ }
1003
+ )
1004
+ ] });
1005
+ };
1006
+
1007
+ // packages/kits/src/paper-diorama-3d/PaperStageLighting3D.tsx
1008
+ var import_react4 = require("react");
1009
+ var import_fiber = require("@react-three/fiber");
1010
+ var THREE3 = __toESM(require("three"), 1);
1011
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1012
+ var PaperCameraRig3D = ({
1013
+ cameraPos,
1014
+ lookAt,
1015
+ fov = 34
1016
+ }) => {
1017
+ const camera = (0, import_fiber.useThree)((state) => state.camera);
1018
+ const [camX, camY, camZ] = cameraPos;
1019
+ const [lookX, lookY, lookZ] = lookAt;
1020
+ (0, import_react4.useLayoutEffect)(() => {
1021
+ camera.position.set(camX, camY, camZ);
1022
+ if (camera instanceof THREE3.PerspectiveCamera) {
1023
+ camera.fov = fov;
1024
+ }
1025
+ camera.lookAt(lookX, lookY, lookZ);
1026
+ camera.updateProjectionMatrix();
1027
+ }, [camera, camX, camY, camZ, lookX, lookY, lookZ, fov]);
1028
+ return null;
1029
+ };
1030
+ var PaperStageLighting3D = ({
1031
+ preset = "daylight",
1032
+ sunPosition
1033
+ }) => {
1034
+ const gl = (0, import_fiber.useThree)((state) => state.gl);
1035
+ (0, import_react4.useLayoutEffect)(() => {
1036
+ gl.shadowMap.enabled = true;
1037
+ gl.shadowMap.type = THREE3.PCFSoftShadowMap;
1038
+ gl.toneMapping = THREE3.ACESFilmicToneMapping;
1039
+ gl.toneMappingExposure = 1.06;
1040
+ }, [gl]);
1041
+ let sunColor = "#FFF5E4";
1042
+ let sunIntensity = 1.95;
1043
+ let ambientIntensity = 0.68;
1044
+ const sunPos = sunPosition ?? [-7.5, 11.5, 8.5];
1045
+ if (preset === "golden-hour") {
1046
+ sunColor = "#FDE68A";
1047
+ sunIntensity = 1.85;
1048
+ ambientIntensity = 0.58;
1049
+ } else if (preset === "indoor-study") {
1050
+ sunColor = "#FEF3C7";
1051
+ sunIntensity = 1.65;
1052
+ ambientIntensity = 0.56;
1053
+ } else if (preset === "spotlight") {
1054
+ sunColor = "#F8FAFC";
1055
+ sunIntensity = 1.35;
1056
+ ambientIntensity = 0.45;
1057
+ }
1058
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1059
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("hemisphereLight", { args: ["#FFFDF9", "#92400E", ambientIntensity] }),
1060
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1061
+ "directionalLight",
1062
+ {
1063
+ position: sunPos,
1064
+ intensity: sunIntensity,
1065
+ color: sunColor,
1066
+ castShadow: true,
1067
+ "shadow-mapSize-width": 2048,
1068
+ "shadow-mapSize-height": 2048,
1069
+ "shadow-camera-near": 1,
1070
+ "shadow-camera-far": 38,
1071
+ "shadow-camera-left": -14,
1072
+ "shadow-camera-right": 14,
1073
+ "shadow-camera-top": 12,
1074
+ "shadow-camera-bottom": -10,
1075
+ "shadow-bias": -5e-4
1076
+ }
1077
+ ),
1078
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1079
+ "directionalLight",
1080
+ {
1081
+ position: [9, 6, -4],
1082
+ intensity: 0.55,
1083
+ color: "#FDE68A"
1084
+ }
1085
+ )
1086
+ ] });
1087
+ };