@editframe/create 0.44.0 → 0.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,566 @@
1
+ ---
2
+ title: Thumbnail Strip Element
3
+ description: Video thumbnail strip that generates and displays preview frames at regular intervals along the composition timeline.
4
+ type: reference
5
+ nav:
6
+ parent: "Timeline"
7
+ priority: 21
8
+ api:
9
+ attributes:
10
+ - name: target
11
+ type: string
12
+ required: true
13
+ description: ID of target video or root timegroup element
14
+ - name: targetElement
15
+ type: Element
16
+ description: Direct reference to target element (alternative to target)
17
+ - name: thumbnail-height
18
+ type: number
19
+ default: 24
20
+ description: Height of thumbnails in pixels
21
+ - name: thumbnail-spacing-px
22
+ type: number
23
+ default: 48
24
+ description: Spacing between thumbnail centers in pixels
25
+ - name: pixels-per-ms
26
+ type: number
27
+ description: Zoom level (overrides timeline context)
28
+ - name: use-intrinsic-duration
29
+ type: boolean
30
+ default: false
31
+ description: Use source duration instead of trimmed duration
32
+ react:
33
+ generate: true
34
+ componentName: ThumbnailStrip
35
+ importPath: "@editframe/react"
36
+ propMapping:
37
+ thumbnail-height: thumbnailHeight
38
+ thumbnail-spacing-px: thumbnailSpacingPx
39
+ pixels-per-ms: pixelsPerMs
40
+ use-intrinsic-duration: useIntrinsicDuration
41
+ additionalProps:
42
+ - name: className
43
+ type: string
44
+ description: CSS classes for styling
45
+ nav:
46
+ parent: "Tools"
47
+ priority: 46
48
+ related: ["timeline", "filmstrip", "video"]
49
+ ---
50
+
51
+ <!-- html-only -->
52
+ # ef-thumbnail-strip
53
+ <!-- /html-only -->
54
+ <!-- react-only -->
55
+ # ThumbnailStrip
56
+ <!-- /react-only -->
57
+
58
+ Visual thumbnail strip showing preview frames from video or timegroup elements. Automatically generates and displays thumbnails at regular intervals along the timeline.
59
+
60
+ <!-- react-only -->
61
+ ## Import
62
+
63
+ ```tsx
64
+ import { ThumbnailStrip } from "@editframe/react";
65
+ ```
66
+ <!-- /react-only -->
67
+
68
+ ## Basic Usage
69
+
70
+ <!-- html-only -->
71
+ Thumbnail strip for a video element.
72
+
73
+ ```html live
74
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="thumb-demo">
75
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
76
+ </ef-timegroup>
77
+ <div class="mt-4 h-[48px] bg-gray-900 rounded-lg overflow-auto">
78
+ <ef-thumbnail-strip target="thumb-demo" thumbnail-height="48"></ef-thumbnail-strip>
79
+ </div>
80
+ <div class="mt-2 flex gap-2">
81
+ <ef-controls target="thumb-demo">
82
+ <ef-toggle-play class="px-3 py-1 bg-blue-600 text-white rounded"></ef-toggle-play>
83
+ </ef-controls>
84
+ </div>
85
+ ```
86
+ <!-- /html-only -->
87
+ <!-- react-only -->
88
+ ```tsx
89
+ import { ThumbnailStrip, Video } from "@editframe/react";
90
+
91
+ <div className="h-12 bg-gray-900 relative">
92
+ <ThumbnailStrip target="video-1" />
93
+ </div>
94
+
95
+ <Video id="video-1" src="/video.mp4" className="size-full" />
96
+ ```
97
+ <!-- /react-only -->
98
+
99
+ ## Adjustable Thumbnail Size
100
+
101
+ Control thumbnail height while maintaining aspect ratio.
102
+
103
+ <!-- html-only -->
104
+ ```html live
105
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="size-demo">
106
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
107
+ </ef-timegroup>
108
+ <div class="mt-4 space-y-2">
109
+ <div class="text-white text-sm">24px height:</div>
110
+ <div class="h-[24px] bg-gray-900 rounded-lg overflow-auto">
111
+ <ef-thumbnail-strip target="size-demo" thumbnail-height="24"></ef-thumbnail-strip>
112
+ </div>
113
+ <div class="text-white text-sm mt-4">48px height:</div>
114
+ <div class="h-[48px] bg-gray-900 rounded-lg overflow-auto">
115
+ <ef-thumbnail-strip target="size-demo" thumbnail-height="48"></ef-thumbnail-strip>
116
+ </div>
117
+ </div>
118
+ ```
119
+ <!-- /html-only -->
120
+ <!-- react-only -->
121
+ ```tsx
122
+ <ThumbnailStrip
123
+ target="video-1"
124
+ thumbnailHeight={64}
125
+ thumbnailSpacingPx={80}
126
+ className="h-16"
127
+ />
128
+ ```
129
+ <!-- /react-only -->
130
+
131
+ ## Thumbnail Spacing
132
+
133
+ Control spacing between thumbnails.
134
+
135
+ <!-- html-only -->
136
+ ```html live
137
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="spacing-demo">
138
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
139
+ </ef-timegroup>
140
+ <div class="mt-4 space-y-2">
141
+ <div class="text-white text-sm">Dense spacing (24px):</div>
142
+ <div class="h-[48px] bg-gray-900 rounded-lg overflow-auto">
143
+ <ef-thumbnail-strip
144
+ target="spacing-demo"
145
+ thumbnail-height="48"
146
+ thumbnail-spacing-px="24"
147
+ ></ef-thumbnail-strip>
148
+ </div>
149
+ <div class="text-white text-sm mt-4">Wide spacing (96px):</div>
150
+ <div class="h-[48px] bg-gray-900 rounded-lg overflow-auto">
151
+ <ef-thumbnail-strip
152
+ target="spacing-demo"
153
+ thumbnail-height="48"
154
+ thumbnail-spacing-px="96"
155
+ ></ef-thumbnail-strip>
156
+ </div>
157
+ </div>
158
+ ```
159
+ <!-- /html-only -->
160
+
161
+ ## Timeline Integration
162
+
163
+ <!-- html-only -->
164
+ Thumbnails automatically integrate with timeline zoom and scroll.
165
+
166
+ ```html live
167
+ <ef-timegroup mode="contain" class="w-[720px] h-[480px] bg-black" id="timeline-thumbs">
168
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="size-full object-contain"></ef-video>
169
+ </ef-timegroup>
170
+ <div class="mt-4 h-[350px] bg-gray-900 rounded-lg overflow-hidden">
171
+ <ef-timeline target="timeline-thumbs"></ef-timeline>
172
+ </div>
173
+ <div class="mt-2 text-white text-sm">
174
+ Thumbnails automatically appear in video tracks. Zoom in to see more detail.
175
+ </div>
176
+ ```
177
+ <!-- /html-only -->
178
+ <!-- react-only -->
179
+ ThumbnailStrip is typically used inside Timeline:
180
+
181
+ ```tsx
182
+ import { Timeline, Timegroup, Video } from "@editframe/react";
183
+
184
+ <Timeline className="w-full h-96" />
185
+
186
+ <Timegroup mode="sequence" className="w-[1920px] h-[1080px]">
187
+ <Video src="/video.mp4" />
188
+ </Timegroup>
189
+ ```
190
+ <!-- /react-only -->
191
+
192
+ <!-- html-only -->
193
+ ## Timegroup Thumbnails
194
+
195
+ Generate thumbnails from entire compositions, not just video.
196
+
197
+ ```html live
198
+ <ef-timegroup mode="sequence" class="w-[720px] h-[480px] bg-black" id="comp-thumbs">
199
+ <ef-timegroup class="flex items-center justify-center">
200
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" sourcein="0s" sourceout="2s" class="absolute inset-0 size-full object-contain"></ef-video>
201
+ <h1 class="text-white text-6xl font-bold bg-blue-600 p-6 rounded relative">One</h1>
202
+ </ef-timegroup>
203
+ <ef-timegroup class="flex items-center justify-center">
204
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" sourcein="5s" sourceout="7s" class="absolute inset-0 size-full object-contain"></ef-video>
205
+ <h1 class="text-white text-6xl font-bold bg-purple-600 p-6 rounded relative">Two</h1>
206
+ </ef-timegroup>
207
+ </ef-timegroup>
208
+ <div class="mt-4 h-[60px] bg-gray-900 rounded-lg overflow-auto">
209
+ <ef-thumbnail-strip target="comp-thumbs" thumbnail-height="60"></ef-thumbnail-strip>
210
+ </div>
211
+ ```
212
+ <!-- /html-only -->
213
+ <!-- react-only -->
214
+ ## Target Video Element
215
+
216
+ Generate thumbnails for a specific video:
217
+
218
+ ```tsx
219
+ import { ThumbnailStrip, Video } from "@editframe/react";
220
+
221
+ <div className="space-y-2">
222
+ <div className="h-16 bg-gray-900 rounded">
223
+ <ThumbnailStrip
224
+ target="main-video"
225
+ thumbnailHeight={48}
226
+ thumbnailSpacingPx={64}
227
+ />
228
+ </div>
229
+
230
+ <Video
231
+ id="main-video"
232
+ src="/video.mp4"
233
+ className="w-full aspect-video"
234
+ />
235
+ </div>
236
+ ```
237
+
238
+ ## Target Timegroup
239
+
240
+ Generate thumbnails for a composition:
241
+
242
+ ```tsx
243
+ import { ThumbnailStrip, Timegroup, Video, Text } from "@editframe/react";
244
+
245
+ <div className="h-12 bg-gray-900">
246
+ <ThumbnailStrip target="composition" />
247
+ </div>
248
+
249
+ <Timegroup id="composition" mode="contain" className="w-[1920px] h-[1080px]">
250
+ <Video src="/background.mp4" className="size-full" />
251
+ <Text className="absolute top-20 left-20 text-6xl text-white">
252
+ Title
253
+ </Text>
254
+ </Timegroup>
255
+ ```
256
+ <!-- /react-only -->
257
+
258
+ ## Custom Zoom
259
+
260
+ Control thumbnail density:
261
+
262
+ <!-- html-only -->
263
+ For standalone use, provide explicit `pixels-per-ms` attribute.
264
+ <!-- /html-only -->
265
+ <!-- react-only -->
266
+ ```tsx
267
+ import { useState } from "react";
268
+ import { ThumbnailStrip, Video } from "@editframe/react";
269
+
270
+ export const ZoomableThumbnails = () => {
271
+ const [zoom, setZoom] = useState(0.04);
272
+
273
+ return (
274
+ <div>
275
+ <input
276
+ type="range"
277
+ min="0.01"
278
+ max="0.2"
279
+ step="0.01"
280
+ value={zoom}
281
+ onChange={(e) => setZoom(parseFloat(e.target.value))}
282
+ className="w-full mb-2"
283
+ />
284
+
285
+ <div className="h-12 bg-gray-900">
286
+ <ThumbnailStrip
287
+ target="video-1"
288
+ pixelsPerMs={zoom}
289
+ />
290
+ </div>
291
+
292
+ <Video id="video-1" src="/video.mp4" />
293
+ </div>
294
+ );
295
+ };
296
+ ```
297
+ <!-- /react-only -->
298
+
299
+ ## Intrinsic Duration
300
+
301
+ <!-- html-only -->
302
+ By default, thumbnails show the trimmed region of video:
303
+ - `trimstart="2s"` means thumbnails start at 2 seconds into source
304
+ - Duration matches effective video duration
305
+
306
+ Set `use-intrinsic-duration` to show entire source file regardless of trim.
307
+ <!-- /html-only -->
308
+ <!-- react-only -->
309
+ Use source video duration instead of trimmed duration:
310
+
311
+ ```tsx
312
+ import { ThumbnailStrip, Video } from "@editframe/react";
313
+
314
+ <ThumbnailStrip
315
+ target="trimmed-video"
316
+ useIntrinsicDuration
317
+ className="h-12"
318
+ />
319
+
320
+ <Video
321
+ id="trimmed-video"
322
+ src="/video.mp4"
323
+ trimStart="5s"
324
+ trimEnd="10s"
325
+ />
326
+ ```
327
+ <!-- /react-only -->
328
+
329
+ <!-- react-only -->
330
+ ## With Direct Element Reference
331
+
332
+ Pass element reference directly:
333
+
334
+ ```tsx
335
+ import { useRef, useEffect, useState } from "react";
336
+ import { ThumbnailStrip, Video } from "@editframe/react";
337
+
338
+ export const RefBasedThumbnails = () => {
339
+ const videoRef = useRef<HTMLVideoElement>(null);
340
+ const [videoElement, setVideoElement] = useState<Element | null>(null);
341
+
342
+ useEffect(() => {
343
+ if (videoRef.current) {
344
+ setVideoElement(videoRef.current);
345
+ }
346
+ }, []);
347
+
348
+ return (
349
+ <div>
350
+ <div className="h-12 bg-gray-900 mb-2">
351
+ <ThumbnailStrip targetElement={videoElement} />
352
+ </div>
353
+
354
+ <Video ref={videoRef} src="/video.mp4" />
355
+ </div>
356
+ );
357
+ };
358
+ ```
359
+
360
+ ## Styled Thumbnails
361
+
362
+ Customize appearance with CSS variables:
363
+
364
+ ```tsx
365
+ <ThumbnailStrip
366
+ target="video-1"
367
+ className="h-16 bg-gradient-to-b from-gray-900 to-gray-800"
368
+ style={{
369
+ '--ef-thumbnail-gap': '4px',
370
+ '--ef-color-bg-inset': 'rgba(100, 100, 100, 0.3)',
371
+ '--ef-color-border-subtle': 'rgba(150, 150, 150, 0.5)',
372
+ } as React.CSSProperties}
373
+ />
374
+ ```
375
+ <!-- /react-only -->
376
+
377
+ ## Features
378
+
379
+ **Lazy loading** — Only generates thumbnails for visible region as you scroll.
380
+
381
+ **Viewport virtualization** — Efficiently handles timelines of any length.
382
+
383
+ **Smart caching** — Caches generated thumbnails and reuses them when possible.
384
+
385
+ **Adaptive spacing** — Maintains consistent visual spacing at all zoom levels.
386
+
387
+ **Frame-accurate** — Aligns thumbnails to frame boundaries for precision.
388
+
389
+ **Video support** — Extracts thumbnails directly from video files.
390
+
391
+ **Timegroup support** — Renders composition snapshots with all layers.
392
+
393
+ **Automatic aspect ratio** — Thumbnails match target element dimensions.
394
+
395
+ ## Target Types
396
+
397
+ <!-- html-only -->
398
+ **Video elements** (`ef-video`):
399
+ <!-- /html-only -->
400
+ <!-- react-only -->
401
+ **Video elements**:
402
+ <!-- /react-only -->
403
+ - Extracts frames directly from video file
404
+ - Fast batch extraction
405
+ - Respects video trim settings
406
+
407
+ <!-- html-only -->
408
+ **Root timegroups** (top-level `ef-timegroup`):
409
+ <!-- /html-only -->
410
+ <!-- react-only -->
411
+ **Root timegroups**:
412
+ <!-- /react-only -->
413
+ - Renders entire composition to thumbnails
414
+ - Includes all layers (video, text, images)
415
+ - Lower resolution rendering for performance
416
+
417
+ ## How It Works
418
+
419
+ The thumbnail strip uses different strategies based on target type:
420
+
421
+ **For videos:**
422
+ 1. Uses `ThumbnailExtractor` for batch frame extraction
423
+ 2. Decodes video to access raw frames
424
+ 3. Caches extracted frames for reuse
425
+ 4. Supports source time translation for trimmed videos
426
+
427
+ **For timegroups:**
428
+ 1. Creates off-screen render clone of composition
429
+ 2. Seeks to each timestamp and captures canvas
430
+ 3. Generates at low resolution (0.25x scale) for performance
431
+ 4. Reuses clone for subsequent thumbnail batches
432
+
433
+ ## Thumbnail Positioning
434
+
435
+ Thumbnails use a stable grid system:
436
+ - Grid is anchored in timeline space (not viewport space)
437
+ - Scrolls naturally with timeline content
438
+ - On zoom, grid snaps to keep thumbnails near viewport edges
439
+ - Prevents visual slipping during zoom operations
440
+
441
+ Spacing between thumbnails is consistent at all zoom levels, but more thumbnails become visible as you zoom in.
442
+
443
+ ## Performance Optimization
444
+
445
+ **Batch extraction** — Videos extract multiple frames in one pass.
446
+
447
+ **Viewport culling** — Only renders thumbnails in visible area plus buffer.
448
+
449
+ **Canvas pooling** — Reuses canvas elements across renders.
450
+
451
+ **Abort on scroll** — Cancels in-flight captures when viewport changes.
452
+
453
+ **Nearest neighbor** — Shows nearby cached thumbnails while loading exact frame.
454
+
455
+ <!-- react-only -->
456
+ ```tsx
457
+ {/* Efficiently handles long videos */}
458
+ <ThumbnailStrip
459
+ target="long-video"
460
+ thumbnailSpacingPx={100}
461
+ className="h-12"
462
+ />
463
+
464
+ <Video id="long-video" src="/10-minute-video.mp4" />
465
+ ```
466
+ <!-- /react-only -->
467
+
468
+ ## Trimmed Videos
469
+
470
+ <!-- html-only -->
471
+ By default, thumbnails show the trimmed region of video:
472
+ - `trimstart="2s"` means thumbnails start at 2 seconds into source
473
+ - Duration matches effective video duration
474
+
475
+ Set `use-intrinsic-duration` to show entire source file regardless of trim.
476
+ <!-- /html-only -->
477
+ <!-- react-only -->
478
+ ThumbnailStrip respects video trim settings by default. Use `useIntrinsicDuration` to show the full source file regardless of trim.
479
+ <!-- /react-only -->
480
+
481
+ ## Timeline Context
482
+
483
+ When used inside a timeline, the strip automatically:
484
+ - Reads zoom level from timeline context
485
+ - Synchronizes with timeline scroll position
486
+ - Updates viewport window as timeline scrolls
487
+ - Respects timeline state without explicit binding
488
+
489
+ <!-- html-only -->
490
+ For standalone use, provide explicit `pixels-per-ms` attribute.
491
+ <!-- /html-only -->
492
+ <!-- react-only -->
493
+ For standalone use, provide explicit `pixelsPerMs` prop.
494
+ <!-- /react-only -->
495
+
496
+ ## CSS Custom Properties
497
+
498
+ Customize appearance:
499
+
500
+ ```css
501
+ ef-thumbnail-strip {
502
+ --ef-thumbnail-gap: 2px;
503
+ --ef-color-bg-inset: rgba(100, 100, 100, 0.3);
504
+ --ef-color-border-subtle: rgba(150, 150, 150, 0.5);
505
+ --ef-color-error: #ef4444;
506
+ }
507
+ ```
508
+
509
+ ## Error States
510
+
511
+ The component shows error messages for:
512
+ - No target specified
513
+ - Target element not found
514
+ - Invalid target type (must be video or root timegroup)
515
+
516
+ <!-- html-only -->
517
+ Example error: "Invalid target: 'ef-text' must be ef-video or root ef-timegroup"
518
+ <!-- /html-only -->
519
+ <!-- react-only -->
520
+ ```tsx
521
+ <div className="space-y-2">
522
+ {/* No target specified */}
523
+ <ThumbnailStrip className="h-12 bg-gray-900" />
524
+
525
+ {/* Invalid target type */}
526
+ <ThumbnailStrip target="not-a-video" className="h-12 bg-gray-900" />
527
+ </div>
528
+ ```
529
+ <!-- /react-only -->
530
+
531
+ <!-- html-only -->
532
+ ## Usage in Timeline
533
+
534
+ Thumbnails are automatically rendered in video and timegroup tracks when inside `ef-timeline`. The timeline manages thumbnail strip lifecycle and positioning.
535
+
536
+ For custom track implementations, use `ef-thumbnail-strip` directly and manage zoom/scroll context.
537
+ <!-- /html-only -->
538
+
539
+ <!-- react-only -->
540
+ ## Multi-Video Timeline
541
+
542
+ Each video track gets its own thumbnail strip:
543
+
544
+ ```tsx
545
+ import { Timeline, Timegroup, Video } from "@editframe/react";
546
+
547
+ <Timeline className="w-full h-96" />
548
+
549
+ <Timegroup mode="contain" className="w-[1920px] h-[1080px]">
550
+ {/* Each video appears as a separate track with thumbnails */}
551
+ <Video src="/video1.mp4" className="absolute top-0 left-0 w-full h-1/2" />
552
+ <Video src="/video2.mp4" className="absolute bottom-0 left-0 w-full h-1/2" />
553
+ </Timegroup>
554
+ ```
555
+
556
+ ## Notes
557
+
558
+ - ThumbnailStrip targets either `ef-video` or root `ef-timegroup` elements
559
+ - Automatically generates thumbnails for visible viewport area
560
+ - Uses efficient batch extraction for videos
561
+ - Canvas rendering for timegroups at low resolution
562
+ - Thumbnails align to frame boundaries for accuracy
563
+ - Spacing adapts to zoom level
564
+ - Shows placeholder while thumbnails load
565
+ - Cache persists for smooth scrubbing
566
+ <!-- /react-only -->