fix: RAF loop + scrollYProgress.on() for frame animation

This commit is contained in:
2026-07-30 23:10:42 +03:00
parent 8bf266f2b2
commit 0ae16f2963
+33 -18
View File
@@ -6,7 +6,6 @@ import {
motion, motion,
useScroll, useScroll,
useTransform, useTransform,
useMotionValueEvent,
useReducedMotion, useReducedMotion,
} from 'framer-motion' } from 'framer-motion'
import UnitRevealOverlay from './UnitRevealOverlay' import UnitRevealOverlay from './UnitRevealOverlay'
@@ -27,6 +26,7 @@ export default function CloudRevealSection() {
const sectionRef = useRef<HTMLDivElement>(null) const sectionRef = useRef<HTMLDivElement>(null)
const canvasRef = useRef<HTMLCanvasElement>(null) const canvasRef = useRef<HTMLCanvasElement>(null)
const framesRef = useRef<(HTMLImageElement | null)[]>([]) const framesRef = useRef<(HTMLImageElement | null)[]>([])
const scrollProgressRef = useRef(0)
const [loaded, setLoaded] = useState(false) const [loaded, setLoaded] = useState(false)
const [loadProgress, setLoadProgress] = useState(0) const [loadProgress, setLoadProgress] = useState(0)
const [activeUnit, setActiveUnit] = useState<{ id: string; label: string; sub: string } | null>(null) const [activeUnit, setActiveUnit] = useState<{ id: string; label: string; sub: string } | null>(null)
@@ -72,6 +72,38 @@ export default function CloudRevealSection() {
return () => window.removeEventListener('resize', resize) return () => window.removeEventListener('resize', resize)
}, []) }, [])
// scrollYProgress → ref (RAF loop için)
useEffect(() => {
return scrollYProgress.on('change', (v) => { scrollProgressRef.current = v })
}, [scrollYProgress])
// RAF loop: scroll progress + yüklü frame → canvas
useEffect(() => {
const canvas = canvasRef.current
if (!canvas) return
const ctx = canvas.getContext('2d')
if (!ctx) return
let rafId: number
const loop = () => {
const progress = scrollProgressRef.current
const targetIdx = Math.min(
Math.floor(progress * (TOTAL_FRAMES - 1)),
TOTAL_FRAMES - 1
)
// En yakın yüklü frame'i bul
for (let i = targetIdx; i >= 0; i--) {
const img = framesRef.current[i]
if (img && canvas.width > 0) {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
break
}
}
rafId = requestAnimationFrame(loop)
}
rafId = requestAnimationFrame(loop)
return () => cancelAnimationFrame(rafId)
}, [])
// Frame preload // Frame preload
useEffect(() => { useEffect(() => {
if (prefersReducedMotion) return if (prefersReducedMotion) return
@@ -109,23 +141,6 @@ export default function CloudRevealSection() {
return () => { cancelled = true } return () => { cancelled = true }
}, [prefersReducedMotion]) }, [prefersReducedMotion])
// Scroll → canvas frame çiz
useMotionValueEvent(scrollYProgress, 'change', (progress) => {
const targetIdx = Math.min(
Math.floor(progress * (TOTAL_FRAMES - 1)),
TOTAL_FRAMES - 1
)
// Hedef frame yüklenmemişse geriye doğru ilk yüklü frame'i bul
let img: HTMLImageElement | null = null
for (let i = targetIdx; i >= 0; i--) {
if (framesRef.current[i]) { img = framesRef.current[i]; break }
}
const canvas = canvasRef.current
const ctx = canvas?.getContext('2d')
if (img && canvas && ctx && canvas.width > 0) {
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
}
})
// Scroll kilidi // Scroll kilidi
useEffect(() => { useEffect(() => {