fix: RAF loop + scrollYProgress.on() for frame animation
This commit is contained in:
@@ -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(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user