Skip to content

Instantly share code, notes, and snippets.

@ArtemVeremienko
Created May 23, 2020 11:30
Show Gist options
  • Save ArtemVeremienko/e97699122ffd3b3343371d654e27abec to your computer and use it in GitHub Desktop.
Save ArtemVeremienko/e97699122ffd3b3343371d654e27abec to your computer and use it in GitHub Desktop.
Bouncing ball
<div id="field">
<img src="https://en.js.cx/clipart/ball.svg" width="40" height="40" id="ball">
</div>
function animate({ timing, draw, duration }) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
let progress = timing(timeFraction);
draw(progress);
if (timeFraction < 1) requestAnimationFrame(animate);
});
}
function bounce(timeFraction) {
for (let a = 0, b = 1, result; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return (
-Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
);
}
}
}
function quad(timeFraction) {
return Math.pow(timeFraction, 2);
}
function makeEaseOut(timing) {
return function (timeFraction) {
return 1 - timing(1 - timeFraction);
};
}
ball.onclick = () => {
let toBottom = field.clientHeight - ball.clientHeight;
let toRight = 100;
animate({
duration: 2000,
timing: makeEaseOut(bounce),
draw: (progress) => (ball.style.top = progress * toBottom + "px")
});
animate({
duration: 2000,
timing: makeEaseOut(quad),
draw: (progress) => (ball.style.left = toRight * progress + "px")
});
};
#field {
height: 200px;
border-bottom: 3px black groove;
position: relative;
}
#ball {
position: absolute;
cursor: pointer;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment