π requestAnimationFrameμ μ΄λΉ νλ μ μ‘°μ νκΈ°
requestAnimationFrame
(μ΄ν rAF) μ μ΄μ©ν΄μ JavaScript μ λλ©μ΄μ
μ ꡬννλλ°, μ±λ₯μμ μ΄μ λ‘ μ΄λΉ νλ μ(FPS
) μ μ‘°μ ν΄μΌ νλ μν©μ΄ μκ²Όμ΅λλ€.
λ€λ₯Έ νμ΄λ¨Έ ν¨μλ€(setInterval, setTimeout)μ μ¬μ©νμ§ μκ³ rAF
μμ μ΄λΉ νλ μμ μ‘°μ νλ λ°©λ²μ ꡬνν΄ λ΄€μ΅λλ€.
animation tick
κ°λ¨νκ² FPS
μ λν΄μ μμλ³΄κ³ μνλ FPS
λ₯Ό μν tick
μ ꡬν΄λ΄
μλ€.
const tick = 1000 / fps
1μ΄λΉ 60 νλ μμ μνλ€λ©΄ 1000 / 60 = 16.6ms
λ§λ€ νλμ νλ μμ κ·Έλ €μΌ ν¨μ μλ―Έν©λλ€.
μ¬κΈ°μ λͺ©νν νλ μ λΉμ¨μ μν΄μ νλμ νλ μμ 그리λλ° νμν μκ°μ tick
μ΄λΌκ³ νκ² μ΅λλ€.
μ΄μ 루ν μ€ν λΆλΆμ ꡬνν©λλ€.
60fps(16.6ms)
λ‘ μ€νλλ rAF 루νμμ tick
μ λλ¬ν κ²½μ°μλ§ drawFn
μ νΈμΆν©λλ€.
let startTime = Date.now() // β
루ν μμ μκ°μ μ€μ ν©λλ€.
loop()
function loop() {
animationId = requestAnimationFrame(_loop)
const now = Date.now()
const elapsed = now - startTime
if (elapsed > tick) {
startTime = now - (elapsed % tick) // β
rAFμ λ°°μκ° λμ§ μλλ‘ κ°μ 보μ ν΄μ€λ€.
drawFn()
}
}
κ·Έλ¦¬κ³ elapsed % tick
μ ν΄λΉνλ κ°μ λΉΌμ€ κ°μΌλ‘ νμ¬ μκ°μ κ°±μ ν©λλ€.
μ΄λ₯Ό ν΅ν΄ κΈ°μ‘΄ νμ΄λ¨Έμ λ°°μκ° λμ§ μλλ‘ λ³΄μ ν΄ μ£Όκ² λ©λλ€.
νμ΄λ¨Έ μμ, μ€μ§, μ΄κΈ°ν
루νλ₯Ό μμ, μ’ λ£ν μ μλ ν¨μλ₯Ό ν¬ν¨νλ κ°μ²΄λ₯Ό λ°ννλλ‘ λ³κ²½ν΄ λ΄ μλ€.
μ΄λ₯Ό μν ν¨μ 본체 ꡬνμ λ΄λΆ ν¨μλ‘ μ 곡ν©λλ€.
function createAnimationLoop({
drawFn,
immediate,
}: {
drawFn: () => void
immediate?: boolean
}): AnimationLoop {
const fps = 1 // β
1μ΄λΉ 1νλ μμ κ·Έλ¦°λ€.
const tick = 1000 / fps
let animationId: number
let startTime: number
function _init() {
startTime = Date.now()
if (immediate) {
drawFn()
}
}
function _loop() {
animationId = requestAnimationFrame(_loop)
const now = Date.now()
const elapsed = now - startTime
if (elapsed > tick) {
startTime = now - (elapsed % tick) // β
rAFμ λ°°μκ° λμ§ μλλ‘ κ°μ 보μ ν΄μ€λ€.
drawFn()
}
}
return {
start: function _start() {
_init()
_loop()
},
stop: function _stop() {
if (animationId !== -1) {
cancelAnimationFrame(animationId)
animationId = -1
}
},
}
}
loop μμ μ μ΄κΈ°μ νλ² μ€νν μ μλλ‘ immediate
μ΅μ
μ μΆκ°ν΄ 쀬μ΅λλ€.
μ¬μ© μμ
React
μ ν¨κ» μ¬μ©νλ€λ©΄ λ€μκ³Ό κ°μ΄ μ μ©ν μ μμ΅λλ€.
function useAnimation() {
const loop = useRef()
useEffect(() => {
loop.current = createAnimationLoop(animate)
if (/** 쑰건μ λλ¬νλ€λ©΄ */) {
loop.current.start()
} else {
loop.current.stop()
}
}, [])
}
π μ°Έκ³ μλ£
'π¨βπ» web.dev > fe' μΉ΄ν κ³ λ¦¬μ λ€λ₯Έ κΈ
storybook middleware proxy λ‘ CORS μ°ννκΈ° (0) | 2024.03.01 |
---|---|
μ κ·μμΌλ‘ camel-case νμ±νκΈ° (1) | 2024.02.24 |
point-in-polygon μκ³ λ¦¬μ¦μΌλ‘ κ΅λ΄μΈ νλ¨νκΈ° (0) | 2024.01.30 |
Vanilla JS λ‘ FigJam μΉμ± λ§λ€κΈ° (1) | 2024.01.23 |
Canvas λν νμ μ μ리μ ꡬν λ°©λ² (1) | 2023.08.29 |
π¬ λκΈ