@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.
- package/README.md +11 -0
- package/dist/index.js +16 -28
- package/dist/index.js.map +1 -1
- package/dist/skills/editframe-brand-video-generator/README.md +155 -0
- package/dist/skills/editframe-brand-video-generator/SKILL.md +207 -0
- package/dist/skills/editframe-brand-video-generator/references/brand-examples.md +178 -0
- package/dist/skills/editframe-brand-video-generator/references/color-psychology.md +227 -0
- package/dist/skills/editframe-brand-video-generator/references/composition-patterns.md +383 -0
- package/dist/skills/editframe-brand-video-generator/references/editing.md +66 -0
- package/dist/skills/editframe-brand-video-generator/references/emotional-arcs.md +496 -0
- package/dist/skills/editframe-brand-video-generator/references/genre-selection.md +135 -0
- package/dist/skills/editframe-brand-video-generator/references/transition-styles.md +611 -0
- package/dist/skills/editframe-brand-video-generator/references/typography-personalities.md +326 -0
- package/dist/skills/editframe-brand-video-generator/references/video-archetypes.md +86 -0
- package/dist/skills/editframe-brand-video-generator/references/video-fundamentals.md +169 -0
- package/dist/skills/editframe-brand-video-generator/references/visual-metaphors.md +50 -0
- package/dist/skills/editframe-composition/SKILL.md +169 -0
- package/dist/skills/editframe-composition/references/audio.md +483 -0
- package/dist/skills/editframe-composition/references/captions.md +844 -0
- package/dist/skills/editframe-composition/references/composition-model.md +73 -0
- package/dist/skills/editframe-composition/references/configuration.md +403 -0
- package/dist/skills/editframe-composition/references/css-parts.md +105 -0
- package/dist/skills/editframe-composition/references/css-variables.md +640 -0
- package/dist/skills/editframe-composition/references/entry-points.md +810 -0
- package/dist/skills/editframe-composition/references/events.md +499 -0
- package/dist/skills/editframe-composition/references/getting-started.md +259 -0
- package/dist/skills/editframe-composition/references/hooks.md +234 -0
- package/dist/skills/editframe-composition/references/image.md +241 -0
- package/dist/skills/editframe-composition/references/r3f.md +580 -0
- package/dist/skills/editframe-composition/references/render-api.md +484 -0
- package/dist/skills/editframe-composition/references/render-strategies.md +119 -0
- package/dist/skills/editframe-composition/references/render-to-video.md +1101 -0
- package/dist/skills/editframe-composition/references/scripting.md +606 -0
- package/dist/skills/editframe-composition/references/sequencing.md +116 -0
- package/dist/skills/editframe-composition/references/server-rendering.md +753 -0
- package/dist/skills/editframe-composition/references/surface.md +329 -0
- package/dist/skills/editframe-composition/references/text.md +627 -0
- package/dist/skills/editframe-composition/references/time-model.md +99 -0
- package/dist/skills/editframe-composition/references/timegroup-modes.md +102 -0
- package/dist/skills/editframe-composition/references/timegroup.md +457 -0
- package/dist/skills/editframe-composition/references/timeline-root.md +398 -0
- package/dist/skills/editframe-composition/references/transcription.md +47 -0
- package/dist/skills/editframe-composition/references/transitions.md +608 -0
- package/dist/skills/editframe-composition/references/use-media-info.md +357 -0
- package/dist/skills/editframe-composition/references/video.md +506 -0
- package/dist/skills/editframe-composition/references/waveform.md +327 -0
- package/dist/skills/editframe-editor-gui/SKILL.md +152 -0
- package/dist/skills/editframe-editor-gui/references/active-root-temporal.md +657 -0
- package/dist/skills/editframe-editor-gui/references/canvas.md +947 -0
- package/dist/skills/editframe-editor-gui/references/controls.md +366 -0
- package/dist/skills/editframe-editor-gui/references/dial.md +756 -0
- package/dist/skills/editframe-editor-gui/references/editor-toolkit.md +587 -0
- package/dist/skills/editframe-editor-gui/references/filmstrip.md +460 -0
- package/dist/skills/editframe-editor-gui/references/fit-scale.md +772 -0
- package/dist/skills/editframe-editor-gui/references/focus-overlay.md +561 -0
- package/dist/skills/editframe-editor-gui/references/hierarchy.md +544 -0
- package/dist/skills/editframe-editor-gui/references/overlay-item.md +634 -0
- package/dist/skills/editframe-editor-gui/references/overlay-layer.md +429 -0
- package/dist/skills/editframe-editor-gui/references/pan-zoom.md +568 -0
- package/dist/skills/editframe-editor-gui/references/pause.md +397 -0
- package/dist/skills/editframe-editor-gui/references/play.md +370 -0
- package/dist/skills/editframe-editor-gui/references/preview.md +391 -0
- package/dist/skills/editframe-editor-gui/references/resizable-box.md +749 -0
- package/dist/skills/editframe-editor-gui/references/scrubber.md +588 -0
- package/dist/skills/editframe-editor-gui/references/thumbnail-strip.md +566 -0
- package/dist/skills/editframe-editor-gui/references/time-display.md +492 -0
- package/dist/skills/editframe-editor-gui/references/timeline-ruler.md +489 -0
- package/dist/skills/editframe-editor-gui/references/timeline.md +604 -0
- package/dist/skills/editframe-editor-gui/references/toggle-loop.md +618 -0
- package/dist/skills/editframe-editor-gui/references/toggle-play.md +526 -0
- package/dist/skills/editframe-editor-gui/references/transform-handles.md +924 -0
- package/dist/skills/editframe-editor-gui/references/trim-handles.md +725 -0
- package/dist/skills/editframe-editor-gui/references/workbench.md +453 -0
- package/dist/skills/editframe-motion-design/SKILL.md +101 -0
- package/dist/skills/editframe-motion-design/references/0-editframe.md +299 -0
- package/dist/skills/editframe-motion-design/references/1-intent.md +201 -0
- package/dist/skills/editframe-motion-design/references/2-physics-model.md +405 -0
- package/dist/skills/editframe-motion-design/references/3-attention.md +350 -0
- package/dist/skills/editframe-motion-design/references/4-process.md +418 -0
- package/dist/skills/editframe-vite-plugin/SKILL.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/file-api.md +111 -0
- package/dist/skills/editframe-vite-plugin/references/getting-started.md +96 -0
- package/dist/skills/editframe-vite-plugin/references/jit-transcoding.md +91 -0
- package/dist/skills/editframe-vite-plugin/references/local-assets.md +75 -0
- package/dist/skills/editframe-vite-plugin/references/visual-testing.md +136 -0
- package/dist/skills/editframe-webhooks/SKILL.md +126 -0
- package/dist/skills/editframe-webhooks/references/events.md +382 -0
- package/dist/skills/editframe-webhooks/references/getting-started.md +232 -0
- package/dist/skills/editframe-webhooks/references/security.md +418 -0
- package/dist/skills/editframe-webhooks/references/testing.md +409 -0
- package/dist/skills/editframe-webhooks/references/troubleshooting.md +457 -0
- package/dist/templates/html/AGENTS.md +13 -0
- package/dist/templates/react/AGENTS.md +13 -0
- package/dist/utils.js +15 -16
- package/dist/utils.js.map +1 -1
- package/package.json +2 -2
- package/tsdown.config.ts +4 -0
- package/dist/detectAgent.js +0 -89
- package/dist/detectAgent.js.map +0 -1
|
@@ -0,0 +1,561 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Focus Overlay Element
|
|
3
|
+
description: Visual focus indicator that highlights and outlines the currently selected element in an Editframe composition preview.
|
|
4
|
+
type: reference
|
|
5
|
+
nav:
|
|
6
|
+
parent: "Preview & Canvas"
|
|
7
|
+
priority: 20
|
|
8
|
+
api:
|
|
9
|
+
properties:
|
|
10
|
+
- name: focusedElement
|
|
11
|
+
type: "HTMLElement | null"
|
|
12
|
+
description: Currently focused element (consumed from context)
|
|
13
|
+
react:
|
|
14
|
+
generate: true
|
|
15
|
+
componentName: FocusOverlay
|
|
16
|
+
importPath: "@editframe/react"
|
|
17
|
+
additionalProps:
|
|
18
|
+
- name: className
|
|
19
|
+
type: string
|
|
20
|
+
description: CSS classes for styling
|
|
21
|
+
nav:
|
|
22
|
+
parent: "Components / Overlay System"
|
|
23
|
+
priority: 55
|
|
24
|
+
related: ["preview", "overlay-layer"]
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
<!-- html-only -->
|
|
28
|
+
# ef-focus-overlay
|
|
29
|
+
<!-- /html-only -->
|
|
30
|
+
<!-- react-only -->
|
|
31
|
+
# FocusOverlay
|
|
32
|
+
<!-- /react-only -->
|
|
33
|
+
|
|
34
|
+
Visual indicator that highlights the focused element in a composition.
|
|
35
|
+
|
|
36
|
+
<!-- react-only -->
|
|
37
|
+
## Import
|
|
38
|
+
|
|
39
|
+
```tsx
|
|
40
|
+
import { FocusOverlay } from "@editframe/react";
|
|
41
|
+
```
|
|
42
|
+
<!-- /react-only -->
|
|
43
|
+
|
|
44
|
+
## Basic Usage
|
|
45
|
+
|
|
46
|
+
<!-- html-only -->
|
|
47
|
+
Display focus overlay in a preview:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<ef-preview target="composition">
|
|
51
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
52
|
+
</ef-preview>
|
|
53
|
+
|
|
54
|
+
<ef-timegroup id="composition">
|
|
55
|
+
<!-- Focus overlay tracks focused element -->
|
|
56
|
+
</ef-timegroup>
|
|
57
|
+
```
|
|
58
|
+
<!-- /html-only -->
|
|
59
|
+
<!-- react-only -->
|
|
60
|
+
```tsx
|
|
61
|
+
import { FocusOverlay, Preview, Timegroup, Video } from "@editframe/react";
|
|
62
|
+
|
|
63
|
+
export const App = () => {
|
|
64
|
+
return (
|
|
65
|
+
<div className="relative w-full h-screen">
|
|
66
|
+
<Preview className="w-full h-full">
|
|
67
|
+
<FocusOverlay className="absolute inset-0" />
|
|
68
|
+
</Preview>
|
|
69
|
+
|
|
70
|
+
<Timegroup mode="sequence" className="w-[1920px] h-[1080px]">
|
|
71
|
+
<Video src="/assets/video1.mp4" />
|
|
72
|
+
<Video src="/assets/video2.mp4" />
|
|
73
|
+
</Timegroup>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
<!-- /react-only -->
|
|
79
|
+
|
|
80
|
+
## Focus Context
|
|
81
|
+
|
|
82
|
+
<!-- html-only -->
|
|
83
|
+
Focus overlay consumes focused element from context:
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<ef-preview target="composition">
|
|
87
|
+
<!-- Preview provides focusedElement context -->
|
|
88
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
89
|
+
</ef-preview>
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
When an element receives focus, the overlay highlights it.
|
|
93
|
+
<!-- /html-only -->
|
|
94
|
+
<!-- react-only -->
|
|
95
|
+
FocusOverlay consumes the `focusedElement` from Preview context:
|
|
96
|
+
|
|
97
|
+
- Preview provides `focusedElementContext`
|
|
98
|
+
- FocusOverlay subscribes to context changes
|
|
99
|
+
- Automatically updates when focus changes
|
|
100
|
+
- No manual wiring required
|
|
101
|
+
<!-- /react-only -->
|
|
102
|
+
|
|
103
|
+
## Visual Appearance
|
|
104
|
+
|
|
105
|
+
Overlay displays:
|
|
106
|
+
|
|
107
|
+
- **Outline**: 2px solid border
|
|
108
|
+
- **Background**: Semi-transparent fill
|
|
109
|
+
- **Blend mode**: Multiply for visibility over content
|
|
110
|
+
- **Opacity**: 0.4
|
|
111
|
+
|
|
112
|
+
## Positioning
|
|
113
|
+
|
|
114
|
+
Overlay uses fixed positioning and tracks element bounds via `getBoundingClientRect()`:
|
|
115
|
+
|
|
116
|
+
```javascript
|
|
117
|
+
// Internal positioning (automatic)
|
|
118
|
+
const rect = focusedElement.getBoundingClientRect();
|
|
119
|
+
overlay.style.top = `${rect.top}px`;
|
|
120
|
+
overlay.style.left = `${rect.left}px`;
|
|
121
|
+
overlay.style.width = `${rect.width}px`;
|
|
122
|
+
overlay.style.height = `${rect.height}px`;
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Animation Frame Loop
|
|
126
|
+
|
|
127
|
+
Focus overlay updates position every frame:
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
// Internal RAF loop
|
|
131
|
+
const drawOverlay = () => {
|
|
132
|
+
if (focusedElement) {
|
|
133
|
+
updatePosition();
|
|
134
|
+
requestAnimationFrame(drawOverlay);
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Ensures overlay stays synchronized with moving or transforming elements.
|
|
140
|
+
|
|
141
|
+
## Visibility
|
|
142
|
+
|
|
143
|
+
Overlay automatically shows/hides based on focus state:
|
|
144
|
+
|
|
145
|
+
- **Focused element exists**: Overlay visible
|
|
146
|
+
- **No focused element**: Overlay hidden (`display: none`)
|
|
147
|
+
|
|
148
|
+
## Styling
|
|
149
|
+
|
|
150
|
+
Focus overlay uses CSS custom properties:
|
|
151
|
+
|
|
152
|
+
<!-- html-only -->
|
|
153
|
+
```css
|
|
154
|
+
ef-focus-overlay {
|
|
155
|
+
/* Outline color */
|
|
156
|
+
--ef-focus-overlay-color: #2196f3;
|
|
157
|
+
|
|
158
|
+
/* Background color */
|
|
159
|
+
--ef-focus-overlay-background: #2196f3;
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Override to match your design:
|
|
164
|
+
|
|
165
|
+
```html
|
|
166
|
+
<style>
|
|
167
|
+
ef-focus-overlay {
|
|
168
|
+
--ef-focus-overlay-color: #ff5722;
|
|
169
|
+
--ef-focus-overlay-background: #ff5722;
|
|
170
|
+
}
|
|
171
|
+
</style>
|
|
172
|
+
|
|
173
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
174
|
+
```
|
|
175
|
+
<!-- /html-only -->
|
|
176
|
+
<!-- react-only -->
|
|
177
|
+
```tsx
|
|
178
|
+
import { FocusOverlay } from "@editframe/react";
|
|
179
|
+
|
|
180
|
+
export const StyledFocusOverlay = () => {
|
|
181
|
+
return (
|
|
182
|
+
<Preview className="w-full h-full">
|
|
183
|
+
<FocusOverlay
|
|
184
|
+
className="absolute inset-0"
|
|
185
|
+
style={{
|
|
186
|
+
"--ef-focus-overlay-color": "#10b981",
|
|
187
|
+
"--ef-focus-overlay-background": "rgba(16, 185, 129, 0.2)"
|
|
188
|
+
} as React.CSSProperties}
|
|
189
|
+
/>
|
|
190
|
+
</Preview>
|
|
191
|
+
);
|
|
192
|
+
};
|
|
193
|
+
```
|
|
194
|
+
<!-- /react-only -->
|
|
195
|
+
|
|
196
|
+
<!-- html-only -->
|
|
197
|
+
## Programmatic Control
|
|
198
|
+
|
|
199
|
+
Set focused element via context provider:
|
|
200
|
+
|
|
201
|
+
```javascript
|
|
202
|
+
const preview = document.querySelector('ef-preview');
|
|
203
|
+
const element = document.getElementById('my-element');
|
|
204
|
+
|
|
205
|
+
// Focus is typically managed by preview
|
|
206
|
+
element.focus();
|
|
207
|
+
```
|
|
208
|
+
<!-- /html-only -->
|
|
209
|
+
|
|
210
|
+
## Pointer Events
|
|
211
|
+
|
|
212
|
+
Focus overlay has `pointer-events: none` to avoid blocking interaction with underlying elements.
|
|
213
|
+
|
|
214
|
+
<!-- html-only -->
|
|
215
|
+
## Use Cases
|
|
216
|
+
|
|
217
|
+
### Preview Focus Tracking
|
|
218
|
+
|
|
219
|
+
```html
|
|
220
|
+
<ef-preview target="composition">
|
|
221
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
222
|
+
</ef-preview>
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Overlay highlights the element that has browser focus.
|
|
226
|
+
|
|
227
|
+
### Custom Focus Indicators
|
|
228
|
+
|
|
229
|
+
```html
|
|
230
|
+
<style>
|
|
231
|
+
ef-focus-overlay {
|
|
232
|
+
--ef-focus-overlay-color: #00ff00;
|
|
233
|
+
--ef-focus-overlay-background: rgba(0, 255, 0, 0.2);
|
|
234
|
+
}
|
|
235
|
+
</style>
|
|
236
|
+
|
|
237
|
+
<ef-preview target="composition">
|
|
238
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
239
|
+
</ef-preview>
|
|
240
|
+
```
|
|
241
|
+
<!-- /html-only -->
|
|
242
|
+
|
|
243
|
+
<!-- react-only -->
|
|
244
|
+
## In Editor Layout
|
|
245
|
+
|
|
246
|
+
```tsx
|
|
247
|
+
import { FocusOverlay, Preview, Controls, Workbench } from "@editframe/react";
|
|
248
|
+
|
|
249
|
+
export const Editor = () => {
|
|
250
|
+
return (
|
|
251
|
+
<div className="h-screen flex flex-col">
|
|
252
|
+
{/* Preview with focus indicator */}
|
|
253
|
+
<div className="flex-1 relative">
|
|
254
|
+
<Preview className="w-full h-full">
|
|
255
|
+
<FocusOverlay className="absolute inset-0" />
|
|
256
|
+
</Preview>
|
|
257
|
+
</div>
|
|
258
|
+
|
|
259
|
+
{/* Controls */}
|
|
260
|
+
<div className="p-4">
|
|
261
|
+
<Controls className="w-full" />
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
{/* Timeline */}
|
|
265
|
+
<div className="h-64">
|
|
266
|
+
<Workbench />
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
);
|
|
270
|
+
};
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
## Multiple Preview Panes
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { FocusOverlay, Preview } from "@editframe/react";
|
|
277
|
+
|
|
278
|
+
export const SplitView = () => {
|
|
279
|
+
return (
|
|
280
|
+
<div className="grid grid-cols-2 gap-4 p-4">
|
|
281
|
+
{/* Main preview with focus */}
|
|
282
|
+
<div className="relative">
|
|
283
|
+
<h3 className="mb-2">Main View</h3>
|
|
284
|
+
<Preview className="w-full aspect-video">
|
|
285
|
+
<FocusOverlay className="absolute inset-0" />
|
|
286
|
+
</Preview>
|
|
287
|
+
</div>
|
|
288
|
+
|
|
289
|
+
{/* Secondary preview without focus overlay */}
|
|
290
|
+
<div className="relative">
|
|
291
|
+
<h3 className="mb-2">Reference View</h3>
|
|
292
|
+
<Preview className="w-full aspect-video" />
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
);
|
|
296
|
+
};
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Focus-Aware Editing
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
import { FocusOverlay, Preview, Timegroup, Video, Text } from "@editframe/react";
|
|
303
|
+
|
|
304
|
+
export const FocusAwareEditor = () => {
|
|
305
|
+
const [focusedElement, setFocusedElement] = useState<HTMLElement | null>(null);
|
|
306
|
+
|
|
307
|
+
return (
|
|
308
|
+
<div className="flex gap-4">
|
|
309
|
+
{/* Preview with focus overlay */}
|
|
310
|
+
<div className="flex-1 relative">
|
|
311
|
+
<Preview className="w-full aspect-video">
|
|
312
|
+
<FocusOverlay className="absolute inset-0" />
|
|
313
|
+
</Preview>
|
|
314
|
+
|
|
315
|
+
<Timegroup mode="fixed" duration="10s" className="w-[1920px] h-[1080px]">
|
|
316
|
+
<Video
|
|
317
|
+
id="bg-video"
|
|
318
|
+
src="/assets/background.mp4"
|
|
319
|
+
duration="10s"
|
|
320
|
+
className="size-full"
|
|
321
|
+
/>
|
|
322
|
+
<Text
|
|
323
|
+
id="title"
|
|
324
|
+
duration="5s"
|
|
325
|
+
className="absolute top-20 left-20 text-white text-4xl"
|
|
326
|
+
>
|
|
327
|
+
Title Text
|
|
328
|
+
</Text>
|
|
329
|
+
</Timegroup>
|
|
330
|
+
</div>
|
|
331
|
+
|
|
332
|
+
{/* Properties panel shows focused element info */}
|
|
333
|
+
<div className="w-64 p-4 bg-gray-100 rounded">
|
|
334
|
+
<h3 className="font-semibold mb-2">Focused Element</h3>
|
|
335
|
+
{focusedElement ? (
|
|
336
|
+
<div className="text-sm space-y-1">
|
|
337
|
+
<div>Tag: {focusedElement.tagName}</div>
|
|
338
|
+
<div>ID: {focusedElement.id || "(none)"}</div>
|
|
339
|
+
</div>
|
|
340
|
+
) : (
|
|
341
|
+
<div className="text-sm text-gray-500">No element focused</div>
|
|
342
|
+
)}
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
);
|
|
346
|
+
};
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Custom Focus Styles
|
|
350
|
+
|
|
351
|
+
```tsx
|
|
352
|
+
import { FocusOverlay } from "@editframe/react";
|
|
353
|
+
|
|
354
|
+
export const CustomFocusStyles = () => {
|
|
355
|
+
return (
|
|
356
|
+
<div className="space-y-4">
|
|
357
|
+
{/* Blue focus */}
|
|
358
|
+
<Preview className="w-full aspect-video">
|
|
359
|
+
<FocusOverlay
|
|
360
|
+
className="absolute inset-0"
|
|
361
|
+
style={{
|
|
362
|
+
"--ef-focus-overlay-color": "#3b82f6",
|
|
363
|
+
"--ef-focus-overlay-background": "rgba(59, 130, 246, 0.15)"
|
|
364
|
+
} as React.CSSProperties}
|
|
365
|
+
/>
|
|
366
|
+
</Preview>
|
|
367
|
+
|
|
368
|
+
{/* Green focus */}
|
|
369
|
+
<Preview className="w-full aspect-video">
|
|
370
|
+
<FocusOverlay
|
|
371
|
+
className="absolute inset-0"
|
|
372
|
+
style={{
|
|
373
|
+
"--ef-focus-overlay-color": "#10b981",
|
|
374
|
+
"--ef-focus-overlay-background": "rgba(16, 185, 129, 0.15)"
|
|
375
|
+
} as React.CSSProperties}
|
|
376
|
+
/>
|
|
377
|
+
</Preview>
|
|
378
|
+
|
|
379
|
+
{/* Red focus */}
|
|
380
|
+
<Preview className="w-full aspect-video">
|
|
381
|
+
<FocusOverlay
|
|
382
|
+
className="absolute inset-0"
|
|
383
|
+
style={{
|
|
384
|
+
"--ef-focus-overlay-color": "#ef4444",
|
|
385
|
+
"--ef-focus-overlay-background": "rgba(239, 68, 68, 0.15)"
|
|
386
|
+
} as React.CSSProperties}
|
|
387
|
+
/>
|
|
388
|
+
</Preview>
|
|
389
|
+
</div>
|
|
390
|
+
);
|
|
391
|
+
};
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Toggle Focus Overlay
|
|
395
|
+
|
|
396
|
+
```tsx
|
|
397
|
+
import { FocusOverlay, Preview } from "@editframe/react";
|
|
398
|
+
|
|
399
|
+
export const ToggleFocus = () => {
|
|
400
|
+
const [showFocus, setShowFocus] = useState(true);
|
|
401
|
+
|
|
402
|
+
return (
|
|
403
|
+
<div className="space-y-4">
|
|
404
|
+
<div className="flex items-center gap-2">
|
|
405
|
+
<input
|
|
406
|
+
type="checkbox"
|
|
407
|
+
checked={showFocus}
|
|
408
|
+
onChange={(e) => setShowFocus(e.target.checked)}
|
|
409
|
+
id="show-focus"
|
|
410
|
+
/>
|
|
411
|
+
<label htmlFor="show-focus">Show focus overlay</label>
|
|
412
|
+
</div>
|
|
413
|
+
|
|
414
|
+
<div className="relative">
|
|
415
|
+
<Preview className="w-full aspect-video">
|
|
416
|
+
{showFocus && <FocusOverlay className="absolute inset-0" />}
|
|
417
|
+
</Preview>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
);
|
|
421
|
+
};
|
|
422
|
+
```
|
|
423
|
+
<!-- /react-only -->
|
|
424
|
+
|
|
425
|
+
## Blend Mode
|
|
426
|
+
|
|
427
|
+
Overlay uses `mix-blend-mode: multiply` to ensure visibility over both light and dark content:
|
|
428
|
+
|
|
429
|
+
```css
|
|
430
|
+
.overlay {
|
|
431
|
+
mix-blend-mode: multiply;
|
|
432
|
+
opacity: 0.4;
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
This creates a darkening effect that's visible regardless of background color.
|
|
437
|
+
|
|
438
|
+
<!-- html-only -->
|
|
439
|
+
## Update Lifecycle
|
|
440
|
+
|
|
441
|
+
Overlay updates in three scenarios:
|
|
442
|
+
|
|
443
|
+
1. **connectedCallback**: Start RAF loop
|
|
444
|
+
2. **updated**: Redraw when focusedElement context changes
|
|
445
|
+
3. **disconnectedCallback**: Cancel RAF loop
|
|
446
|
+
<!-- /html-only -->
|
|
447
|
+
|
|
448
|
+
## Performance
|
|
449
|
+
|
|
450
|
+
Single RAF loop per overlay. RAF automatically pauses when no element is focused, resuming when focus changes.
|
|
451
|
+
|
|
452
|
+
## Comparison with Selection Overlay
|
|
453
|
+
|
|
454
|
+
**Focus overlay**:
|
|
455
|
+
- Tracks browser focus (single element)
|
|
456
|
+
- Used in preview/playback mode
|
|
457
|
+
- Highlights interactive element
|
|
458
|
+
<!-- html-only -->
|
|
459
|
+
- Provided by ef-preview context
|
|
460
|
+
<!-- /html-only -->
|
|
461
|
+
<!-- react-only -->
|
|
462
|
+
- Provided by Preview context
|
|
463
|
+
<!-- /react-only -->
|
|
464
|
+
|
|
465
|
+
**Selection overlay** (canvas):
|
|
466
|
+
- Tracks canvas selection (multiple elements)
|
|
467
|
+
- Used in editing mode
|
|
468
|
+
- Shows selected elements
|
|
469
|
+
<!-- html-only -->
|
|
470
|
+
- Provided by ef-canvas
|
|
471
|
+
<!-- /html-only -->
|
|
472
|
+
<!-- react-only -->
|
|
473
|
+
- Provided by Canvas
|
|
474
|
+
<!-- /react-only -->
|
|
475
|
+
|
|
476
|
+
## Context Requirement
|
|
477
|
+
|
|
478
|
+
<!-- html-only -->
|
|
479
|
+
Focus overlay requires a parent that provides `focusedElementContext`:
|
|
480
|
+
|
|
481
|
+
```html
|
|
482
|
+
<!-- Works - preview provides context -->
|
|
483
|
+
<ef-preview target="composition">
|
|
484
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
485
|
+
</ef-preview>
|
|
486
|
+
|
|
487
|
+
<!-- Doesn't work - no context provider -->
|
|
488
|
+
<ef-focus-overlay></ef-focus-overlay>
|
|
489
|
+
```
|
|
490
|
+
<!-- /html-only -->
|
|
491
|
+
<!-- react-only -->
|
|
492
|
+
FocusOverlay must be a child of Preview component. Preview provides the `focusedElementContext` that FocusOverlay consumes.
|
|
493
|
+
<!-- /react-only -->
|
|
494
|
+
|
|
495
|
+
## Fixed Positioning
|
|
496
|
+
|
|
497
|
+
Overlay uses `position: fixed` to stay visible during scrolling and pan/zoom operations.
|
|
498
|
+
|
|
499
|
+
## Container Sizing
|
|
500
|
+
|
|
501
|
+
Overlay fills its container:
|
|
502
|
+
|
|
503
|
+
```css
|
|
504
|
+
ef-focus-overlay {
|
|
505
|
+
display: block;
|
|
506
|
+
position: relative;
|
|
507
|
+
width: 100%;
|
|
508
|
+
height: 100%;
|
|
509
|
+
pointer-events: none;
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
Actual highlight overlay uses fixed positioning within.
|
|
514
|
+
|
|
515
|
+
<!-- html-only -->
|
|
516
|
+
## Debug Visibility
|
|
517
|
+
|
|
518
|
+
To debug focus overlay:
|
|
519
|
+
|
|
520
|
+
```javascript
|
|
521
|
+
const overlay = document.querySelector('ef-focus-overlay');
|
|
522
|
+
|
|
523
|
+
// Check if element is focused
|
|
524
|
+
console.log(overlay.focusedElement);
|
|
525
|
+
|
|
526
|
+
// Check overlay visibility
|
|
527
|
+
const overlayDiv = overlay.shadowRoot.querySelector('.overlay');
|
|
528
|
+
console.log(overlayDiv.style.display); // 'block' or 'none'
|
|
529
|
+
```
|
|
530
|
+
<!-- /html-only -->
|
|
531
|
+
|
|
532
|
+
## Architecture
|
|
533
|
+
|
|
534
|
+
- Uses `position: fixed` for overlay positioning
|
|
535
|
+
- Runs continuous RAF loop for smooth tracking
|
|
536
|
+
- Reads `getBoundingClientRect()` from focused element
|
|
537
|
+
- Mix blend mode creates visual highlight effect
|
|
538
|
+
- Automatically hidden when no element focused
|
|
539
|
+
|
|
540
|
+
## CSS Customization
|
|
541
|
+
|
|
542
|
+
Customize appearance with CSS variables:
|
|
543
|
+
|
|
544
|
+
```css
|
|
545
|
+
.focus-overlay {
|
|
546
|
+
--ef-focus-overlay-color: #3b82f6; /* Border color */
|
|
547
|
+
--ef-focus-overlay-background: rgba(59, 130, 246, 0.4); /* Fill color */
|
|
548
|
+
}
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
<!-- react-only -->
|
|
552
|
+
## Important Notes
|
|
553
|
+
|
|
554
|
+
- Must be a child of Preview component
|
|
555
|
+
- Position is `fixed` to viewport (not Preview-relative)
|
|
556
|
+
- Updates every animation frame for smooth tracking
|
|
557
|
+
- Pointer events are disabled (`pointer-events: none`)
|
|
558
|
+
- Automatically syncs with Preview's focused element
|
|
559
|
+
- Use for visual feedback in editor interfaces
|
|
560
|
+
- Works with all composition elements (Video, Text, Image, etc.)
|
|
561
|
+
<!-- /react-only -->
|