@editframe/create 0.44.0 → 0.45.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 (98) hide show
  1. package/dist/index.js +16 -28
  2. package/dist/index.js.map +1 -1
  3. package/dist/skills/editframe-brand-video-generator/README.md +155 -0
  4. package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
  5. package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
  6. package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
  7. package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
  8. package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
  9. package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
  10. package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
  11. package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
  12. package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
  13. package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
  14. package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
  15. package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
  16. package/dist/skills/editframe-composition/SKILL.md +169 -0
  17. package/dist/skills/editframe-composition/references/audio.md +483 -0
  18. package/dist/skills/editframe-composition/references/captions.md +844 -0
  19. package/dist/skills/editframe-composition/references/composition-model.md +73 -0
  20. package/dist/skills/editframe-composition/references/configuration.md +403 -0
  21. package/dist/skills/editframe-composition/references/css-parts.md +105 -0
  22. package/dist/skills/editframe-composition/references/css-variables.md +640 -0
  23. package/dist/skills/editframe-composition/references/entry-points.md +810 -0
  24. package/dist/skills/editframe-composition/references/events.md +499 -0
  25. package/dist/skills/editframe-composition/references/getting-started.md +259 -0
  26. package/dist/skills/editframe-composition/references/hooks.md +234 -0
  27. package/dist/skills/editframe-composition/references/image.md +241 -0
  28. package/dist/skills/editframe-composition/references/r3f.md +580 -0
  29. package/dist/skills/editframe-composition/references/render-api.md +484 -0
  30. package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
  31. package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
  32. package/dist/skills/editframe-composition/references/scripting.md +606 -0
  33. package/dist/skills/editframe-composition/references/sequencing.md +116 -0
  34. package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
  35. package/dist/skills/editframe-composition/references/surface.md +329 -0
  36. package/dist/skills/editframe-composition/references/text.md +627 -0
  37. package/dist/skills/editframe-composition/references/time-model.md +99 -0
  38. package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
  39. package/dist/skills/editframe-composition/references/timegroup.md +457 -0
  40. package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
  41. package/dist/skills/editframe-composition/references/transcription.md +47 -0
  42. package/dist/skills/editframe-composition/references/transitions.md +608 -0
  43. package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
  44. package/dist/skills/editframe-composition/references/video.md +506 -0
  45. package/dist/skills/editframe-composition/references/waveform.md +327 -0
  46. package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
  47. package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
  48. package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
  49. package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
  50. package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
  51. package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
  52. package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
  53. package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
  54. package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
  55. package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
  56. package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
  57. package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
  58. package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
  59. package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
  60. package/dist/skills/editframe-editor-gui/references/play.md +370 -0
  61. package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
  62. package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
  63. package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
  64. package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
  65. package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
  66. package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
  67. package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
  68. package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
  69. package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
  70. package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
  71. package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
  72. package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
  73. package/dist/skills/editframe-motion-design/SKILL.md +101 -0
  74. package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
  75. package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
  76. package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
  77. package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
  78. package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
  79. package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
  80. package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
  81. package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
  82. package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
  83. package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
  84. package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
  85. package/dist/skills/editframe-webhooks/SKILL.md +126 -0
  86. package/dist/skills/editframe-webhooks/references/events.md +382 -0
  87. package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
  88. package/dist/skills/editframe-webhooks/references/security.md +418 -0
  89. package/dist/skills/editframe-webhooks/references/testing.md +409 -0
  90. package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
  91. package/dist/templates/html/AGENTS.md +13 -0
  92. package/dist/templates/react/AGENTS.md +13 -0
  93. package/dist/utils.js +15 -16
  94. package/dist/utils.js.map +1 -1
  95. package/package.json +1 -1
  96. package/tsdown.config.ts +4 -0
  97. package/dist/detectAgent.js +0 -89
  98. package/dist/detectAgent.js.map +0 -1
@@ -0,0 +1,580 @@
1
+ ---
2
+ title: React Three Fiber Integration
3
+ description: Integrate React Three Fiber 3D scenes into Editframe compositions with frame-accurate scrubbing and video export support.
4
+ type: reference
5
+ nav:
6
+ parent: "Advanced"
7
+ priority: 20
8
+ api:
9
+ components:
10
+ - name: OffscreenCompositionCanvas
11
+ description: R3F canvas that renders in a web worker via OffscreenCanvas
12
+ props:
13
+ - name: worker
14
+ type: Worker
15
+ required: true
16
+ description: Web worker that will handle R3F rendering
17
+ - name: fallback
18
+ type: React.ReactNode
19
+ description: Fallback content for browsers without OffscreenCanvas support
20
+ - name: containerStyle
21
+ type: React.CSSProperties
22
+ description: Extra styles for the container div
23
+ - name: containerClassName
24
+ type: string
25
+ description: Extra className for the container div
26
+ - name: canvasProps
27
+ type: CanvasProps
28
+ description: Canvas props to forward to R3F Canvas (shadows, dpr, gl, camera, scene, etc.)
29
+ - name: CompositionCanvas
30
+ description: R3F canvas that renders on the main thread with timeline synchronization
31
+ props:
32
+ - name: children
33
+ type: React.ReactNode
34
+ required: true
35
+ description: R3F scene content
36
+ - name: containerStyle
37
+ type: React.CSSProperties
38
+ description: Extra styles for the container div
39
+ - name: containerClassName
40
+ type: string
41
+ description: Extra className for the container div
42
+ - name: gl
43
+ type: object
44
+ description: WebGL renderer options (automatically includes preserveDrawingBuffer)
45
+ hooks:
46
+ - name: useCompositionTime
47
+ signature: "useCompositionTime(): { timeMs: number; durationMs: number }"
48
+ description: Hook to read current composition time inside an R3F scene
49
+ returns: "{ timeMs, durationMs }"
50
+ functions:
51
+ - name: renderOffscreen
52
+ signature: "renderOffscreen(children: React.ReactNode): void"
53
+ description: Worker-side entry point for offscreen R3F rendering
54
+ returns: void
55
+ react:
56
+ generate: true
57
+ componentName: "React Three Fiber Integration"
58
+ importPath: "@editframe/react/r3f"
59
+ nav:
60
+ parent: "Advanced / 3D Integration"
61
+ priority: 80
62
+ ---
63
+
64
+ # React Three Fiber Integration
65
+
66
+ <!-- html-only -->
67
+ Editframe provides first-class integration with React Three Fiber (R3F) for rendering 3D scenes in video compositions. Import from `@editframe/react/r3f` to access components and utilities for synchronizing Three.js animations with your timeline.
68
+ <!-- /html-only -->
69
+ <!-- react-only -->
70
+ Editframe provides first-class integration with React Three Fiber (R3F) for rendering 3D scenes in video compositions.
71
+ <!-- /react-only -->
72
+
73
+ ## Import
74
+
75
+ ```tsx
76
+ import {
77
+ CompositionCanvas,
78
+ OffscreenCompositionCanvas,
79
+ useCompositionTime
80
+ } from "@editframe/react/r3f";
81
+ ```
82
+
83
+ ## CompositionCanvas
84
+
85
+ <!-- html-only -->
86
+ Renders a React Three Fiber scene on the main thread with automatic timeline synchronization.
87
+ <!-- /html-only -->
88
+ <!-- react-only -->
89
+ Main-thread R3F canvas that automatically synchronizes with Editframe's timeline.
90
+ <!-- /react-only -->
91
+
92
+ ### Basic Usage
93
+
94
+ ```tsx
95
+ import { Timegroup } from "@editframe/react";
96
+ import { CompositionCanvas, useCompositionTime } from "@editframe/react/r3f";
97
+ import { Box } from "@react-three/drei";
98
+
99
+ function RotatingBox() {
100
+ const { timeMs } = useCompositionTime();
101
+ const rotation = (timeMs / 1000) * Math.PI * 2; // Full rotation per second
102
+
103
+ return (
104
+ <Box rotation={[0, rotation, 0]}>
105
+ <meshStandardMaterial color="orange" />
106
+ </Box>
107
+ );
108
+ }
109
+
110
+ export const Video = () => {
111
+ return (
112
+ <Timegroup mode="fixed" duration="5s" className="w-[1920px] h-[1080px]">
113
+ <CompositionCanvas shadows>
114
+ <ambientLight intensity={0.5} />
115
+ <pointLight position={[10, 10, 10]} />
116
+ <RotatingBox />
117
+ </CompositionCanvas>
118
+ </Timegroup>
119
+ );
120
+ };
121
+ ```
122
+
123
+ ### Features
124
+
125
+ - **Automatic Time Sync:** Integrates with `ef-timegroup`'s `addFrameTask` to synchronize 3D animations with your timeline
126
+ - **Deterministic Rendering:** Uses `frameloop="demand"` for frame-by-frame rendering during video export
127
+ - **WebGL Sync:** Calls `gl.finish()` after each frame to ensure all GPU commands complete before capture
128
+ - **Preserves Drawing Buffer:** Automatically sets `preserveDrawingBuffer: true` for video export
129
+
130
+ <!-- react-only -->
131
+ ### Timeline Synchronization
132
+
133
+ `CompositionCanvas` automatically:
134
+ - Registers with parent `<Timegroup>` via `addFrameTask`
135
+ - Updates 3D scene on every frame
136
+ - Provides current time via `useCompositionTime()` hook
137
+ - Ensures deterministic frame-by-frame rendering
138
+ <!-- /react-only -->
139
+
140
+ ### useCompositionTime Hook
141
+
142
+ Access the current composition time inside your R3F scene:
143
+
144
+ ```tsx
145
+ function AnimatedSphere() {
146
+ const { timeMs, durationMs } = useCompositionTime();
147
+ const progress = timeMs / durationMs; // 0 to 1
148
+ const scale = 1 + Math.sin(progress * Math.PI * 2) * 0.5;
149
+
150
+ return (
151
+ <mesh scale={[scale, scale, scale]}>
152
+ <sphereGeometry args={[1, 32, 32]} />
153
+ <meshStandardMaterial color="hotpink" />
154
+ </mesh>
155
+ );
156
+ }
157
+ ```
158
+
159
+ <!-- react-only -->
160
+ **Returns:**
161
+ - `timeMs` - Current time in milliseconds (relative to this timegroup)
162
+ - `durationMs` - Total duration in milliseconds
163
+ <!-- /react-only -->
164
+
165
+ ### Custom WebGL Options
166
+
167
+ ```tsx
168
+ <CompositionCanvas
169
+ shadows
170
+ gl={{
171
+ antialias: true,
172
+ alpha: true,
173
+ // preserveDrawingBuffer is automatically added
174
+ }}
175
+ camera={{ position: [0, 0, 5], fov: 75 }}
176
+ <!-- react-only -->
177
+ scene={{ background: new THREE.Color("#000000") }}
178
+ <!-- /react-only -->
179
+ >
180
+ {/* Scene content */}
181
+ </CompositionCanvas>
182
+ ```
183
+
184
+ <!-- react-only -->
185
+ **Note:** `preserveDrawingBuffer: true` is automatically set for video export compatibility.
186
+
187
+ ### Styling
188
+
189
+ The canvas fills its container absolutely:
190
+
191
+ ```tsx
192
+ <Timegroup mode="fixed" duration="10s" className="w-[1920px] h-[1080px] bg-black">
193
+ <CompositionCanvas
194
+ containerClassName="rounded-lg"
195
+ containerStyle={{ border: "2px solid white" }}
196
+ >
197
+ {/* Scene */}
198
+ </CompositionCanvas>
199
+ </Timegroup>
200
+ ```
201
+ <!-- /react-only -->
202
+
203
+ ## OffscreenCompositionCanvas
204
+
205
+ Renders a React Three Fiber scene in a **web worker** using OffscreenCanvas. This keeps the main thread free and enables rendering to continue even when the browser tab is hidden.
206
+
207
+ ### Worker Setup
208
+
209
+ Create a worker file:
210
+
211
+ ```typescript
212
+ // scene-worker.ts
213
+ import { renderOffscreen } from "@editframe/react/r3f";
214
+ import { useCompositionTime } from "@editframe/react/r3f";
215
+ import { Box } from "@react-three/drei";
216
+
217
+ function Scene() {
218
+ const { timeMs } = useCompositionTime();
219
+ const rotation = (timeMs / 1000) * Math.PI;
220
+
221
+ return (
222
+ <>
223
+ <ambientLight intensity={0.5} />
224
+ <pointLight position={[10, 10, 10]} />
225
+ <Box rotation={[0, rotation, 0]}>
226
+ <meshStandardMaterial color="cyan" />
227
+ </Box>
228
+ </>
229
+ );
230
+ }
231
+
232
+ renderOffscreen(<Scene />);
233
+ ```
234
+
235
+ ### Component Usage
236
+
237
+ ```tsx
238
+ import { Timegroup } from "@editframe/react";
239
+ import { OffscreenCompositionCanvas } from "@editframe/react/r3f";
240
+
241
+ const worker = new Worker(
242
+ new URL('./scene-worker.ts', import.meta.url),
243
+ { type: 'module' }
244
+ );
245
+
246
+ export const Video = () => {
247
+ return (
248
+ <Timegroup mode="fixed" duration="10s" className="w-[1920px] h-[1080px]">
249
+ <OffscreenCompositionCanvas
250
+ worker={worker}
251
+ canvasProps={{ shadows: true, dpr: [1, 2] }}
252
+ fallback={
253
+ <div className="flex items-center justify-center w-full h-full">
254
+ <p>OffscreenCanvas not supported</p>
255
+ </div>
256
+ }
257
+ />
258
+ </Timegroup>
259
+ );
260
+ };
261
+ ```
262
+
263
+ ### Features
264
+
265
+ - **Web Worker Rendering:** All R3F rendering happens in a separate thread
266
+ - **Background Tab Resilience:** Continues rendering when the browser tab is hidden
267
+ - **Zero-Copy Transfer:** Uses ImageBitmap transfer for efficient pixel data
268
+ - **Automatic Sync:** Integrates with `addFrameTask` for frame-by-frame rendering
269
+ - **Safari Fallback:** Shows fallback content when OffscreenCanvas is unavailable
270
+
271
+ <!-- html-only -->
272
+ ### Worker Protocol
273
+
274
+ The worker communicates via structured messages:
275
+
276
+ **Main → Worker:**
277
+ ```typescript
278
+ {
279
+ type: 'renderFrame',
280
+ timeMs: number,
281
+ durationMs: number,
282
+ requestId: number
283
+ }
284
+ ```
285
+
286
+ **Worker → Main:**
287
+ ```typescript
288
+ {
289
+ type: 'frameRendered',
290
+ requestId: number,
291
+ bitmap: ImageBitmap // Transferred, not copied
292
+ }
293
+ ```
294
+ <!-- /html-only -->
295
+
296
+ ### When to Use OffscreenCanvas vs CompositionCanvas
297
+
298
+ **Use OffscreenCompositionCanvas when:**
299
+ - Complex 3D scenes with heavy computation
300
+ - Long render times where main thread responsiveness matters
301
+ - Need guaranteed rendering in background tabs
302
+ - Rendering multiple compositions simultaneously
303
+
304
+ **Use CompositionCanvas when:**
305
+ - Simple 3D scenes
306
+ - Browser compatibility is critical (Safari support)
307
+ - Debugging (easier to inspect in main thread)
308
+ - Using Three.js features incompatible with workers
309
+ <!-- react-only -->
310
+ - Interactive preview with controls
311
+ <!-- /react-only -->
312
+
313
+ <!-- react-only -->
314
+ ### Browser Support
315
+
316
+ - **Chrome:** Full support
317
+ - **Firefox:** Full support
318
+ - **Edge:** Full support
319
+ - **Safari:** Not supported (use `fallback` prop)
320
+
321
+ Use the `fallback` prop to provide alternative content for Safari:
322
+
323
+ ```tsx
324
+ <OffscreenCompositionCanvas
325
+ worker={worker}
326
+ fallback={
327
+ <CompositionCanvas>
328
+ <MyScene />
329
+ </CompositionCanvas>
330
+ }
331
+ />
332
+ ```
333
+ <!-- /react-only -->
334
+
335
+ ## Advanced: <!-- html-only -->Custom<!-- /html-only --><!-- react-only -->Complex<!-- /react-only --> Animations
336
+
337
+ <!-- html-only -->
338
+ Combine `useCompositionTime` with Three.js for complex animations:
339
+ <!-- /html-only -->
340
+
341
+ ### Particle System
342
+
343
+ ```tsx
344
+ <!-- react-only -->
345
+ import { useRef, useEffect } from "react";
346
+ import { useCompositionTime } from "@editframe/react/r3f";
347
+ import * as THREE from "three";
348
+
349
+ <!-- /react-only -->
350
+ function ParticleSystem() {
351
+ const { timeMs, durationMs } = useCompositionTime();
352
+ const meshRef = useRef<THREE.InstancedMesh>(null);
353
+
354
+ useEffect(() => {
355
+ if (!meshRef.current) return;
356
+
357
+ const count = 1000;
358
+ const dummy = new THREE.Object3D();
359
+ const progress = timeMs / durationMs;
360
+
361
+ for (let i = 0; i < count; i++) {
362
+ const t = progress + (i / count) * 0.1;
363
+ const angle = t * Math.PI * 2;
364
+ const radius = 5 + Math.sin(t * 10) * 2;
365
+
366
+ dummy.position.set(
367
+ Math.cos(angle) * radius,
368
+ Math.sin(t * 5) * 3,
369
+ Math.sin(angle) * radius
370
+ );
371
+ dummy.rotation.set(t * Math.PI, t * Math.PI * 2, 0);
372
+ dummy.updateMatrix();
373
+
374
+ meshRef.current.setMatrixAt(i, dummy.matrix);
375
+ }
376
+
377
+ meshRef.current.instanceMatrix.needsUpdate = true;
378
+ }, [timeMs, durationMs]);
379
+
380
+ return (
381
+ <instancedMesh ref={meshRef} args={[undefined, undefined, 1000]}>
382
+ <sphereGeometry args={[0.1, 16, 16]} />
383
+ <meshStandardMaterial color="white" />
384
+ </instancedMesh>
385
+ );
386
+ }
387
+ ```
388
+
389
+ <!-- react-only -->
390
+ ### Camera Animation
391
+
392
+ ```tsx
393
+ import { useThree } from "@react-three/fiber";
394
+ import { useCompositionTime } from "@editframe/react/r3f";
395
+ import { useEffect } from "react";
396
+
397
+ function CameraRig() {
398
+ const { camera } = useThree();
399
+ const { timeMs } = useCompositionTime();
400
+
401
+ useEffect(() => {
402
+ const t = timeMs / 1000;
403
+ camera.position.x = Math.sin(t) * 5;
404
+ camera.position.z = Math.cos(t) * 5;
405
+ camera.lookAt(0, 0, 0);
406
+ }, [timeMs, camera]);
407
+
408
+ return null;
409
+ }
410
+ ```
411
+
412
+ ### Material Animation
413
+
414
+ ```tsx
415
+ function AnimatedMaterial() {
416
+ const { timeMs } = useCompositionTime();
417
+ const materialRef = useRef<THREE.MeshStandardMaterial>(null);
418
+
419
+ useEffect(() => {
420
+ if (!materialRef.current) return;
421
+ const hue = (timeMs / 1000) % 1;
422
+ materialRef.current.color.setHSL(hue, 1, 0.5);
423
+ }, [timeMs]);
424
+
425
+ return (
426
+ <mesh>
427
+ <boxGeometry />
428
+ <meshStandardMaterial ref={materialRef} />
429
+ </mesh>
430
+ );
431
+ }
432
+ ```
433
+
434
+ ## Integration with @react-three/drei
435
+
436
+ Use Drei helpers with Editframe:
437
+
438
+ ```tsx
439
+ import { OrbitControls, Environment, ContactShadows } from "@react-three/drei";
440
+ import { CompositionCanvas, useCompositionTime } from "@editframe/react/r3f";
441
+
442
+ function Scene() {
443
+ const { timeMs } = useCompositionTime();
444
+
445
+ return (
446
+ <>
447
+ <OrbitControls enableZoom={false} />
448
+ <Environment preset="sunset" />
449
+ <ContactShadows opacity={0.5} />
450
+
451
+ <Box position={[0, Math.sin(timeMs / 500), 0]} />
452
+ </>
453
+ );
454
+ }
455
+
456
+ export const Video = () => {
457
+ return (
458
+ <Timegroup mode="fixed" duration="10s" className="w-[1920px] h-[1080px]">
459
+ <CompositionCanvas>
460
+ <Scene />
461
+ </CompositionCanvas>
462
+ </Timegroup>
463
+ );
464
+ };
465
+ ```
466
+ <!-- /react-only -->
467
+
468
+ ## Rendering to Video
469
+
470
+ 3D scenes render to video just like any other Editframe element:
471
+
472
+ ```tsx
473
+ import { Timegroup } from "@editframe/react";
474
+ import { CompositionCanvas } from "@editframe/react/r3f";
475
+
476
+ export const Video = () => {
477
+ return (
478
+ <Timegroup
479
+ mode="fixed"
480
+ duration="10s"
481
+ className="w-[1920px] h-[1080px]"
482
+ >
483
+ <CompositionCanvas>
484
+ {/* Your 3D scene */}
485
+ </CompositionCanvas>
486
+ </Timegroup>
487
+ );
488
+ };
489
+
490
+ // Render with CLI
491
+ // npx editframe render ./src/Video.tsx
492
+ ```
493
+
494
+ The R3F integration ensures:
495
+ 1. Each frame renders synchronously at the correct timeline position
496
+ 2. WebGL finishes all commands before frame capture
497
+ 3. Deterministic output regardless of playback state
498
+ 4. Proper integration with Editframe's rendering pipeline
499
+
500
+ ## Browser Support
501
+
502
+ - **CompositionCanvas:** All modern browsers (Chrome, Firefox, Safari, Edge)
503
+ - **OffscreenCompositionCanvas:** Chrome, Firefox, Edge (Safari does not support OffscreenCanvas)
504
+
505
+ <!-- react-only -->
506
+ ## Performance Tips
507
+
508
+ 1. **Memoize scene components** to avoid unnecessary re-renders:
509
+ ```tsx
510
+ const Scene = React.memo(() => {
511
+ const { timeMs } = useCompositionTime();
512
+ // ...
513
+ });
514
+ ```
515
+
516
+ 2. **Use instancing** for many identical objects:
517
+ ```tsx
518
+ <instancedMesh args={[geometry, material, count]} />
519
+ ```
520
+
521
+ 3. **Limit geometry complexity** during rendering:
522
+ ```tsx
523
+ <sphereGeometry args={[1, 16, 16]} /> {/* Lower segments */}
524
+ ```
525
+
526
+ 4. **Disable antialiasing** if not needed:
527
+ ```tsx
528
+ <CompositionCanvas gl={{ antialias: false }}>
529
+ ```
530
+
531
+ ## Troubleshooting
532
+
533
+ ### Scene appears black
534
+ **Problem:** Missing lights or incorrect camera setup.
535
+
536
+ **Solution:**
537
+ ```tsx
538
+ <CompositionCanvas>
539
+ <ambientLight intensity={0.5} />
540
+ <pointLight position={[10, 10, 10]} />
541
+ {/* Your scene */}
542
+ </CompositionCanvas>
543
+ ```
544
+
545
+ ### Animation stutters during export
546
+ **Problem:** Animations using `useFrame` RAF loop.
547
+
548
+ **Solution:** Use `useCompositionTime()` instead:
549
+ ```tsx
550
+ // Don't use useFrame for time-based animations
551
+ useFrame((state) => {
552
+ mesh.rotation.y += 0.01;
553
+ });
554
+
555
+ // Use useCompositionTime
556
+ const { timeMs } = useCompositionTime();
557
+ mesh.rotation.y = timeMs / 1000;
558
+ ```
559
+
560
+ ### Worker fails to load
561
+ **Problem:** Incorrect worker URL or module type.
562
+
563
+ **Solution:**
564
+ ```tsx
565
+ // Correct
566
+ const worker = new Worker(
567
+ new URL('./worker.ts', import.meta.url),
568
+ { type: 'module' }
569
+ );
570
+
571
+ // Wrong
572
+ const worker = new Worker('./worker.ts');
573
+ ```
574
+ <!-- /react-only -->
575
+
576
+ ## Related
577
+
578
+ - [timegroup.md](references/timegroup.md) - Timeline container <!-- html-only -->element<!-- /html-only --><!-- react-only -->component<!-- /react-only -->
579
+ - [render-to-video.md](references/render-to-video.md) - Rendering compositions to video
580
+ - [scripting.md](references/scripting.md) - Programmatic element control