@editframe/create 0.43.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 (99) hide show
  1. package/README.md +11 -0
  2. package/dist/index.js +16 -28
  3. package/dist/index.js.map +1 -1
  4. package/dist/skills/editframe-brand-video-generator/README.md +155 -0
  5. package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
  6. package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
  7. package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
  8. package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
  9. package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
  10. package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
  11. package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
  12. package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
  13. package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
  14. package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
  15. package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
  16. package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
  17. package/dist/skills/editframe-composition/SKILL.md +169 -0
  18. package/dist/skills/editframe-composition/references/audio.md +483 -0
  19. package/dist/skills/editframe-composition/references/captions.md +844 -0
  20. package/dist/skills/editframe-composition/references/composition-model.md +73 -0
  21. package/dist/skills/editframe-composition/references/configuration.md +403 -0
  22. package/dist/skills/editframe-composition/references/css-parts.md +105 -0
  23. package/dist/skills/editframe-composition/references/css-variables.md +640 -0
  24. package/dist/skills/editframe-composition/references/entry-points.md +810 -0
  25. package/dist/skills/editframe-composition/references/events.md +499 -0
  26. package/dist/skills/editframe-composition/references/getting-started.md +259 -0
  27. package/dist/skills/editframe-composition/references/hooks.md +234 -0
  28. package/dist/skills/editframe-composition/references/image.md +241 -0
  29. package/dist/skills/editframe-composition/references/r3f.md +580 -0
  30. package/dist/skills/editframe-composition/references/render-api.md +484 -0
  31. package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
  32. package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
  33. package/dist/skills/editframe-composition/references/scripting.md +606 -0
  34. package/dist/skills/editframe-composition/references/sequencing.md +116 -0
  35. package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
  36. package/dist/skills/editframe-composition/references/surface.md +329 -0
  37. package/dist/skills/editframe-composition/references/text.md +627 -0
  38. package/dist/skills/editframe-composition/references/time-model.md +99 -0
  39. package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
  40. package/dist/skills/editframe-composition/references/timegroup.md +457 -0
  41. package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
  42. package/dist/skills/editframe-composition/references/transcription.md +47 -0
  43. package/dist/skills/editframe-composition/references/transitions.md +608 -0
  44. package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
  45. package/dist/skills/editframe-composition/references/video.md +506 -0
  46. package/dist/skills/editframe-composition/references/waveform.md +327 -0
  47. package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
  48. package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
  49. package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
  50. package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
  51. package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
  52. package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
  53. package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
  54. package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
  55. package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
  56. package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
  57. package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
  58. package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
  59. package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
  60. package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
  61. package/dist/skills/editframe-editor-gui/references/play.md +370 -0
  62. package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
  63. package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
  64. package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
  65. package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
  66. package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
  67. package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
  68. package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
  69. package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
  70. package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
  71. package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
  72. package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
  73. package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
  74. package/dist/skills/editframe-motion-design/SKILL.md +101 -0
  75. package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
  76. package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
  77. package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
  78. package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
  79. package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
  80. package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
  81. package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
  82. package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
  83. package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
  84. package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
  85. package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
  86. package/dist/skills/editframe-webhooks/SKILL.md +126 -0
  87. package/dist/skills/editframe-webhooks/references/events.md +382 -0
  88. package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
  89. package/dist/skills/editframe-webhooks/references/security.md +418 -0
  90. package/dist/skills/editframe-webhooks/references/testing.md +409 -0
  91. package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
  92. package/dist/templates/html/AGENTS.md +13 -0
  93. package/dist/templates/react/AGENTS.md +13 -0
  94. package/dist/utils.js +15 -16
  95. package/dist/utils.js.map +1 -1
  96. package/package.json +2 -2
  97. package/tsdown.config.ts +4 -0
  98. package/dist/detectAgent.js +0 -89
  99. package/dist/detectAgent.js.map +0 -1
@@ -0,0 +1,608 @@
1
+ ---
2
+ title: Transitions
3
+ description: Create smooth CSS-animated transitions between sequence items using configurable overlap duration and animation keyframes.
4
+ type: how-to
5
+ nav:
6
+ parent: "Layout & Timing"
7
+ priority: 12
8
+ related: ["sequencing", "video~effects"]
9
+ prerequisites: ["sequencing"]
10
+ react:
11
+ generate: true
12
+ componentName: "Transitions"
13
+ importPath: "@editframe/react"
14
+ nav:
15
+ parent: "Guides"
16
+ priority: 20
17
+ related: ["timegroup", "css-variables"]
18
+ ---
19
+
20
+ # Transitions
21
+
22
+ Create smooth transitions between sequence items using overlap and CSS animations.
23
+
24
+ ## Overlap <!-- html-only -->Attribute<!-- /html-only --><!-- react-only -->Prop<!-- /react-only -->
25
+
26
+ Use `overlap` on sequence timegroups to make items overlap in time:
27
+
28
+ <!-- html-only -->
29
+ ```html
30
+ <ef-timegroup mode="sequence" overlap="1s">
31
+ <ef-timegroup mode="contain"><!-- Scene 1 --></ef-timegroup>
32
+ <ef-timegroup mode="contain"><!-- Scene 2 --></ef-timegroup>
33
+ </ef-timegroup>
34
+ ```
35
+ <!-- /html-only -->
36
+ <!-- react-only -->
37
+ ```tsx
38
+ <Timegroup mode="sequence" overlap="1s">
39
+ <Timegroup mode="contain">{/* Scene 1 */}</Timegroup>
40
+ <Timegroup mode="contain">{/* Scene 2 */}</Timegroup>
41
+ </Timegroup>
42
+ ```
43
+ <!-- /react-only -->
44
+
45
+ This creates a 1-second overlap where both scenes are visible simultaneously.
46
+
47
+ ## CSS Variables for Transitions
48
+
49
+ Use these variables to time animations:
50
+
51
+ - `--ef-duration` - Element's total duration (e.g., `"10s"`)
52
+ - `--ef-transition-duration` - Overlap duration for transitions
53
+ - `--ef-transition-out-start` - When fade-out should start (near end)
54
+
55
+ ## Crossfade Transition
56
+
57
+ Fade out first clip while fading in second clip:
58
+
59
+ <!-- html-only -->
60
+ ```html
61
+ <style>
62
+ @keyframes fade-in {
63
+ from { opacity: 0; }
64
+ to { opacity: 1; }
65
+ }
66
+
67
+ @keyframes fade-out {
68
+ from { opacity: 1; }
69
+ to { opacity: 0; }
70
+ }
71
+ </style>
72
+
73
+ <ef-timegroup mode="sequence" overlap="1s">
74
+ <ef-timegroup mode="contain">
75
+ <ef-video
76
+ src="clip1.mp4"
77
+ class="size-full"
78
+ style="animation: 1s fade-out var(--ef-transition-out-start)"
79
+ ></ef-video>
80
+ </ef-timegroup>
81
+
82
+ <ef-timegroup mode="contain">
83
+ <ef-video
84
+ src="clip2.mp4"
85
+ class="size-full"
86
+ style="animation: 1s fade-in 0s"
87
+ ></ef-video>
88
+ </ef-timegroup>
89
+ </ef-timegroup>
90
+ ```
91
+ <!-- /html-only -->
92
+ <!-- react-only -->
93
+ ```tsx
94
+ import { Timegroup, Video } from "@editframe/react";
95
+
96
+ const CrossfadeExample = () => {
97
+ return (
98
+ <>
99
+ <style>{`
100
+ @keyframes fade-in {
101
+ from { opacity: 0; }
102
+ to { opacity: 1; }
103
+ }
104
+
105
+ @keyframes fade-out {
106
+ from { opacity: 1; }
107
+ to { opacity: 0; }
108
+ }
109
+ `}</style>
110
+
111
+ <Timegroup mode="sequence" overlap="1s">
112
+ <Timegroup mode="contain">
113
+ <Video
114
+ src="/assets/clip1.mp4"
115
+ className="size-full"
116
+ style={{ animation: "1s fade-out var(--ef-transition-out-start)" }}
117
+ />
118
+ </Timegroup>
119
+
120
+ <Timegroup mode="contain">
121
+ <Video
122
+ src="/assets/clip2.mp4"
123
+ className="size-full"
124
+ style={{ animation: "1s fade-in 0s" }}
125
+ />
126
+ </Timegroup>
127
+ </Timegroup>
128
+ </>
129
+ );
130
+ };
131
+ ```
132
+ <!-- /react-only -->
133
+
134
+ **How it works:**
135
+ 1. `overlap="1s"` makes clips overlap by 1 second
136
+ 2. First clip fades out during last 1 second (`--ef-transition-out-start`)
137
+ 3. Second clip fades in during first 1 second (`0s` delay)
138
+ 4. Result: Smooth crossfade
139
+
140
+ ## Slide Transition
141
+
142
+ Slide second clip in from the right:
143
+
144
+ <!-- html-only -->
145
+ ```html
146
+ <style>
147
+ @keyframes slide-in-right {
148
+ from { transform: translateX(100%); }
149
+ to { transform: translateX(0); }
150
+ }
151
+
152
+ @keyframes slide-out-left {
153
+ from { transform: translateX(0); }
154
+ to { transform: translateX(-100%); }
155
+ }
156
+ </style>
157
+
158
+ <ef-timegroup mode="sequence" overlap="0.5s">
159
+ <ef-timegroup mode="contain" class="absolute w-full h-full">
160
+ <ef-video
161
+ src="clip1.mp4"
162
+ class="size-full"
163
+ style="animation: 0.5s slide-out-left var(--ef-transition-out-start)"
164
+ ></ef-video>
165
+ </ef-timegroup>
166
+
167
+ <ef-timegroup mode="contain" class="absolute w-full h-full">
168
+ <ef-video
169
+ src="clip2.mp4"
170
+ class="size-full"
171
+ style="animation: 0.5s slide-in-right 0s"
172
+ ></ef-video>
173
+ </ef-timegroup>
174
+ </ef-timegroup>
175
+ ```
176
+ <!-- /html-only -->
177
+ <!-- react-only -->
178
+ ```tsx
179
+ const SlideTransition = () => {
180
+ return (
181
+ <>
182
+ <style>{`
183
+ @keyframes slide-in-right {
184
+ from { transform: translateX(100%); }
185
+ to { transform: translateX(0); }
186
+ }
187
+
188
+ @keyframes slide-out-left {
189
+ from { transform: translateX(0); }
190
+ to { transform: translateX(-100%); }
191
+ }
192
+ `}</style>
193
+
194
+ <Timegroup mode="sequence" overlap="0.5s">
195
+ <Timegroup mode="contain" className="absolute w-full h-full">
196
+ <Video
197
+ src="/assets/clip1.mp4"
198
+ className="size-full"
199
+ style={{ animation: "0.5s slide-out-left var(--ef-transition-out-start)" }}
200
+ />
201
+ </Timegroup>
202
+
203
+ <Timegroup mode="contain" className="absolute w-full h-full">
204
+ <Video
205
+ src="/assets/clip2.mp4"
206
+ className="size-full"
207
+ style={{ animation: "0.5s slide-in-right 0s" }}
208
+ />
209
+ </Timegroup>
210
+ </Timegroup>
211
+ </>
212
+ );
213
+ };
214
+ ```
215
+ <!-- /react-only -->
216
+
217
+ ## Zoom Transition
218
+
219
+ Zoom out first clip while zooming in second:
220
+
221
+ <!-- html-only -->
222
+ ```html
223
+ <style>
224
+ @keyframes zoom-in {
225
+ from { transform: scale(0.5); opacity: 0; }
226
+ to { transform: scale(1); opacity: 1; }
227
+ }
228
+
229
+ @keyframes zoom-out {
230
+ from { transform: scale(1); opacity: 1; }
231
+ to { transform: scale(1.5); opacity: 0; }
232
+ }
233
+ </style>
234
+
235
+ <ef-timegroup mode="sequence" overlap="0.8s">
236
+ <ef-timegroup mode="contain" class="absolute w-full h-full">
237
+ <ef-video
238
+ src="clip1.mp4"
239
+ class="size-full object-cover"
240
+ style="animation: 0.8s zoom-out var(--ef-transition-out-start)"
241
+ ></ef-video>
242
+ </ef-timegroup>
243
+
244
+ <ef-timegroup mode="contain" class="absolute w-full h-full">
245
+ <ef-video
246
+ src="clip2.mp4"
247
+ class="size-full object-cover"
248
+ style="animation: 0.8s zoom-in 0s"
249
+ ></ef-video>
250
+ </ef-timegroup>
251
+ </ef-timegroup>
252
+ ```
253
+ <!-- /html-only -->
254
+ <!-- react-only -->
255
+ ```tsx
256
+ const ZoomTransition = () => {
257
+ return (
258
+ <>
259
+ <style>{`
260
+ @keyframes zoom-in {
261
+ from { transform: scale(0.5); opacity: 0; }
262
+ to { transform: scale(1); opacity: 1; }
263
+ }
264
+
265
+ @keyframes zoom-out {
266
+ from { transform: scale(1); opacity: 1; }
267
+ to { transform: scale(1.5); opacity: 0; }
268
+ }
269
+ `}</style>
270
+
271
+ <Timegroup mode="sequence" overlap="0.8s">
272
+ <Timegroup mode="contain" className="absolute w-full h-full">
273
+ <Video
274
+ src="/assets/clip1.mp4"
275
+ className="size-full object-cover"
276
+ style={{ animation: "0.8s zoom-out var(--ef-transition-out-start)" }}
277
+ />
278
+ </Timegroup>
279
+
280
+ <Timegroup mode="contain" className="absolute w-full h-full">
281
+ <Video
282
+ src="/assets/clip2.mp4"
283
+ className="size-full object-cover"
284
+ style={{ animation: "0.8s zoom-in 0s" }}
285
+ />
286
+ </Timegroup>
287
+ </Timegroup>
288
+ </>
289
+ );
290
+ };
291
+ ```
292
+ <!-- /react-only -->
293
+
294
+ ## Dissolve Transition
295
+
296
+ Gradual opacity transition with blur:
297
+
298
+ <!-- html-only -->
299
+ ```html
300
+ <style>
301
+ @keyframes dissolve-in {
302
+ from { opacity: 0; filter: blur(10px); }
303
+ to { opacity: 1; filter: blur(0); }
304
+ }
305
+
306
+ @keyframes dissolve-out {
307
+ from { opacity: 1; filter: blur(0); }
308
+ to { opacity: 0; filter: blur(10px); }
309
+ }
310
+ </style>
311
+
312
+ <ef-timegroup mode="sequence" overlap="1.5s">
313
+ <ef-timegroup mode="contain">
314
+ <ef-video
315
+ src="clip1.mp4"
316
+ class="size-full"
317
+ style="animation: 1.5s dissolve-out var(--ef-transition-out-start)"
318
+ ></ef-video>
319
+ </ef-timegroup>
320
+
321
+ <ef-timegroup mode="contain">
322
+ <ef-video
323
+ src="clip2.mp4"
324
+ class="size-full"
325
+ style="animation: 1.5s dissolve-in 0s"
326
+ ></ef-video>
327
+ </ef-timegroup>
328
+ </ef-timegroup>
329
+ ```
330
+ <!-- /html-only -->
331
+ <!-- react-only -->
332
+ ```tsx
333
+ const DissolveTransition = () => {
334
+ return (
335
+ <>
336
+ <style>{`
337
+ @keyframes dissolve-in {
338
+ from { opacity: 0; filter: blur(10px); }
339
+ to { opacity: 1; filter: blur(0); }
340
+ }
341
+
342
+ @keyframes dissolve-out {
343
+ from { opacity: 1; filter: blur(0); }
344
+ to { opacity: 0; filter: blur(10px); }
345
+ }
346
+ `}</style>
347
+
348
+ <Timegroup mode="sequence" overlap="1.5s">
349
+ <Timegroup mode="contain">
350
+ <Video
351
+ src="/assets/clip1.mp4"
352
+ className="size-full"
353
+ style={{ animation: "1.5s dissolve-out var(--ef-transition-out-start)" }}
354
+ />
355
+ </Timegroup>
356
+
357
+ <Timegroup mode="contain">
358
+ <Video
359
+ src="/assets/clip2.mp4"
360
+ className="size-full"
361
+ style={{ animation: "1.5s dissolve-in 0s" }}
362
+ />
363
+ </Timegroup>
364
+ </Timegroup>
365
+ </>
366
+ );
367
+ };
368
+ ```
369
+ <!-- /react-only -->
370
+
371
+ ## Multiple Clips with Transitions
372
+
373
+ Chain multiple clips with consistent transitions:
374
+
375
+ <!-- html-only -->
376
+ ```html
377
+ <ef-timegroup mode="sequence" overlap="1s">
378
+ <ef-timegroup mode="contain">
379
+ <ef-video
380
+ src="clip1.mp4"
381
+ class="size-full"
382
+ style="animation: 1s fade-out var(--ef-transition-out-start)"
383
+ ></ef-video>
384
+ </ef-timegroup>
385
+
386
+ <ef-timegroup mode="contain">
387
+ <ef-video
388
+ src="clip2.mp4"
389
+ class="size-full"
390
+ style="animation: 1s fade-in 0s, 1s fade-out var(--ef-transition-out-start)"
391
+ ></ef-video>
392
+ </ef-timegroup>
393
+
394
+ <ef-timegroup mode="contain">
395
+ <ef-video
396
+ src="clip3.mp4"
397
+ class="size-full"
398
+ style="animation: 1s fade-in 0s, 1s fade-out var(--ef-transition-out-start)"
399
+ ></ef-video>
400
+ </ef-timegroup>
401
+
402
+ <ef-timegroup mode="contain">
403
+ <ef-video
404
+ src="clip4.mp4"
405
+ class="size-full"
406
+ style="animation: 1s fade-in 0s"
407
+ ></ef-video>
408
+ </ef-timegroup>
409
+ </ef-timegroup>
410
+ ```
411
+ <!-- /html-only -->
412
+ <!-- react-only -->
413
+ ```tsx
414
+ const MultiClipTransitions = () => {
415
+ const clips = [
416
+ "/assets/clip1.mp4",
417
+ "/assets/clip2.mp4",
418
+ "/assets/clip3.mp4",
419
+ "/assets/clip4.mp4",
420
+ ];
421
+
422
+ return (
423
+ <>
424
+ <style>{`
425
+ @keyframes fade-in {
426
+ from { opacity: 0; }
427
+ to { opacity: 1; }
428
+ }
429
+
430
+ @keyframes fade-out {
431
+ from { opacity: 1; }
432
+ to { opacity: 0; }
433
+ }
434
+ `}</style>
435
+
436
+ <Timegroup mode="sequence" overlap="1s">
437
+ {clips.map((src, index) => {
438
+ const isFirst = index === 0;
439
+ const isLast = index === clips.length - 1;
440
+
441
+ let animation = "";
442
+ if (isFirst) {
443
+ animation = "1s fade-out var(--ef-transition-out-start)";
444
+ } else if (isLast) {
445
+ animation = "1s fade-in 0s";
446
+ } else {
447
+ animation = "1s fade-in 0s, 1s fade-out var(--ef-transition-out-start)";
448
+ }
449
+
450
+ return (
451
+ <Timegroup key={src} mode="contain">
452
+ <Video
453
+ src={src}
454
+ className="size-full"
455
+ style={{ animation }}
456
+ />
457
+ </Timegroup>
458
+ );
459
+ })}
460
+ </Timegroup>
461
+ </>
462
+ );
463
+ };
464
+ ```
465
+ <!-- /react-only -->
466
+
467
+ **Pattern:**
468
+ - First clip: fade-out only
469
+ - Middle clips: fade-in and fade-out
470
+ - Last clip: fade-in only
471
+
472
+ ## Transition Timing
473
+
474
+ Match overlap duration to animation duration:
475
+
476
+ <!-- html-only -->
477
+ ```html
478
+ <!-- overlap="1s" matches animation duration of 1s -->
479
+ <ef-timegroup mode="sequence" overlap="1s">
480
+ <ef-timegroup mode="contain">
481
+ <ef-video style="animation: 1s fade-out var(--ef-transition-out-start)"></ef-video>
482
+ </ef-timegroup>
483
+ <ef-timegroup mode="contain">
484
+ <ef-video style="animation: 1s fade-in 0s"></ef-video>
485
+ </ef-timegroup>
486
+ </ef-timegroup>
487
+ ```
488
+ <!-- /html-only -->
489
+ <!-- react-only -->
490
+ ```tsx
491
+ {/* overlap="1s" matches animation duration of 1s */}
492
+ <Timegroup mode="sequence" overlap="1s">
493
+ <Timegroup mode="contain">
494
+ <Video style={{ animation: "1s fade-out var(--ef-transition-out-start)" }} />
495
+ </Timegroup>
496
+ <Timegroup mode="contain">
497
+ <Video style={{ animation: "1s fade-in 0s" }} />
498
+ </Timegroup>
499
+ </Timegroup>
500
+ ```
501
+ <!-- /react-only -->
502
+
503
+ **Important:** Animation duration should match overlap duration for smooth transitions.
504
+
505
+ ## No Overlap (Cut)
506
+
507
+ Omit `overlap` for instant cuts between clips:
508
+
509
+ <!-- html-only -->
510
+ ```html
511
+ <ef-timegroup mode="sequence">
512
+ <ef-timegroup mode="contain">
513
+ <ef-video src="clip1.mp4" class="size-full"></ef-video>
514
+ </ef-timegroup>
515
+ <ef-timegroup mode="contain">
516
+ <ef-video src="clip2.mp4" class="size-full"></ef-video>
517
+ </ef-timegroup>
518
+ </ef-timegroup>
519
+ ```
520
+ <!-- /html-only -->
521
+ <!-- react-only -->
522
+ ```tsx
523
+ <Timegroup mode="sequence">
524
+ <Timegroup mode="contain">
525
+ <Video src="/assets/clip1.mp4" className="size-full" />
526
+ </Timegroup>
527
+ <Timegroup mode="contain">
528
+ <Video src="/assets/clip2.mp4" className="size-full" />
529
+ </Timegroup>
530
+ </Timegroup>
531
+ ```
532
+ <!-- /react-only -->
533
+
534
+ <!-- react-only -->
535
+ ## Reusable Transition Component
536
+
537
+ Create a reusable component for transitions:
538
+
539
+ ```tsx
540
+ interface TransitionProps {
541
+ children: React.ReactNode;
542
+ type?: "fade" | "slide" | "zoom";
543
+ duration?: string;
544
+ }
545
+
546
+ const TransitionScene = ({
547
+ children,
548
+ type = "fade",
549
+ duration = "1s"
550
+ }: TransitionProps) => {
551
+ const animations = {
552
+ fade: {
553
+ in: `${duration} fade-in 0s`,
554
+ out: `${duration} fade-out var(--ef-transition-out-start)`,
555
+ },
556
+ slide: {
557
+ in: `${duration} slide-in-right 0s`,
558
+ out: `${duration} slide-out-left var(--ef-transition-out-start)`,
559
+ },
560
+ zoom: {
561
+ in: `${duration} zoom-in 0s`,
562
+ out: `${duration} zoom-out var(--ef-transition-out-start)`,
563
+ },
564
+ };
565
+
566
+ return (
567
+ <Timegroup
568
+ mode="contain"
569
+ className="absolute w-full h-full"
570
+ style={{ animation: `${animations[type].in}, ${animations[type].out}` }}
571
+ >
572
+ {children}
573
+ </Timegroup>
574
+ );
575
+ };
576
+
577
+ // Usage
578
+ <Timegroup mode="sequence" overlap="1s">
579
+ <TransitionScene type="fade">
580
+ <Video src="/assets/clip1.mp4" className="size-full" />
581
+ </TransitionScene>
582
+ <TransitionScene type="slide">
583
+ <Video src="/assets/clip2.mp4" className="size-full" />
584
+ </TransitionScene>
585
+ </Timegroup>
586
+ ```
587
+ <!-- /react-only -->
588
+
589
+ ## Tips
590
+
591
+ 1. **Match durations** - Overlap and animation duration should be equal
592
+ 2. **Use contain mode** - Wrap clips in `mode="contain"` timegroups
593
+ <!-- html-only -->
594
+ 3. **Absolute positioning** - Add `class="absolute w-full h-full"` for overlays
595
+ <!-- /html-only -->
596
+ <!-- react-only -->
597
+ 3. **Absolute positioning** - Add `className="absolute w-full h-full"` for overlays
598
+ <!-- /react-only -->
599
+ 4. **Test transitions** - Preview to ensure smooth timing
600
+ 5. **Combine effects** - Mix opacity, transform, and filter for complex transitions
601
+ <!-- react-only -->
602
+ 6. **Extract to components** - Create reusable transition components
603
+ <!-- /react-only -->
604
+
605
+ ## See Also
606
+
607
+ - [css-variables.md](references/css-variables.md) - CSS variables reference
608
+ - [timegroup.md](references/timegroup.md) - Timegroup <!-- html-only -->modes and sequencing<!-- /html-only --><!-- react-only -->component reference<!-- /react-only -->