egaki 0.7.2 → 0.9.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 (63) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/cli/bpm-detect.d.ts +7 -0
  3. package/dist/cli/bpm-detect.d.ts.map +1 -0
  4. package/dist/cli/bpm-detect.js +123 -0
  5. package/dist/cli/cli.d.ts.map +1 -1
  6. package/dist/cli/cli.js +115 -0
  7. package/dist/cli/loudness-detect.d.ts +13 -0
  8. package/dist/cli/loudness-detect.d.ts.map +1 -0
  9. package/dist/cli/loudness-detect.js +96 -0
  10. package/dist/vite/angled-screen-shader.d.ts +45 -0
  11. package/dist/vite/angled-screen-shader.d.ts.map +1 -0
  12. package/dist/vite/angled-screen-shader.js +573 -0
  13. package/dist/vite/angled-screen.d.ts +12 -3
  14. package/dist/vite/angled-screen.d.ts.map +1 -1
  15. package/dist/vite/angled-screen.js +12 -3
  16. package/dist/vite/code-block.d.ts.map +1 -1
  17. package/dist/vite/code-block.js +26 -5
  18. package/dist/vite/layout-editor.js +1 -1
  19. package/dist/vite/mdx-video.d.ts +4 -2
  20. package/dist/vite/mdx-video.d.ts.map +1 -1
  21. package/dist/vite/mdx-video.js +4 -2
  22. package/dist/vite/mdx-video.test.js +1 -79
  23. package/dist/vite/player-page.d.ts.map +1 -1
  24. package/dist/vite/player-page.js +6 -94
  25. package/dist/vite/render-client.d.ts +27 -0
  26. package/dist/vite/render-client.d.ts.map +1 -1
  27. package/dist/vite/render-client.js +47 -51
  28. package/dist/vite/sdk.d.ts.map +1 -1
  29. package/dist/vite/sdk.js +4 -3
  30. package/dist/vite/shader-renderer.d.ts +4 -0
  31. package/dist/vite/shader-renderer.d.ts.map +1 -1
  32. package/dist/vite/shader-renderer.js +3 -3
  33. package/dist/vite/store-hooks.d.ts +2 -0
  34. package/dist/vite/store-hooks.d.ts.map +1 -1
  35. package/dist/vite/store-hooks.js +8 -0
  36. package/dist/vite/store.d.ts +5 -0
  37. package/dist/vite/store.d.ts.map +1 -1
  38. package/dist/vite/store.js +5 -0
  39. package/dist/vite/tweakpane-hook.d.ts +12 -3
  40. package/dist/vite/tweakpane-hook.d.ts.map +1 -1
  41. package/dist/vite/tweakpane-hook.js +128 -20
  42. package/dist/vite/vite-plugin.d.ts +0 -6
  43. package/dist/vite/vite-plugin.d.ts.map +1 -1
  44. package/dist/vite/vite-plugin.js +1 -92
  45. package/package.json +9 -6
  46. package/skills/egaki/SKILL.md +26 -224
  47. package/src/cli/bpm-detect.ts +165 -0
  48. package/src/cli/cli.ts +149 -0
  49. package/src/cli/loudness-detect.ts +129 -0
  50. package/src/vite/angled-screen-shader.tsx +706 -0
  51. package/src/vite/angled-screen.tsx +13 -4
  52. package/src/vite/code-block.tsx +28 -6
  53. package/src/vite/layout-editor.tsx +1 -1
  54. package/src/vite/mdx-video.test.tsx +1 -94
  55. package/src/vite/mdx-video.tsx +4 -1
  56. package/src/vite/player-page.tsx +28 -117
  57. package/src/vite/render-client.ts +52 -51
  58. package/src/vite/sdk.ts +4 -3
  59. package/src/vite/shader-renderer.tsx +3 -3
  60. package/src/vite/store-hooks.ts +11 -0
  61. package/src/vite/store.ts +10 -0
  62. package/src/vite/tweakpane-hook.tsx +173 -28
  63. package/src/vite/vite-plugin.ts +1 -91
@@ -0,0 +1,573 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * AngledScreen — WebGL depth-of-field 3D screen via Remotion HtmlInCanvas.
5
+ *
6
+ * Shader-based successor to BasicAngledScreen (angled-screen.tsx). Children
7
+ * DOM is captured per frame with the HTML-in-canvas API (texElementImage2D)
8
+ * and rendered as a 3D-tilted plane in a WebGL2 fragment shader:
9
+ *
10
+ * screen pixel → ray from CSS-style perspective camera → ray/plane
11
+ * intersection → plane-local UV → sample DOM texture
12
+ *
13
+ * The intersection distance gives true per-pixel depth, which drives:
14
+ * - bokeh blur (poisson-disc, radius grows with distance from focus)
15
+ * - fog toward backgroundColor (like the original Three.js plugin's
16
+ * scene fog, unframer-private/plugin-angled-screen BokehPass setup)
17
+ * - film grain (from the plugin's filmGrainShader, u_time-seeded)
18
+ *
19
+ * Prop names match BasicAngledScreen where semantics carry over:
20
+ * perspective/rotateX/rotateY/rotateZ/translateZ are interpreted exactly
21
+ * like the CSS transform version. Depth of field uses the exact Three.js
22
+ * BokehShader algorithm and the plugin's defaults (aperture 0.5,
23
+ * maxblur 0.12, focus at the plane center): blur grows linearly with the
24
+ * signed distance from the focus plane and saturates at maxBlur, sampled
25
+ * with the 41-tap Martins Upitis ring kernel in screen space.
26
+ *
27
+ * Requires Chrome 149+ with chrome://flags/#canvas-draw-element enabled.
28
+ * Falls back to the CSS BasicAngledScreen when unsupported.
29
+ *
30
+ * EXPORT PATH (DOM-composer fallback), hard-won — don't re-debug:
31
+ * When Remotion's nested HTML-in-canvas probe fails (Chromium changes the
32
+ * API shape between builds), web-renderer composes exports/stills with the
33
+ * DOM composer instead of native capture. Three things must line up for the
34
+ * shader output to survive that path:
35
+ * 1. The scaffold wrapper is visibility:hidden, and Chromium creates no
36
+ * paint records for hidden subtrees — captureElementImage() throws
37
+ * "missing paint record" and HtmlInCanvas SILENTLY skips onInit/onPaint
38
+ * (canRetryMissingPaintRecord swallows it). Fix: the egaki render entry
39
+ * points wrap the composition root in a visibility:visible div
40
+ * (wrapForWebRenderer in render-client.ts), restoring paint records
41
+ * while preserving deeper visibility:hidden semantics (e.g.
42
+ * LayoutTransition's hidden inactive instances). Do NOT force
43
+ * visibility on this component's canvas — that leaks into preview.
44
+ * 2. remotion's HtmlInCanvas has a scoping bug (present through 4.0.495):
45
+ * it registers delayRender() on the GLOBAL window scope but the
46
+ * scaffold's waitForReady() polls its own delayRenderScope — so the
47
+ * renderer never waits for the nested canvas paint. Fix: this component
48
+ * registers its own properly-scoped useDelayRender() handle per frame
49
+ * while isRendering, calls requestPaint(), and releases the handle only
50
+ * after onPaint has drawn and blitted the frame.
51
+ * TODO: remove the scoped-delayRender workaround (and re-evaluate the
52
+ * visibility wrapper in render-client.ts) once this upstream issue is
53
+ * fixed: https://github.com/remotion-dev/remotion/issues/9367
54
+ * 3. The DOM composer cannot read the transferred placeholder canvas, so
55
+ * every painted GL frame is blitted into a plain 2D mirror canvas that
56
+ * the composer picks up like any regular canvas.
57
+ *
58
+ * Coordinate mapping notes (hard-won, don't re-derive):
59
+ * - GL space is y-up, z toward viewer, camera at (0, 0, perspective).
60
+ * - CSS rotateX(+)/rotateY(+) match standard GL Rx/Ry; CSS rotateZ is
61
+ * visually clockwise (y-down), so we negate it for GL.
62
+ * - UNPACK_FLIP_Y_WEBGL=true puts DOM top at v=1, matching y-up plane UVs.
63
+ */
64
+ import { HtmlInCanvas, useCurrentFrame, useDelayRender, useRemotionEnvironment, useVideoConfig, } from 'remotion';
65
+ import { useCallback, useLayoutEffect, useRef } from 'react';
66
+ import { useTweakpane } from "./tweakpane-hook.js";
67
+ import { compileGlShader, linkGlProgram, parseHexColor } from "./shader-renderer.js";
68
+ import { BasicAngledScreen } from "./angled-screen.js";
69
+ const VERTEX_SHADER = `#version 300 es
70
+ precision highp float;
71
+ in vec2 a_position;
72
+ in vec2 a_texCoord;
73
+ out vec2 v_uv;
74
+ void main() {
75
+ v_uv = a_texCoord;
76
+ gl_Position = vec4(a_position, 0.0, 1.0);
77
+ }
78
+ `;
79
+ const FRAGMENT_SHADER = `#version 300 es
80
+ precision highp float;
81
+
82
+ uniform sampler2D u_tex;
83
+ uniform mat3 u_rot; // plane local -> world rotation
84
+ uniform vec2 u_planeSize; // logical composition px
85
+ uniform float u_perspective; // camera z in px
86
+ uniform float u_translateX; // plane center x in px
87
+ uniform float u_translateZ; // plane center z in px
88
+ uniform float u_depthMin; // nearest corner distance to camera
89
+ uniform float u_depthMax; // farthest corner distance to camera
90
+ uniform float u_bokehEnabled;
91
+ uniform float u_aperture; // Three BokehShader aperture (plugin: 0.5)
92
+ uniform float u_maxblur; // Three BokehShader maxblur, screen-UV units (plugin: 0.12)
93
+ uniform float u_focusDist; // focus distance in px along the ray
94
+ uniform float u_aspect; // width / height, for circular bokeh
95
+ uniform float u_fog;
96
+ uniform float u_grain;
97
+ uniform vec4 u_background;
98
+ uniform float u_debug;
99
+ uniform float u_time;
100
+
101
+ in vec2 v_uv;
102
+ out vec4 fragColor;
103
+
104
+ float rand(vec2 co) {
105
+ return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
106
+ }
107
+
108
+ // Three.js BokehShader ring kernel (Martins Upitis lens blur):
109
+ // 16 taps at radius 1.0, 8 at 0.9, 8 at 0.7, 8 at 0.4, plus center = 41.
110
+ const vec2 RING1[16] = vec2[](
111
+ vec2(0.0, 0.4), vec2(0.15, 0.37), vec2(0.29, 0.29), vec2(-0.37, 0.15),
112
+ vec2(0.40, 0.0), vec2(0.37, -0.15), vec2(0.29, -0.29), vec2(-0.15, -0.37),
113
+ vec2(0.0, -0.4), vec2(-0.15, 0.37), vec2(-0.29, 0.29), vec2(0.37, 0.15),
114
+ vec2(-0.4, 0.0), vec2(-0.37, -0.15), vec2(-0.29, -0.29), vec2(0.15, -0.37)
115
+ );
116
+ const vec2 RING9[8] = vec2[](
117
+ vec2(0.15, 0.37), vec2(-0.37, 0.15), vec2(0.37, -0.15), vec2(-0.15, -0.37),
118
+ vec2(-0.15, 0.37), vec2(0.37, 0.15), vec2(-0.37, -0.15), vec2(0.15, -0.37)
119
+ );
120
+ const vec2 RING7[8] = vec2[](
121
+ vec2(0.29, 0.29), vec2(0.40, 0.0), vec2(0.29, -0.29), vec2(0.0, -0.4),
122
+ vec2(-0.29, 0.29), vec2(-0.4, 0.0), vec2(-0.29, -0.29), vec2(0.0, 0.4)
123
+ );
124
+
125
+ // Intersect the camera ray through screen uv suv with the tilted plane.
126
+ // Returns ray distance t, or -1.0 on miss. Outputs plane uv + edge coverage.
127
+ float intersectPlane(vec2 suv, out vec2 uv, out float coverage) {
128
+ vec2 screen = (suv - 0.5) * u_planeSize;
129
+ vec3 C = vec3(0.0, 0.0, u_perspective);
130
+ vec3 dir = normalize(vec3(screen, 0.0) - C);
131
+ vec3 n = u_rot * vec3(0.0, 0.0, 1.0);
132
+ vec3 q0 = vec3(u_translateX, 0.0, u_translateZ);
133
+ float denom = dot(n, dir);
134
+ if (abs(denom) < 1e-6) return -1.0;
135
+ float t = dot(n, q0 - C) / denom;
136
+ if (t <= 0.0) return -1.0;
137
+ vec3 local = transpose(u_rot) * (C + t * dir - q0);
138
+ uv = local.xy / u_planeSize + 0.5;
139
+ vec2 edgePx = (0.5 - abs(uv - 0.5)) * u_planeSize;
140
+ coverage = clamp(min(edgePx.x, edgePx.y) + 0.5, 0.0, 1.0);
141
+ return t;
142
+ }
143
+
144
+ // Full scene color at a screen position: plane composited over background.
145
+ // Screen-space sampling like Three's BokehPass (which blurs the rendered
146
+ // frame), so blur also softens the plane edges into the background.
147
+ vec4 sampleScene(vec2 suv) {
148
+ vec2 uv;
149
+ float coverage;
150
+ float t = intersectPlane(suv, uv, coverage);
151
+ if (t < 0.0 || coverage <= 0.0) return u_background;
152
+ vec4 c = texture(u_tex, uv);
153
+ c = vec4(mix(u_background.rgb, c.rgb, c.a), 1.0);
154
+ return mix(u_background, c, coverage);
155
+ }
156
+
157
+ void main() {
158
+ vec4 bg = u_background;
159
+
160
+ vec2 uv;
161
+ float coverage;
162
+ float t = intersectPlane(v_uv, uv, coverage);
163
+ bool hit = t > 0.0 && coverage > 0.0;
164
+
165
+ // Normalized depth across the visible plane (0 = near, 1 = far) — used
166
+ // for fog and the debug view.
167
+ float depth01 = hit
168
+ ? clamp((t - u_depthMin) / max(u_depthMax - u_depthMin, 1e-3), 0.0, 1.0)
169
+ : 1.0;
170
+
171
+ if (u_debug > 0.5) {
172
+ fragColor = hit ? mix(bg, vec4(vec3(depth01), 1.0), coverage) : bg;
173
+ return;
174
+ }
175
+
176
+ // Three.js BokehShader blur factor, made one-sided: only content BEYOND
177
+ // the focus plane blurs (the far side of the tilted screen). The near side
178
+ // stays tack sharp. Background pixels (no hit) count as far away, so the
179
+ // plane silhouette melts softly where it is out of focus.
180
+ float factor = hit ? max(t - u_focusDist, 0.0) / u_perspective : 1.0;
181
+ vec2 dofblur = vec2(clamp(factor * u_aperture, 0.0, u_maxblur)) * u_bokehEnabled;
182
+
183
+ vec2 aspectcorrect = vec2(1.0, u_aspect);
184
+ vec2 dofblur9 = dofblur * 0.9;
185
+ vec2 dofblur7 = dofblur * 0.7;
186
+ vec2 dofblur4 = dofblur * 0.4;
187
+
188
+ vec4 col = sampleScene(v_uv);
189
+ for (int i = 0; i < 16; i++) {
190
+ col += sampleScene(v_uv + RING1[i] * aspectcorrect * dofblur);
191
+ }
192
+ for (int i = 0; i < 8; i++) {
193
+ col += sampleScene(v_uv + RING9[i] * aspectcorrect * dofblur9);
194
+ }
195
+ for (int i = 0; i < 8; i++) {
196
+ col += sampleScene(v_uv + RING7[i] * aspectcorrect * dofblur7);
197
+ }
198
+ for (int i = 0; i < 8; i++) {
199
+ col += sampleScene(v_uv + RING7[i] * aspectcorrect * dofblur4);
200
+ }
201
+ col /= 41.0;
202
+
203
+ // Fog toward background with depth (plugin's THREE.Fog equivalent)
204
+ col.rgb = mix(col.rgb, bg.rgb, u_fog * depth01 * (hit ? 1.0 : 0.0));
205
+
206
+ // Film grain (plugin's filmGrainShader)
207
+ col.rgb += (rand(v_uv + fract(u_time)) - 0.5) * u_grain;
208
+ col.a = 1.0;
209
+
210
+ fragColor = col;
211
+ }
212
+ `;
213
+ const UNIFORM_NAMES = [
214
+ 'u_tex',
215
+ 'u_rot',
216
+ 'u_planeSize',
217
+ 'u_perspective',
218
+ 'u_translateX',
219
+ 'u_translateZ',
220
+ 'u_depthMin',
221
+ 'u_depthMax',
222
+ 'u_bokehEnabled',
223
+ 'u_aperture',
224
+ 'u_maxblur',
225
+ 'u_focusDist',
226
+ 'u_aspect',
227
+ 'u_fog',
228
+ 'u_grain',
229
+ 'u_background',
230
+ 'u_debug',
231
+ 'u_time',
232
+ ];
233
+ /**
234
+ * Build the CSS-order rotation matrix M = Rx * Ry * Rz(-z) in GL coords
235
+ * (y up, z toward viewer). Returns row-major 3x3 as number[][].
236
+ */
237
+ function rotationMatrix(rxDeg, ryDeg, rzDeg) {
238
+ const rx = (rxDeg * Math.PI) / 180;
239
+ const ry = (ryDeg * Math.PI) / 180;
240
+ const rz = (-rzDeg * Math.PI) / 180;
241
+ const cx = Math.cos(rx);
242
+ const sx = Math.sin(rx);
243
+ const cy = Math.cos(ry);
244
+ const sy = Math.sin(ry);
245
+ const cz = Math.cos(rz);
246
+ const sz = Math.sin(rz);
247
+ const Rx = [
248
+ [1, 0, 0],
249
+ [0, cx, -sx],
250
+ [0, sx, cx],
251
+ ];
252
+ const Ry = [
253
+ [cy, 0, sy],
254
+ [0, 1, 0],
255
+ [-sy, 0, cy],
256
+ ];
257
+ const Rz = [
258
+ [cz, -sz, 0],
259
+ [sz, cz, 0],
260
+ [0, 0, 1],
261
+ ];
262
+ const mul = (a, b) => a.map((row, i) => row.map((_, j) => a[i][0] * b[0][j] + a[i][1] * b[1][j] + a[i][2] * b[2][j]));
263
+ return mul(mul(Rx, Ry), Rz);
264
+ }
265
+ export function AngledScreen(props) {
266
+ const frame = useCurrentFrame();
267
+ const { width: compW, height: compH, fps } = useVideoConfig();
268
+ const glRef = useRef(null);
269
+ // Mirror canvas: the web-renderer's DOM composer (used for exports and SDK
270
+ // screenshots whenever nested HTML-in-canvas capture is unavailable)
271
+ // cannot read the HtmlInCanvas offscreen and paints the raw children
272
+ // instead. Every painted GL frame is blitted into this plain 2D canvas
273
+ // overlaid on top; the DOM composer draws it like any regular canvas.
274
+ // It is always mounted (not only during export) because sdk.screenshot()
275
+ // captures the live tree without ExportContext.
276
+ const mirrorRef = useRef(null);
277
+ const mirrorLoggedRef = useRef(false);
278
+ // Export sync: while web-renderer renders (isRendering), hold a scoped
279
+ // delayRender handle per frame and force a paint on the layout canvas.
280
+ // Released in onPaint after the GL frame is blitted to the mirror, so
281
+ // waitForReady() blocks until the shader output for THIS frame exists.
282
+ // Needed because remotion's own "waiting for first paint" delayRender
283
+ // registers on the window scope, which the export scaffold ignores.
284
+ // TODO: remove once fixed upstream:
285
+ // https://github.com/remotion-dev/remotion/issues/9367
286
+ const { isRendering } = useRemotionEnvironment();
287
+ const { delayRender, continueRender } = useDelayRender();
288
+ const continueRenderRef = useRef(continueRender);
289
+ continueRenderRef.current = continueRender;
290
+ const layoutCanvasRef = useRef(null);
291
+ const pendingPaintHandleRef = useRef(null);
292
+ const tp = useTweakpane('AngledScreen', {
293
+ perspective: { value: props.perspective ?? 1200, min: 100, max: 3000, step: 10 },
294
+ rotateX: { value: props.rotateX ?? 8, min: -90, max: 90, step: 0.5 },
295
+ rotateY: { value: props.rotateY ?? -12, min: -90, max: 90, step: 0.5 },
296
+ rotateZ: { value: props.rotateZ ?? 0, min: -180, max: 180, step: 0.5 },
297
+ translateX: { value: props.translateX ?? 0, min: -1000, max: 1000, step: 1 },
298
+ translateZ: { value: props.translateZ ?? 0, min: -500, max: 500, step: 1 },
299
+ bokeh: props.bokeh ?? true,
300
+ aperture: { value: props.aperture ?? 0.5, min: 0, max: 2, step: 0.01 },
301
+ maxBlur: { value: props.maxBlur ?? 0.12, min: 0, max: 0.3, step: 0.005 },
302
+ // 0 = auto: focus tracks the nearest visible point of the plane, so only
303
+ // the far side blurs, progressively. Any other value = fraction of
304
+ // perspective, like Three's focus uniform.
305
+ focus: {
306
+ value: props.focus ?? 0,
307
+ min: 0,
308
+ max: 2,
309
+ step: 0.01,
310
+ },
311
+ fog: { value: props.fog ?? 0.35, min: 0, max: 1, step: 0.01 },
312
+ grainIntensity: { value: props.grainIntensity ?? 0.02, min: 0, max: 0.2, step: 0.005 },
313
+ backgroundColor: props.backgroundColor ?? '#000000',
314
+ debug: props.debug ?? false,
315
+ });
316
+ const { perspective, rotateX, rotateY, rotateZ, translateX, translateZ } = tp;
317
+ const { aperture, maxBlur, focus, fog, grainIntensity } = tp;
318
+ const { bokeh, debug, backgroundColor } = tp;
319
+ const time = frame / fps;
320
+ const onInit = useCallback(({ canvas }) => {
321
+ const gl = canvas.getContext('webgl2', {
322
+ alpha: true,
323
+ premultipliedAlpha: true,
324
+ antialias: false,
325
+ // Required so the mirror canvas (export path) can drawImage() the GL
326
+ // buffer after the draw call instead of getting a cleared buffer.
327
+ preserveDrawingBuffer: true,
328
+ });
329
+ if (!gl) {
330
+ throw new Error('[AngledScreen] WebGL2 unavailable');
331
+ }
332
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
333
+ const vs = compileGlShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
334
+ const fs = compileGlShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
335
+ const program = linkGlProgram(gl, vs, fs);
336
+ gl.deleteShader(vs);
337
+ gl.deleteShader(fs);
338
+ const texture = gl.createTexture();
339
+ gl.bindTexture(gl.TEXTURE_2D, texture);
340
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
341
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
342
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
343
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
344
+ // Fullscreen quad: interleaved position + uv, 6 vertices
345
+ const buffer = gl.createBuffer();
346
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
347
+ // prettier-ignore
348
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
349
+ -1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1,
350
+ -1, 1, 0, 1, 1, -1, 1, 0, 1, 1, 1, 1,
351
+ ]), gl.STATIC_DRAW);
352
+ const vao = gl.createVertexArray();
353
+ gl.bindVertexArray(vao);
354
+ const posLoc = gl.getAttribLocation(program, 'a_position');
355
+ const uvLoc = gl.getAttribLocation(program, 'a_texCoord');
356
+ gl.enableVertexAttribArray(posLoc);
357
+ gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 16, 0);
358
+ gl.enableVertexAttribArray(uvLoc);
359
+ gl.vertexAttribPointer(uvLoc, 2, gl.FLOAT, false, 16, 8);
360
+ const locs = {};
361
+ for (const name of UNIFORM_NAMES) {
362
+ locs[name] = gl.getUniformLocation(program, name);
363
+ }
364
+ gl.useProgram(program);
365
+ gl.bindVertexArray(vao);
366
+ glRef.current = { gl, program, texture, locs, canvas };
367
+ return () => {
368
+ gl.deleteProgram(program);
369
+ gl.deleteTexture(texture);
370
+ gl.deleteVertexArray(vao);
371
+ gl.deleteBuffer(buffer);
372
+ glRef.current = null;
373
+ };
374
+ }, []);
375
+ const onPaint = useCallback(({ elementImage }) => {
376
+ const state = glRef.current;
377
+ if (!state)
378
+ return;
379
+ const { gl, locs } = state;
380
+ gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
381
+ gl.activeTexture(gl.TEXTURE0);
382
+ gl.bindTexture(gl.TEXTURE_2D, state.texture);
383
+ // The HTML-in-canvas API changed shape between Chromium builds:
384
+ // Chrome 149-151: texElementImage2D(target, level, internalformat, format, type, element)
385
+ // Chrome 152+: texElementImage2D(target, internalformat, element)
386
+ // where internalformat must be sized (RGBA8, SRGB8_ALPHA8, RGBA16F, RGBA32F)
387
+ // Detect via Function.length (3 = new signature).
388
+ if (gl.texElementImage2D.length <= 3) {
389
+ ;
390
+ gl.texElementImage2D(gl.TEXTURE_2D, gl.RGBA8, elementImage);
391
+ }
392
+ else {
393
+ gl.texElementImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, elementImage);
394
+ }
395
+ // CPU-side scene setup: rotation matrix + VISIBLE depth statistics.
396
+ // Depth is sampled on a 7x7 grid of rays across the screen and
397
+ // summarized with percentiles. Percentiles are area-weighted, which
398
+ // matters: rays toward the plane's vanishing direction produce huge t
399
+ // values, and using the raw corner min/max would compress the blur
400
+ // ramp so much that most of the image reads sharp. Quantiles keep the
401
+ // ramp perceptually spread across the screen.
402
+ const M = rotationMatrix(rotateX, rotateY, rotateZ);
403
+ const hw = compW / 2;
404
+ const hh = compH / 2;
405
+ // Plane normal (third column of M)
406
+ const nx = M[0][2];
407
+ const ny = M[1][2];
408
+ const nz = M[2][2];
409
+ const depths = [];
410
+ for (let gy = 0; gy < 7; gy++) {
411
+ for (let gx = 0; gx < 7; gx++) {
412
+ // Ray from camera C=(0,0,perspective) through screen point (sx,sy,0)
413
+ const sx = ((gx / 6) * 2 - 1) * hw;
414
+ const sy = ((gy / 6) * 2 - 1) * hh;
415
+ const len = Math.hypot(sx, sy, perspective);
416
+ const denom = (nx * sx + ny * sy - nz * perspective) / len;
417
+ if (Math.abs(denom) < 1e-6)
418
+ continue;
419
+ // t = dot(n, q0 - C) / dot(n, dir), q0 = (translateX,0,translateZ)
420
+ const t = (nx * translateX + nz * (translateZ - perspective)) / denom;
421
+ if (t > 0 && Number.isFinite(t))
422
+ depths.push(t);
423
+ }
424
+ }
425
+ depths.sort((a, b) => a - b);
426
+ const quantile = (q) => depths[Math.min(depths.length - 1, Math.round(q * (depths.length - 1)))] ?? perspective;
427
+ const depthMin = depths.length > 0 ? depths[0] : perspective;
428
+ const depthMax = depths.length > 0 ? quantile(0.95) : perspective + 1;
429
+ if (locs.u_tex)
430
+ gl.uniform1i(locs.u_tex, 0);
431
+ if (locs.u_rot) {
432
+ // GLSL mat3 is column-major; M is row-major → transpose on flatten
433
+ // prettier-ignore
434
+ gl.uniformMatrix3fv(locs.u_rot, false, [
435
+ M[0][0], M[1][0], M[2][0],
436
+ M[0][1], M[1][1], M[2][1],
437
+ M[0][2], M[1][2], M[2][2],
438
+ ]);
439
+ }
440
+ if (locs.u_planeSize)
441
+ gl.uniform2f(locs.u_planeSize, compW, compH);
442
+ if (locs.u_perspective)
443
+ gl.uniform1f(locs.u_perspective, perspective);
444
+ if (locs.u_translateX)
445
+ gl.uniform1f(locs.u_translateX, translateX);
446
+ if (locs.u_translateZ)
447
+ gl.uniform1f(locs.u_translateZ, translateZ);
448
+ if (locs.u_depthMin)
449
+ gl.uniform1f(locs.u_depthMin, depthMin);
450
+ if (locs.u_depthMax)
451
+ gl.uniform1f(locs.u_depthMax, depthMax);
452
+ // focus=0 (auto): the focus plane sits at the 40th depth percentile,
453
+ // so roughly the near half of the image reads sharp and blur ramps
454
+ // progressively from there toward the far edge. The effective aperture
455
+ // is auto-scaled so blur reaches maxBlur at the 95th percentile
456
+ // regardless of scene scale (aperture prop acts as a multiplier
457
+ // relative to its 0.5 default: higher = saturates earlier).
458
+ const focusDist = focus > 0 ? focus * perspective : quantile(0.4);
459
+ const apertureEff = focus > 0
460
+ ? aperture
461
+ : (aperture / 0.5) * ((maxBlur * perspective) / Math.max(depthMax - focusDist, 1));
462
+ if (locs.u_bokehEnabled)
463
+ gl.uniform1f(locs.u_bokehEnabled, bokeh ? 1 : 0);
464
+ if (locs.u_aperture)
465
+ gl.uniform1f(locs.u_aperture, apertureEff);
466
+ if (locs.u_maxblur)
467
+ gl.uniform1f(locs.u_maxblur, maxBlur);
468
+ if (locs.u_focusDist)
469
+ gl.uniform1f(locs.u_focusDist, focusDist);
470
+ if (locs.u_aspect)
471
+ gl.uniform1f(locs.u_aspect, compW / compH);
472
+ if (locs.u_fog)
473
+ gl.uniform1f(locs.u_fog, fog);
474
+ if (locs.u_grain)
475
+ gl.uniform1f(locs.u_grain, grainIntensity);
476
+ if (locs.u_background)
477
+ gl.uniform4fv(locs.u_background, parseHexColor(backgroundColor));
478
+ if (locs.u_debug)
479
+ gl.uniform1f(locs.u_debug, debug ? 1 : 0);
480
+ if (locs.u_time)
481
+ gl.uniform1f(locs.u_time, time);
482
+ gl.drawArrays(gl.TRIANGLES, 0, 6);
483
+ // Export path: mirror the GL frame into the overlay 2D canvas so the
484
+ // DOM composer (used when nested HTML-in-canvas capture is
485
+ // unavailable) picks up the shader output instead of the raw children.
486
+ const mirror = mirrorRef.current;
487
+ if (mirror) {
488
+ if (mirror.width !== state.canvas.width || mirror.height !== state.canvas.height) {
489
+ mirror.width = state.canvas.width;
490
+ mirror.height = state.canvas.height;
491
+ }
492
+ const ctx2d = mirror.getContext('2d');
493
+ if (ctx2d) {
494
+ ctx2d.drawImage(state.canvas, 0, 0);
495
+ if (!mirrorLoggedRef.current) {
496
+ mirrorLoggedRef.current = true;
497
+ console.info('[egaki] AngledScreen: mirror canvas active — GL frames are blitted to a 2D canvas so DOM-composer captures (export/screenshot) include the shader output.');
498
+ }
499
+ }
500
+ }
501
+ // Release the export-sync handle now that this frame's shader output
502
+ // (including the mirror blit) is complete.
503
+ const pending = pendingPaintHandleRef.current;
504
+ if (pending !== null) {
505
+ pendingPaintHandleRef.current = null;
506
+ continueRenderRef.current(pending);
507
+ }
508
+ }, [
509
+ compW, compH, perspective, rotateX, rotateY, rotateZ, translateX, translateZ,
510
+ bokeh, aperture, maxBlur, focus, fog, grainIntensity,
511
+ backgroundColor, debug, time,
512
+ ]);
513
+ const supported = typeof document !== 'undefined' && HtmlInCanvas.isSupported();
514
+ // Per-frame export sync (see comment on pendingPaintHandleRef). Layout
515
+ // effect so the handle is registered synchronously inside the renderer's
516
+ // flushSync time update, before waitForReady() first checks the scope.
517
+ // Gated on `supported`: the CSS BasicAngledScreen fallback never paints,
518
+ // so registering a handle there would hang the export until timeout.
519
+ // Also gated on computed visibility: instances under visibility:hidden
520
+ // ancestors (LayoutTransition ghosts and inactive timed instances) get no
521
+ // Chromium paint records, so their HtmlInCanvas never fires paint and a
522
+ // registered handle would hang the export. Premounted sections are fine —
523
+ // remotion premount hides via opacity:0, which keeps paint records.
524
+ useLayoutEffect(() => {
525
+ if (!isRendering || !supported)
526
+ return;
527
+ const canvas = layoutCanvasRef.current;
528
+ if (!canvas || getComputedStyle(canvas).visibility === 'hidden')
529
+ return;
530
+ const handle = delayRender('AngledScreen: waiting for shader paint');
531
+ pendingPaintHandleRef.current = handle;
532
+ layoutCanvasRef.current?.requestPaint?.();
533
+ return () => {
534
+ if (pendingPaintHandleRef.current === handle) {
535
+ pendingPaintHandleRef.current = null;
536
+ }
537
+ continueRenderRef.current(handle);
538
+ };
539
+ }, [frame, isRendering, supported, delayRender]);
540
+ if (!supported) {
541
+ if (typeof console !== 'undefined' && !globalThis.__egakiAngledScreenFallbackWarned) {
542
+ ;
543
+ globalThis.__egakiAngledScreenFallbackWarned = true;
544
+ console.warn('[egaki] AngledScreen: HTML-in-canvas is not supported in this browser — ' +
545
+ 'falling back to the CSS BasicAngledScreen (no true depth-of-field). ' +
546
+ 'Use Chrome 149+ and enable chrome://flags/#canvas-draw-element for the WebGL version.');
547
+ }
548
+ return (_jsx(BasicAngledScreen, { perspective: perspective, rotateX: rotateX, rotateY: rotateY, rotateZ: rotateZ, translateZ: translateZ, bokeh: bokeh, bokehBlur: maxBlur * compW * 0.4, bokehOffset: 0.5, backgroundColor: backgroundColor, width: props.width, height: props.height, debug: debug, style: {
549
+ // BasicAngledScreen has no translateX — approximate with a CSS shift
550
+ transform: translateX !== 0 ? `translateX(${translateX}px)` : undefined,
551
+ ...props.style,
552
+ }, children: props.children }));
553
+ }
554
+ return (_jsxs("div", { style: { position: 'relative', width: '100%', height: '100%', overflow: 'hidden', ...props.style }, children: [_jsx(HtmlInCanvas, { ref: layoutCanvasRef, width: compW, height: compH, pixelDensity: Math.min(typeof window !== 'undefined' ? window.devicePixelRatio || 1 : 1, 2), onInit: onInit, onPaint: onPaint, children: _jsx("div", { style: {
555
+ position: 'absolute',
556
+ inset: 0,
557
+ display: 'flex',
558
+ alignItems: 'center',
559
+ justifyContent: 'center',
560
+ }, children: _jsx("div", { style: {
561
+ width: typeof props.width === 'number' ? `${props.width}px` : (props.width ?? '80%'),
562
+ height: typeof props.height === 'number' ? `${props.height}px` : (props.height ?? 'auto'),
563
+ position: 'relative',
564
+ borderRadius: '12px',
565
+ overflow: 'hidden',
566
+ }, children: props.children }) }) }), _jsx("canvas", { ref: mirrorRef, style: {
567
+ position: 'absolute',
568
+ inset: 0,
569
+ width: '100%',
570
+ height: '100%',
571
+ pointerEvents: 'none',
572
+ } })] }));
573
+ }
@@ -1,5 +1,9 @@
1
1
  /**
2
- * AngledScreen — CSS 3D perspective wrapper with fake bokeh depth-of-field.
2
+ * BasicAngledScreen — CSS 3D perspective wrapper with fake bokeh depth-of-field.
3
+ *
4
+ * The shader-based version (true depth-of-field via WebGL) lives in
5
+ * angled-screen-shader.tsx and is exported as AngledScreen. This CSS version
6
+ * is kept as a lightweight fallback that works without HTML-in-canvas support.
3
7
  *
4
8
  * Wraps any children (images, videos, divs) in a 3D-transformed plane using
5
9
  * CSS `perspective` + `transform: rotateX/Y/Z`. Simulates depth-of-field
@@ -18,7 +22,7 @@
18
22
  * Set `debug` to visualize the mask gradient as green (sharp) / red (blur).
19
23
  */
20
24
  import { type CSSProperties, type ReactNode } from 'react';
21
- export interface AngledScreenProps {
25
+ export interface BasicAngledScreenProps {
22
26
  children: ReactNode;
23
27
  /** CSS perspective distance in px. Smaller = more dramatic. Default 1200. */
24
28
  perspective?: number;
@@ -53,5 +57,10 @@ export interface AngledScreenProps {
53
57
  /** Optional inline style on the outer container. */
54
58
  style?: CSSProperties;
55
59
  }
56
- export declare function AngledScreen(props: AngledScreenProps): import("react").JSX.Element;
60
+ /**
61
+ * @deprecated Use `AngledScreen` (angled-screen-shader.tsx) instead — the
62
+ * WebGL version with true depth-of-field. This CSS version only remains as
63
+ * the automatic fallback for browsers without HTML-in-canvas support.
64
+ */
65
+ export declare function BasicAngledScreen(props: BasicAngledScreenProps): import("react").JSX.Element;
57
66
  //# sourceMappingURL=angled-screen.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"angled-screen.d.ts","sourceRoot":"","sources":["../../src/vite/angled-screen.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG1D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,SAAS,CAAA;IAGnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;+EAC2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gFAAgF;IAChF,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IACpD;4EACwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAExB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf,oDAAoD;IACpD,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAwBD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,+BAwHpD"}
1
+ {"version":3,"file":"angled-screen.d.ts","sourceRoot":"","sources":["../../src/vite/angled-screen.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAG1D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,SAAS,CAAA;IAGnB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;+EAC2E;IAC3E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,2CAA2C;IAC3C,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gFAAgF;IAChF,cAAc,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAA;IACpD;4EACwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAA;IAGpB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAA;IAGxB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAExB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAA;IAEf,oDAAoD;IACpD,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAwBD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,+BAwH9D"}
@@ -1,7 +1,11 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  /**
4
- * AngledScreen — CSS 3D perspective wrapper with fake bokeh depth-of-field.
4
+ * BasicAngledScreen — CSS 3D perspective wrapper with fake bokeh depth-of-field.
5
+ *
6
+ * The shader-based version (true depth-of-field via WebGL) lives in
7
+ * angled-screen-shader.tsx and is exported as AngledScreen. This CSS version
8
+ * is kept as a lightweight fallback that works without HTML-in-canvas support.
5
9
  *
6
10
  * Wraps any children (images, videos, divs) in a 3D-transformed plane using
7
11
  * CSS `perspective` + `transform: rotateX/Y/Z`. Simulates depth-of-field
@@ -41,9 +45,14 @@ function autoDirection(rotateX, rotateY) {
41
45
  }
42
46
  return rotateX > 0 ? 'bottom' : 'top';
43
47
  }
44
- export function AngledScreen(props) {
48
+ /**
49
+ * @deprecated Use `AngledScreen` (angled-screen-shader.tsx) instead — the
50
+ * WebGL version with true depth-of-field. This CSS version only remains as
51
+ * the automatic fallback for browsers without HTML-in-canvas support.
52
+ */
53
+ export function BasicAngledScreen(props) {
45
54
  const { children, transformOrigin = '50% 50%', bokehDirection, backgroundColor = '#000000', width = '80%', height = 'auto', style, } = props;
46
- const tp = useTweakpane('AngledScreen', {
55
+ const tp = useTweakpane('BasicAngledScreen', {
47
56
  perspective: { value: props.perspective ?? 1200, min: 100, max: 3000, step: 10 },
48
57
  rotateX: { value: props.rotateX ?? 8, min: -90, max: 90, step: 0.5 },
49
58
  rotateY: { value: props.rotateY ?? -12, min: -90, max: 90, step: 0.5 },
@@ -1 +1 @@
1
- {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../src/vite/code-block.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"code-block.d.ts","sourceRoot":"","sources":["../../src/vite/code-block.tsx"],"names":[],"mappings":"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"}