@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,259 @@
1
+ ---
2
+ title: Getting Started
3
+ description: Build your first HTML video composition with Editframe Elements — install the package, place elements, and render to MP4.
4
+ type: tutorial
5
+ nav:
6
+ parent: "Quick Start"
7
+ priority: 1
8
+ track: "getting-started"
9
+ track_step: 1
10
+ track_title: "Your First Composition"
11
+ next_steps: ["video"]
12
+ react:
13
+ generate: true
14
+ componentName: "Getting Started"
15
+ importPath: "@editframe/react"
16
+ nav:
17
+ parent: "Quick Start"
18
+ priority: 0
19
+ ---
20
+
21
+ # Getting Started
22
+
23
+ <!-- html-only -->
24
+ Build your first video composition with Editframe Elements.
25
+
26
+ > **Note:** Need a project? Run `npm create @editframe -- html -d my-project -y` — see the `editframe-create` skill.
27
+ <!-- /html-only -->
28
+ <!-- react-only -->
29
+ Build your first video composition with React.
30
+
31
+ > **Note:** Need a project? Run `npm create @editframe -- react -d my-project -y` — see the `editframe-create` skill.
32
+ <!-- /react-only -->
33
+
34
+ ## Composition Structure
35
+
36
+ <!-- html-only -->
37
+ Every composition starts with an `ef-timegroup` root:
38
+
39
+ ```html
40
+ <ef-timegroup mode="sequence" class="w-[1920px] h-[1080px] bg-black">
41
+ <!-- scenes go here -->
42
+ </ef-timegroup>
43
+ ```
44
+
45
+ The `mode` controls how child elements are timed.
46
+
47
+ ### Step 1: Start with Motion
48
+
49
+ The first thing a viewer sees should move. Add an animated title — every word slides up in sequence using `split="word"` and `--ef-word-index`:
50
+
51
+ ```html live
52
+ <ef-timegroup mode="fixed" duration="3s" class="w-[720px] h-[400px] bg-black flex items-center justify-center">
53
+ <ef-text
54
+ split="word"
55
+ class="text-white text-5xl font-bold"
56
+ style="animation: 0.6s slide-up both; animation-delay: calc(var(--ef-word-index) * 100ms)"
57
+ >Hello Editframe</ef-text>
58
+ </ef-timegroup>
59
+ <style>
60
+ @keyframes slide-up {
61
+ from { transform: translateY(30px); opacity: 0; }
62
+ to { transform: translateY(0); opacity: 1; }
63
+ }
64
+ </style>
65
+ ```
66
+
67
+ `split="word"` breaks the text into individual word elements. Each gets a `--ef-word-index` CSS variable so you can stagger delays. The animation runs relative to the scene timeline — it's fully scrubbable.
68
+
69
+ ### Step 2: Add a Video Background
70
+
71
+ Place the title inside a `contain` timegroup with a video beneath it. The timegroup holds both layers simultaneously:
72
+
73
+ ```html live
74
+ <ef-timegroup mode="contain" class="w-[720px] h-[400px] bg-black">
75
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" class="absolute inset-0 size-full object-cover"></ef-video>
76
+ <div class="absolute inset-0 bg-black/50"></div>
77
+ <ef-text
78
+ split="word"
79
+ class="absolute top-8 left-8 text-white text-4xl font-bold"
80
+ style="animation: 0.6s slide-up both; animation-delay: calc(var(--ef-word-index) * 100ms)"
81
+ >Hello Editframe</ef-text>
82
+ </ef-timegroup>
83
+ <style>
84
+ @keyframes slide-up {
85
+ from { transform: translateY(30px); opacity: 0; }
86
+ to { transform: translateY(0); opacity: 1; }
87
+ }
88
+ </style>
89
+ ```
90
+
91
+ ### Step 3: Chain Scenes with a Transition
92
+
93
+ Use `mode="sequence"` with `overlap` to crossfade between scenes. Each scene fades out while the next fades in:
94
+
95
+ ```html live
96
+ <ef-timegroup mode="sequence" overlap="1s" class="w-[720px] h-[400px] bg-black">
97
+ <ef-timegroup mode="contain" class="absolute w-full h-full" style="animation: 1s fade-out var(--ef-transition-out-start) both">
98
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" sourcein="0s" sourceout="4s" class="absolute inset-0 size-full object-cover"></ef-video>
99
+ <ef-text
100
+ split="word"
101
+ class="absolute top-8 left-8 text-white text-4xl font-bold"
102
+ style="animation: 0.6s slide-up both; animation-delay: calc(var(--ef-word-index) * 100ms)"
103
+ >Scene One</ef-text>
104
+ </ef-timegroup>
105
+ <ef-timegroup mode="contain" class="absolute w-full h-full" style="animation: 1s fade-in both">
106
+ <ef-video src="https://assets.editframe.com/bars-n-tone.mp4" sourcein="5s" sourceout="9s" class="absolute inset-0 size-full object-cover"></ef-video>
107
+ <ef-text
108
+ split="word"
109
+ class="absolute top-8 left-8 text-white text-4xl font-bold"
110
+ style="animation: 0.6s slide-up 0.3s both; animation-delay: calc(0.3s + var(--ef-word-index) * 100ms)"
111
+ >Scene Two</ef-text>
112
+ </ef-timegroup>
113
+ </ef-timegroup>
114
+ <style>
115
+ @keyframes slide-up {
116
+ from { transform: translateY(30px); opacity: 0; }
117
+ to { transform: translateY(0); opacity: 1; }
118
+ }
119
+ @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
120
+ @keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
121
+ </style>
122
+ ```
123
+
124
+ `--ef-transition-out-start` is a CSS variable Editframe sets automatically — it's the point in time when the overlap begins, so the fade-out starts exactly at the transition point.
125
+
126
+ <!-- /html-only -->
127
+ <!-- react-only -->
128
+ ## Motion-First Composition
129
+
130
+ The first thing a viewer sees should move. This example animates a title word-by-word using `split="word"` and `--ef-word-index`:
131
+
132
+ ```tsx
133
+ import { Timegroup, Text } from "@editframe/react";
134
+
135
+ export const Video = () => {
136
+ return (
137
+ <Timegroup mode="fixed" duration="3s" className="w-[1920px] h-[1080px] bg-black flex items-center justify-center">
138
+ <Text
139
+ split="word"
140
+ className="text-white text-7xl font-bold"
141
+ style={{
142
+ animation: "0.6s slide-up both",
143
+ animationDelay: "calc(var(--ef-word-index) * 100ms)"
144
+ }}
145
+ >
146
+ Hello Editframe
147
+ </Text>
148
+ </Timegroup>
149
+ );
150
+ };
151
+ ```
152
+
153
+ ```css
154
+ @keyframes slide-up {
155
+ from { transform: translateY(30px); opacity: 0; }
156
+ to { transform: translateY(0); opacity: 1; }
157
+ }
158
+ ```
159
+
160
+ Wrap it with `TimelineRoot` in `src/main.tsx`:
161
+
162
+ ```tsx
163
+ import React from "react";
164
+ import ReactDOM from "react-dom/client";
165
+ import { TimelineRoot } from "@editframe/react";
166
+ import { Video } from "./Video";
167
+ import "@editframe/elements/styles.css";
168
+
169
+ const root = document.getElementById("root");
170
+ if (!root) throw new Error("Root element not found");
171
+
172
+ ReactDOM.createRoot(root).render(
173
+ <TimelineRoot id="root" component={Video} />
174
+ );
175
+ ```
176
+
177
+ **Important**: `TimelineRoot` is required for rendering. See [timeline-root.md](references/timeline-root.md).
178
+
179
+ ## Add a Video Background
180
+
181
+ ```tsx
182
+ import { Timegroup, Video, Text } from "@editframe/react";
183
+
184
+ export const MyVideo = () => (
185
+ <Timegroup mode="contain" className="w-[1920px] h-[1080px] bg-black">
186
+ <Video src="/assets/background.mp4" className="absolute inset-0 size-full object-cover" />
187
+ <div className="absolute inset-0 bg-black/50" />
188
+ <Text
189
+ split="word"
190
+ className="absolute top-16 left-16 text-white text-6xl font-bold"
191
+ style={{
192
+ animation: "0.6s slide-up both",
193
+ animationDelay: "calc(var(--ef-word-index) * 100ms)"
194
+ }}
195
+ >
196
+ Opening Title
197
+ </Text>
198
+ </Timegroup>
199
+ );
200
+ ```
201
+
202
+ ## Chain Scenes with a Transition
203
+
204
+ ```tsx
205
+ import { Timegroup, Video, Text, Audio } from "@editframe/react";
206
+
207
+ export const VideoComposition = () => (
208
+ <Timegroup mode="sequence" overlap="1s" className="w-[1920px] h-[1080px]">
209
+ <Timegroup
210
+ mode="contain"
211
+ className="absolute w-full h-full"
212
+ style={{ animation: "1s fade-out var(--ef-transition-out-start) both" }}
213
+ >
214
+ <Video src="/assets/intro.mp4" className="size-full object-cover" />
215
+ <Text
216
+ split="word"
217
+ className="absolute top-16 left-16 text-white text-5xl font-bold"
218
+ style={{ animation: "0.6s slide-up both", animationDelay: "calc(var(--ef-word-index) * 100ms)" }}
219
+ >
220
+ Scene One
221
+ </Text>
222
+ </Timegroup>
223
+ <Timegroup
224
+ mode="contain"
225
+ className="absolute w-full h-full"
226
+ style={{ animation: "1s fade-in both" }}
227
+ >
228
+ <Video src="/assets/main.mp4" className="size-full object-cover" />
229
+ <Audio src="/assets/music.mp3" volume={0.3} />
230
+ </Timegroup>
231
+ </Timegroup>
232
+ );
233
+ ```
234
+
235
+ ```css
236
+ @keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
237
+ @keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }
238
+ ```
239
+ <!-- /react-only -->
240
+
241
+ ## Assets
242
+
243
+ Place media files in `src/assets/` and reference with `/assets/filename`:
244
+
245
+ <!-- html-only -->
246
+ ```html
247
+ <ef-video src="/assets/video.mp4"></ef-video>
248
+ <ef-audio src="/assets/music.mp3"></ef-audio>
249
+ <ef-image src="/assets/logo.png"></ef-image>
250
+ ```
251
+ <!-- /html-only -->
252
+
253
+ ## Render to Video
254
+
255
+ ```bash
256
+ npx editframe render -o output.mp4
257
+ ```
258
+
259
+ See the `editframe-cli` skill for full render options.
@@ -0,0 +1,234 @@
1
+ ---
2
+ title: Hooks
3
+ description: React hooks for reading current playback time, pan/zoom transform, and media loading state from within composition components.
4
+ type: reference
5
+ nav:
6
+ parent: "React"
7
+ priority: 11
8
+ related: ["timeline-root", "timegroup"]
9
+ ---
10
+
11
+ # Hooks
12
+
13
+ React hooks for accessing timing information and transforms.
14
+
15
+ ## useTimingInfo
16
+
17
+ Access timing information for the current element.
18
+
19
+ **Important**: This hook requires `TimelineRoot` to work correctly in render clones. See [timeline-root.md](references/timeline-root.md).
20
+
21
+ ### Import
22
+
23
+ ```tsx
24
+ import { useTimingInfo } from "@editframe/react";
25
+ ```
26
+
27
+ ### Returns
28
+
29
+ ```tsx
30
+ {
31
+ ref: RefObject<HTMLElement>; // Attach to your component
32
+ ownCurrentTimeMs: number; // Current time within this element
33
+ durationMs: number; // Total duration of element
34
+ percentComplete: number; // Progress (0-1)
35
+ isActive: boolean; // Is currently playing
36
+ startTimeMs: number; // Start time in parent
37
+ endTimeMs: number; // End time in parent
38
+ }
39
+ ```
40
+
41
+ ### Basic Usage
42
+
43
+ ```tsx
44
+ import { Timegroup, useTimingInfo } from "@editframe/react";
45
+
46
+ const AnimatedScene = () => {
47
+ const { ref, percentComplete, ownCurrentTimeMs } = useTimingInfo();
48
+
49
+ return (
50
+ <Timegroup ref={ref} mode="fixed" duration="5s" className="absolute w-full h-full">
51
+ <div style={{ opacity: percentComplete }}>
52
+ Fading in... {(ownCurrentTimeMs / 1000).toFixed(2)}s
53
+ </div>
54
+ </Timegroup>
55
+ );
56
+ };
57
+ ```
58
+
59
+ ### Fade In/Out
60
+
61
+ ```tsx
62
+ const FadeInOut = ({ children }: { children: React.ReactNode }) => {
63
+ const { ref, percentComplete } = useTimingInfo();
64
+
65
+ // Fade in first half, fade out second half
66
+ const opacity = percentComplete < 0.5
67
+ ? percentComplete * 2
68
+ : (1 - percentComplete) * 2;
69
+
70
+ return (
71
+ <Timegroup ref={ref} mode="fixed" duration="5s" className="absolute w-full h-full">
72
+ <div style={{ opacity }}>
73
+ {children}
74
+ </div>
75
+ </Timegroup>
76
+ );
77
+ };
78
+ ```
79
+
80
+ ### Scale Animation
81
+
82
+ ```tsx
83
+ const ScaleIn = ({ children }: { children: React.ReactNode }) => {
84
+ const { ref, percentComplete } = useTimingInfo();
85
+
86
+ return (
87
+ <Timegroup ref={ref} mode="fixed" duration="3s" className="absolute w-full h-full flex items-center justify-center">
88
+ <div style={{ transform: `scale(${percentComplete})` }}>
89
+ {children}
90
+ </div>
91
+ </Timegroup>
92
+ );
93
+ };
94
+ ```
95
+
96
+ ### Progress Bar
97
+
98
+ ```tsx
99
+ const SceneWithProgress = () => {
100
+ const { ref, percentComplete, ownCurrentTimeMs, durationMs } = useTimingInfo();
101
+
102
+ return (
103
+ <Timegroup ref={ref} mode="fixed" duration="10s" className="absolute w-full h-full bg-black flex flex-col items-center justify-center">
104
+ <h1 className="text-white text-4xl mb-4">Scene Content</h1>
105
+
106
+ <div className="w-96 bg-gray-700 h-2 rounded">
107
+ <div
108
+ className="bg-blue-500 h-full rounded transition-all"
109
+ style={{ width: `${percentComplete * 100}%` }}
110
+ />
111
+ </div>
112
+
113
+ <p className="text-white mt-2">
114
+ {(ownCurrentTimeMs / 1000).toFixed(1)}s / {(durationMs / 1000).toFixed(1)}s
115
+ </p>
116
+ </Timegroup>
117
+ );
118
+ };
119
+ ```
120
+
121
+ ### Conditional Rendering
122
+
123
+ ```tsx
124
+ const TimedReveal = () => {
125
+ const { ref, ownCurrentTimeMs } = useTimingInfo();
126
+
127
+ return (
128
+ <Timegroup ref={ref} mode="fixed" duration="10s" className="absolute w-full h-full">
129
+ {ownCurrentTimeMs > 2000 && (
130
+ <Text duration="8s" className="text-white text-4xl">
131
+ Appears after 2 seconds
132
+ </Text>
133
+ )}
134
+
135
+ {ownCurrentTimeMs > 5000 && (
136
+ <Image src="/assets/logo.png" className="absolute top-8 right-8 w-32" />
137
+ )}
138
+ </Timegroup>
139
+ );
140
+ };
141
+ ```
142
+
143
+ ### Complex Animation
144
+
145
+ ```tsx
146
+ const ComplexAnimation = ({ children }: { children: React.ReactNode }) => {
147
+ const { ref, percentComplete } = useTimingInfo();
148
+
149
+ // Different animations per stage
150
+ let transform = '';
151
+ let opacity = 1;
152
+
153
+ if (percentComplete < 0.25) {
154
+ // Slide in from left
155
+ const progress = percentComplete * 4;
156
+ transform = `translateX(${-100 + progress * 100}%)`;
157
+ } else if (percentComplete < 0.75) {
158
+ // Stay centered
159
+ transform = 'translateX(0)';
160
+ } else {
161
+ // Slide out to right
162
+ const progress = (percentComplete - 0.75) * 4;
163
+ transform = `translateX(${progress * 100}%)`;
164
+ opacity = 1 - progress;
165
+ }
166
+
167
+ return (
168
+ <Timegroup ref={ref} mode="fixed" duration="8s" className="absolute w-full h-full flex items-center justify-center">
169
+ <div style={{ transform, opacity }}>
170
+ {children}
171
+ </div>
172
+ </Timegroup>
173
+ );
174
+ };
175
+ ```
176
+
177
+ ## usePanZoomTransform
178
+
179
+ Access pan/zoom transform values for synchronized UI elements.
180
+
181
+ ### Import
182
+
183
+ ```tsx
184
+ import { usePanZoomTransform } from "@editframe/react";
185
+ ```
186
+
187
+ ### Returns
188
+
189
+ ```tsx
190
+ {
191
+ x: number; // Pan X offset
192
+ y: number; // Pan Y offset
193
+ scale: number; // Zoom scale
194
+ }
195
+ ```
196
+
197
+ ### Basic Usage
198
+
199
+ ```tsx
200
+ import { PanZoom, usePanZoomTransform } from "@editframe/react";
201
+
202
+ const SyncedOverlay = () => {
203
+ const { x, y, scale } = usePanZoomTransform();
204
+
205
+ return (
206
+ <div
207
+ className="absolute top-0 left-0 pointer-events-none"
208
+ style={{
209
+ transform: `translate(${x}px, ${y}px) scale(${scale})`,
210
+ }}
211
+ >
212
+ <div className="text-white text-2xl">
213
+ Follows pan/zoom
214
+ </div>
215
+ </div>
216
+ );
217
+ };
218
+ ```
219
+
220
+ ### Display Transform Info
221
+
222
+ ```tsx
223
+ const TransformInfo = () => {
224
+ const { x, y, scale } = usePanZoomTransform();
225
+
226
+ return (
227
+ <div className="absolute top-4 right-4 bg-black/80 text-white p-2 rounded text-sm font-mono">
228
+ <div>X: {x.toFixed(0)}px</div>
229
+ <div>Y: {y.toFixed(0)}px</div>
230
+ <div>Scale: {scale.toFixed(2)}x</div>
231
+ </div>
232
+ );
233
+ };
234
+ ```