React Native - requestAnimationFrame 暂停和恢复
React Native - requestAnimationFrame pause and resume
我正在使用 requestAnimationFrame 每 1 秒更新一次计时器。
const [secondsPassed, setSecondsPassed] = useState(0)
const t0Ref = useRef(Date.now())
const requestRef = useRef()
const targetValueRef = useRef(0)
const updateSecondsPassed = useCallback(() => {
const time = Date.now() - t0Ref.current
const nextValue = time * 0.001
if (nextValue >= sessionTime) {
console.log('Reset to 0')
setSecondsPassed(0)
return
}
const targetValue = targetValueRef.current
if (nextValue >= targetValue) {
console.log(`Update ${targetValue - 1} -> ${nextValue | 0}`)
setSecondsPassed(targetValue)
targetValueRef.current = targetValue + 1
}
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}, [sessionTime])
useEffect(() => {
if (playbackState === 'initial' || playbackState === 'stopped') {
setSecondsPassed(0)
targetValueRef.current = 0
}
if (playbackState === 'playing') {
t0Ref.current = Date.now()
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}
if (playbackState === 'paused') {
console.log(secondsPassed)
}
if (playbackState === 'resumed') {
// Code here...
}
return () => cancelAnimationFrame(requestRef.current)
}, [playbackState])
问题是我在 'resumed' playbackState 块上尝试了所有方法,它会等待已经过去的秒数,然后再开始重新计数。
感谢阅读!
通过将 t0Ref 重置为 Date.now() 减去已经过去的秒数(以毫秒为单位)解决了这个问题:
if (playbackState === 'resumed') {
t0Ref.current = Date.now() - secondsPassed * 1000
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}
我正在使用 requestAnimationFrame 每 1 秒更新一次计时器。
const [secondsPassed, setSecondsPassed] = useState(0)
const t0Ref = useRef(Date.now())
const requestRef = useRef()
const targetValueRef = useRef(0)
const updateSecondsPassed = useCallback(() => {
const time = Date.now() - t0Ref.current
const nextValue = time * 0.001
if (nextValue >= sessionTime) {
console.log('Reset to 0')
setSecondsPassed(0)
return
}
const targetValue = targetValueRef.current
if (nextValue >= targetValue) {
console.log(`Update ${targetValue - 1} -> ${nextValue | 0}`)
setSecondsPassed(targetValue)
targetValueRef.current = targetValue + 1
}
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}, [sessionTime])
useEffect(() => {
if (playbackState === 'initial' || playbackState === 'stopped') {
setSecondsPassed(0)
targetValueRef.current = 0
}
if (playbackState === 'playing') {
t0Ref.current = Date.now()
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}
if (playbackState === 'paused') {
console.log(secondsPassed)
}
if (playbackState === 'resumed') {
// Code here...
}
return () => cancelAnimationFrame(requestRef.current)
}, [playbackState])
问题是我在 'resumed' playbackState 块上尝试了所有方法,它会等待已经过去的秒数,然后再开始重新计数。
感谢阅读!
通过将 t0Ref 重置为 Date.now() 减去已经过去的秒数(以毫秒为单位)解决了这个问题:
if (playbackState === 'resumed') {
t0Ref.current = Date.now() - secondsPassed * 1000
requestRef.current = requestAnimationFrame(updateSecondsPassed)
}