'use client' import { useEffect, useRef, useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { X } from 'lucide-react' const UNIT_FRAMES = 120 const CDN = 'https://media.ayris.tech/t' // Video kullanan birimler const VIDEO_UNITS: Record = { 'blok-a': `${CDN}/vesta/unit-videos/blok-a.mp4`, } interface UnitRevealOverlayProps { unitId: string | null unitLabel: string unitSub: string onClose: () => void } export default function UnitRevealOverlay({ unitId, unitLabel, unitSub, onClose, }: UnitRevealOverlayProps) { const isVideo = unitId ? !!VIDEO_UNITS[unitId] : false // ── Video mode ────────────────────────────────────────────────── const videoRef = useRef(null) const [videoFinished, setVideoFinished] = useState(false) useEffect(() => { if (!unitId || !isVideo) return setVideoFinished(false) const v = videoRef.current if (!v) return v.currentTime = 0 v.play().catch(() => {}) }, [unitId, isVideo]) // ── Frame mode ─────────────────────────────────────────────────── const canvasRef = useRef(null) const framesRef = useRef([]) const rafRef = useRef(null) const [loadProgress, setLoadProgress] = useState(0) const [loaded, setLoaded] = useState(false) const [finished, setFinished] = useState(false) useEffect(() => { if (!unitId || isVideo) return setLoaded(false) setFinished(false) setLoadProgress(0) framesRef.current = [] const images: HTMLImageElement[] = new Array(UNIT_FRAMES) let loadedCount = 0 let cancelled = false for (let i = 0; i < UNIT_FRAMES; i++) { const img = new Image() img.src = `${CDN}/vesta/unit-frames/${unitId}/ezgif-frame-${String(i + 1).padStart(3, '0')}.jpg` img.onload = () => { if (cancelled) return loadedCount++ setLoadProgress(Math.round((loadedCount / UNIT_FRAMES) * 100)) if (loadedCount === UNIT_FRAMES) { framesRef.current = images setLoaded(true) } } images[i] = img } return () => { cancelled = true } }, [unitId, isVideo]) useEffect(() => { const canvas = canvasRef.current if (!canvas) return const resize = () => { canvas.width = window.innerWidth canvas.height = window.innerHeight } resize() window.addEventListener('resize', resize) return () => window.removeEventListener('resize', resize) }, []) useEffect(() => { if (!loaded || isVideo) return const canvas = canvasRef.current const ctx = canvas?.getContext('2d') if (!canvas || !ctx) return let frame = 0 const fps = 24 const interval = 1000 / fps let last = 0 const animate = (ts: number) => { if (ts - last >= interval) { const img = framesRef.current[frame] if (img?.complete && img.naturalWidth > 0) { ctx.drawImage(img, 0, 0, canvas.width, canvas.height) } last = ts if (frame < UNIT_FRAMES - 1) { frame++ } else { setFinished(true) return } } rafRef.current = requestAnimationFrame(animate) } rafRef.current = requestAnimationFrame(animate) return () => { if (rafRef.current) cancelAnimationFrame(rafRef.current) } }, [loaded, isVideo]) // ESC kapat useEffect(() => { const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') onClose() } window.addEventListener('keydown', onKey) return () => window.removeEventListener('keydown', onKey) }, [onClose]) const showInfo = isVideo ? videoFinished : finished return ( {unitId && ( {/* Video modu */} {isVideo && (