-
-
Save gielcobben/7e6d9177cd8dea75374439481f45c7c5 to your computer and use it in GitHub Desktop.
requestAnimationFrame boilerplate code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
// animation utils | |
// =============== | |
const trackTime = timing => { | |
const now = performance.now(); | |
if (!timing.startTime) timing.startTime = now; | |
const elapsed = now - timing.startTime; | |
const {duration} = timing; | |
if (duration != null && duration <= elapsed) timing.startTime = null; | |
return elapsed; | |
}; | |
const delay = (callback, duration) => { | |
const timing = {duration}; | |
const tick = () => | |
trackTime(timing) < duration ? requestAnimationFrame(tick) : callback(); | |
tick(); | |
}; | |
const getProgress = timing => { | |
const {duration} = timing; | |
return duration > 0 ? Math.min(trackTime(timing) / duration, 1) : 1; | |
}; | |
const getCurrentValue = ({from = 0, to}, easing) => | |
from + (to - from) * easing; | |
// easing equations | |
// ================ | |
const ease = (() => { | |
const easings = { | |
"in-cubic": progress => Math.pow(progress, 3), | |
"in-quartic": progress => Math.pow(progress, 4), | |
"in-quintic": progress => Math.pow(progress, 5), | |
"in-exponential": progress => progress > 0 ? Math.pow(1024, progress - 1) : 0, | |
"in-circular": progress => 1 - Math.sqrt(1 - Math.pow(progress, 2)), | |
"in-elastic": progress => { | |
if (progress == 0) return 0; | |
if (progress == 1) return 1; | |
return -Math.pow(2, 10 * (progress - 1)) * Math.sin((progress - 1.1) * 5 * Math.PI); | |
}, | |
"out-cubic": progress => Math.pow(--progress, 3) + 1, | |
"out-quartic": progress => 1 - Math.pow(--progress, 4), | |
"out-quintic": progress => Math.pow(--progress, 5) + 1, | |
"out-exponential": progress => progress < 1 ? 1 - Math.pow(2, -10 * progress) : 1, | |
"out-circular": progress => Math.sqrt(1 - Math.pow(--progress, 2)), | |
"out-elastic": progress => { | |
if (progress == 0) return 0; | |
if (progress == 1) return 1; | |
return Math.pow(2, -10 * progress) * Math.sin((progress - .1) * 5 * Math.PI) + 1; | |
}, | |
"in-out-cubic": progress => | |
(progress *= 2) < 1 | |
? .5 * Math.pow(progress, 3) | |
: .5 * ((progress -= 2) * Math.pow(progress, 2) + 2), | |
"in-out-quartic": progress => | |
(progress *= 2) < 1 | |
? .5 * Math.pow(progress, 4) | |
: -.5 * ((progress -= 2) * Math.pow(progress, 3) - 2), | |
"in-out-quintic": progress => | |
(progress *= 2) < 1 | |
? .5 * Math.pow(progress, 5) | |
: .5 * ((progress -= 2) * Math.pow(progress, 4) + 2), | |
"in-out-exponential": progress => { | |
if (progress == 0) return 0; | |
if (progress == 1) return 1; | |
return (progress *= 2) < 1 | |
? .5 * Math.pow(1024, progress - 1) | |
: .5 * (-Math.pow(2, -10 * (progress - 1)) + 2); | |
}, | |
"in-out-circular": progress => | |
(progress *= 2) < 1 | |
? -.5 * (Math.sqrt(1 - Math.pow(progress, 2)) - 1) | |
: .5 * (Math.sqrt(1 - (progress -= 2) * progress) + 1), | |
"in-out-elastic": progress => { | |
if (progress == 0) return 0; | |
if (progress == 1) return 1; | |
progress *= 2; | |
const sin = Math.sin((progress - 1.1) * 5 * Math.PI); | |
return progress < 1 | |
? -.5 * Math.pow(2, 10 * (progress - 1)) * sin | |
: .5 * Math.pow(2, -10 * (progress - 1)) * sin + 1; | |
} | |
}; | |
return ({easing = "out-elastic"}, progress) => easings[easing](progress); | |
})(); | |
// animation | |
// ========= | |
const animate = () => { | |
const element = document.body.firstElementChild; | |
const keyframes = { | |
from: 0, | |
to: 800 | |
}; | |
const timing = { | |
duration: 2000, | |
easing: "out-circular" | |
}; | |
const tick = () => { | |
const progress = getProgress(timing); | |
if (progress < 1) requestAnimationFrame(tick); | |
const easing = ease(timing, progress); | |
const value = getCurrentValue(keyframes, easing); | |
element.style.transform = `translate(${value}px)`; | |
}; | |
tick(); | |
}; | |
delay(animate, 500); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment