Skip to content

Instantly share code, notes, and snippets.

@smhutch
Forked from bendc/personal-raf-boilerplate.js
Created September 2, 2017 17:32
Show Gist options
  • Save smhutch/408cee48808c4628bce4a7e2fa5b5501 to your computer and use it in GitHub Desktop.
Save smhutch/408cee48808c4628bce4a7e2fa5b5501 to your computer and use it in GitHub Desktop.
requestAnimationFrame boilerplate code
"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