fix: RAF loop + scrollYProgress.on() for frame animation
This commit is contained in:
@@ -6,7 +6,6 @@ import {
|
||||
motion,
|
||||
useScroll,
|
||||
useTransform,
|
||||
useMotionValueEvent,
|
||||
useReducedMotion,
|
||||
} from 'framer-motion'
|
||||
import UnitRevealOverlay from './UnitRevealOverlay'
|
||||
@@ -27,6 +26,7 @@ export default function CloudRevealSection() {
|
||||
const sectionRef = useRef<HTMLDivElement>(null)
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null)
|
||||
const framesRef = useRef<(HTMLImageElement | null)[]>([])
|
||||
const scrollProgressRef = useRef(0)
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
const [loadProgress, setLoadProgress] = useState(0)
|
||||
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)
|
||||
}, [])
|
||||
|
||||
// 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
|
||||
useEffect(() => {
|
||||
if (prefersReducedMotion) return
|
||||
@@ -109,23 +141,6 @@ export default function CloudRevealSection() {
|
||||
return () => { cancelled = true }
|
||||
}, [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
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user