Skip to content

Instantly share code, notes, and snippets.

@gielcobben
Created March 29, 2019 15:08
Show Gist options
  • Save gielcobben/07fedce793d336c8350d5eee3e4fc200 to your computer and use it in GitHub Desktop.
Save gielcobben/07fedce793d336c8350d5eee3e4fc200 to your computer and use it in GitHub Desktop.
useAnimation
import * as React from "react"
function useAnimationTimer(duration = 1000, delay = 0) {
const [elapsed, setTime] = React.useState(0)
React.useEffect(() => {
let animationFrame, timerStop, start
// Function to be executed on each animation frame
function onFrame() {
setTime(Date.now() - start)
loop()
}
// Call onFrame() on next animation frame
function loop() {
animationFrame = requestAnimationFrame(onFrame)
}
function onStart() {
// Set a timeout to stop things when duration time elapses
timerStop = setTimeout(() => {
cancelAnimationFrame(animationFrame)
setTime(Date.now() - start)
}, duration)
// Start the loop
start = Date.now()
loop()
}
// Start after specified delay (defaults to 0)
const timerDelay = setTimeout(onStart, delay)
// Clean things up
return () => {
clearTimeout(timerStop)
clearTimeout(timerDelay)
cancelAnimationFrame(animationFrame)
}
}, [duration, delay]) // Only re-run effect if duration or delay changes
return elapsed
}
export function useValueAnimation(
easingName = "linear",
duration = 500,
delay = 0
) {
// The useAnimationTimer hook calls useState every animation frame ...
// ... giving us elapsed time and causing a rerender as frequently ...
// ... as possible for a smooth animation.
const elapsed = useAnimationTimer(duration, delay)
// Amount of specified duration elapsed on a scale from 0 - 1
const n = Math.min(1, elapsed / duration)
// Return altered value based on our specified easing function
return easing[easingName](n)
}
// Some easing functions copied from:
// https://github.com/streamich/ts-easing/blob/master/src/index.ts
// Hardcode here or pull in a dependency
const easing = {
linear: n => n,
elastic: n =>
n * (33 * n * n * n * n - 106 * n * n * n + 126 * n * n - 67 * n + 15),
inExpo: n => Math.pow(2, 10 * (n - 1)),
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment