Skip to content

Instantly share code, notes, and snippets.

@tol-is
Created April 3, 2024 06:48
Show Gist options
  • Save tol-is/ec035c797292b96696bf300ed60611f5 to your computer and use it in GitHub Desktop.
Save tol-is/ec035c797292b96696bf300ed60611f5 to your computer and use it in GitHub Desktop.
useTimer
import { useRef } from 'react'
export type UseTimerProps = {
duration: number
onFrame: (percent: number) => void
onComplete: () => void
}
export const useTimer = (props: UseTimerProps) => {
const { duration: propsDuration, onFrame, onComplete } = props
const startRef = useRef<number>(0)
const rafRef = useRef<number>(0)
const durationRef = useRef<number>(propsDuration)
const elapsedRef = useRef<number>(0)
const start = (duration?: number) => {
durationRef.current = duration || propsDuration
cancelAnimationFrame(rafRef.current)
startRef.current = performance.now()
animate()
}
const stop = () => {
cancelAnimationFrame(rafRef.current)
}
const reset = () => {
startRef.current = performance.now()
}
const resume = () => {
startRef.current = elapsedRef.current
animate()
}
const animate = () => {
const currentTime = performance.now()
const elapsedTime = currentTime - startRef.current
elapsedRef.current = elapsedTime
const percent = Math.min(elapsedTime / durationRef.current, 1)
onFrame(percent)
if (percent < 1) {
rafRef.current = requestAnimationFrame(animate)
} else {
cancelAnimationFrame(rafRef.current)
onComplete()
}
}
return { start, reset, resume, stop }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment