import { useMemo } from 'react'; import { useSceneSelector } from '@/lib/contexts/scene-context'; import { useCanvasStore } from '@/lib/store/canvas'; import type { SlideContent } from '@/lib/types/stage'; import type { PPTElement } from '@/lib/types/slides'; /** * Highlight overlay component * * Features: * - Overlays highlight effects on top of elements * - Does not modify element properties * - Supports highlighting multiple elements simultaneously * - Supports animation effects (breathing, blinking, etc.) * * Implementation: * - Creates overlay divs at element positions * - Uses box-shadow for glow effects * - Uses CSS animation for animated effects */ export function HighlightOverlay() { const highlightedElementIds = useCanvasStore.use.highlightedElementIds(); const highlightOptions = useCanvasStore.use.highlightOptions(); // Get the element list of the current scene const elements = useSceneSelector( (content) => content.canvas.elements, ); // Find all elements to highlight (exclude line elements as they have no height property) const highlightedElements = useMemo(() => { if (!highlightedElementIds.length) return []; return elements.filter((el) => highlightedElementIds.includes(el.id) && el.type !== 'line'); }, [elements, highlightedElementIds]); // Skip rendering if no highlighted elements if (!highlightedElements.length || !highlightOptions) { return null; } const { color = '#ff6b6b', opacity = 0.3, borderWidth = 3, animated = true } = highlightOptions; return ( <> {highlightedElements.map((element) => { // Type guard: line elements are already filtered out above // Use 'in' operator for runtime checks to satisfy TypeScript const height = 'height' in element ? element.height : 0; const rotate = 'rotate' in element ? element.rotate : 0; return (
{/* Highlight border */}
{/* Glow effect */} {animated && (
)}
); })} {/* CSS animation (breathing light effect) */} ); }