ef-overlay-item
Attributes
element-idstringElement ID to track (searches data-element-id or data-timegroup-id)
targetstring | HTMLElementCSS selector or element reference to track
Methods
updatePosition(): voidUpdate position based on target element (called by parent layer)
Individual overlay that tracks and follows a target element's position.
Basic Usage
Track an element with an overlay:
<div class="relative w-[600px] h-[400px] border border-gray-300 rounded overflow-hidden"><ef-overlay-layer class="absolute inset-0 pointer-events-none"><ef-overlay-item target="#box-1" class="border-2 border-blue-500 pointer-events-auto"><div class="absolute -top-6 left-0 bg-blue-500 text-white text-xs px-2 py-1 rounded whitespace-nowrap">Selected Box</div></ef-overlay-item></ef-overlay-layer><div id="box-1" class="absolute top-12 left-12 w-40 h-32 bg-blue-100 border-2 border-blue-300 rounded"></div><div id="box-2" class="absolute top-48 left-48 w-40 h-32 bg-green-100 border-2 border-green-300 rounded"></div></div>
Target Selection
Overlay items support multiple ways to specify targets:
CSS Selector
Use any valid CSS selector:
<ef-overlay-item target="#my-element"></ef-overlay-item><ef-overlay-item target=".selected"></ef-overlay-item><ef-overlay-item target="ef-video[src*='intro']"></ef-overlay-item>
Element Reference
Pass element directly via JavaScript:
const overlay = document.querySelector('ef-overlay-item');const element = document.getElementById('my-element');overlay.target = element;
Element ID Attribute
Use element-id for canvas elements with data attributes:
<ef-canvas><div data-element-id="element-1"></div><ef-timegroup data-timegroup-id="group-1"></ef-timegroup></ef-canvas><ef-overlay-layer><ef-overlay-item element-id="element-1"></ef-overlay-item><ef-overlay-item element-id="group-1"></ef-overlay-item></ef-overlay-layer>
Overlay Content
Add any content inside the overlay item:
Selection Border
<ef-overlay-item target="#element" class="border-2 border-blue-500 rounded"></ef-overlay-item>
Labels and Badges
<div class="relative w-[600px] h-[400px] border border-gray-300 rounded overflow-hidden bg-gray-50"><ef-overlay-layer class="absolute inset-0 pointer-events-none"><ef-overlay-item target="#video-element" class="pointer-events-none"><div class="absolute -top-7 left-0 bg-purple-600 text-white text-xs px-2 py-1 rounded-t flex items-center gap-1"><svg class="w-3 h-3" fill="currentColor" viewBox="0 0 20 20"><path d="M2 6a2 2 0 012-2h6a2 2 0 012 2v8a2 2 0 01-2 2H4a2 2 0 01-2-2V6zm12.553 1.106A1 1 0 0014 8v4a1 1 0 00.553.894l2 1A1 1 0 0018 13V7a1 1 0 00-1.447-.894l-2 1z" /></svg>Video</div><div class="absolute -bottom-6 right-0 bg-gray-800 text-white text-xs px-2 py-1 rounded">320x240</div></ef-overlay-item></ef-overlay-layer><div id="video-element" class="absolute top-16 left-16 w-64 h-48 bg-black rounded shadow-lg flex items-center justify-center text-gray-400">Video Player</div></div>
Handles and Controls
<ef-overlay-item target="#element" class="pointer-events-auto"><button class="absolute top-0 right-0 w-4 h-4 bg-blue-500 rounded-full -mt-2 -mr-2"></button><button class="absolute bottom-0 right-0 w-4 h-4 bg-blue-500 rounded-full -mb-2 -mr-2"></button></ef-overlay-item>
Position Updates
Overlay items are updated by their parent layer's RAF loop:
const overlay = document.querySelector('ef-overlay-item');// Listen for position changesoverlay.addEventListener('position-changed', (e) => {const { x, y, width, height, rotation } = e.detail;console.log('Overlay moved to:', x, y);console.log('Size:', width, height);console.log('Rotation:', rotation);});
Rotation Support
Overlay items automatically track element rotation:
<div class="relative w-[600px] h-[400px] border border-gray-300 rounded overflow-hidden bg-gray-50"><ef-overlay-layer class="absolute inset-0 pointer-events-none"><ef-overlay-item target="#rotated-box" class="border-2 border-red-500"></ef-overlay-item></ef-overlay-layer><div id="rotated-box" class="absolute top-24 left-24 w-40 h-32 bg-red-100 rounded shadow" style="transform: rotate(15deg)"><div class="p-4 text-center">Rotated Element</div></div></div>
The overlay automatically rotates to match its target.
Visibility
Overlay items automatically hide when target is not found:
const overlay = document.querySelector('ef-overlay-item');// Target exists - overlay visibleoverlay.target = '#existing-element';// Target not found - overlay hidden (display: none)overlay.target = '#nonexistent-element';// Target removed - overlay hiddenconst element = document.getElementById('existing-element');element.remove();
Pointer Events
Enable pointer events for interactive overlays:
<ef-overlay-item target="#element" class="pointer-events-auto cursor-move"><!-- Interactive content --></ef-overlay-item>
Overlay layer has pointer-events: none, so explicitly enable on items that need interaction.
Coordinate System
Overlay items use absolute positioning relative to their parent overlay layer:
- x, y: Top-left position in layer coordinates
- width, height: Match target element dimensions
- rotation: Parsed from target element's transform
The parent layer handles transform synchronization with pan/zoom.
Update Frequency
Position updates happen every animation frame (60fps) via the parent layer's RAF loop. No throttling or change detection - updates are always fresh.
Performance
Overlay items are passive - they don't run their own RAF loops. The parent layer manages all updates in a single synchronized loop, preventing RAF proliferation.
Target Validation
Overlay items verify target is still in the DOM:
const overlay = document.querySelector('ef-overlay-item');const element = document.getElementById('my-element');overlay.target = element; // Works - element in DOMelement.remove(); // Element removed// Overlay automatically hidesdocument.body.appendChild(element); // Element re-added// Overlay reappears on next frame
CSS Styling
Style the overlay item container:
ef-overlay-item {/* Border and background */border: 2px solid blue;background: rgba(0, 0, 255, 0.1);/* Pointer interaction */pointer-events: auto;cursor: pointer;/* Transform origin (rotation center) */transform-origin: center;}
Position Change Event
The position-changed event provides:
interface OverlayItemPosition {x: number; // Left position relative to OverlayLayery: number; // Top position relative to OverlayLayerwidth: number; // Element widthheight: number; // Element heightrotation: number; // Element rotation in degrees}
Important Notes
- Must be a child of an ef-overlay-layer element
- Updates position continuously in sync with parent's RAF loop
- Automatically handles element rotation transforms
- Hidden when target element is not found
- Position is relative to the overlay layer container
- Use
element-idfor canvas elements with data attributes - Use
targetfor custom DOM elements