JSFiddle - React, Tailwind, and code Playground
HTML
<body>
<div id="ball"></div>
</body>
CSS
body {
padding: 0;
margin: 0;
background: white;
}
#ball {
position: absolute;
top: 0%;
left: calc(50% - 50px);
width: 100px;
height: 100px;
border-radius: 100%;
background-color: rgba(0,0,0,.8);
}
JavaScript
/* Example animation function
*
* Interpolate between a start and end position.
*
* obj.x represents a position parameter (e.g. 12.2)
* end_pos is the value obj.x will have at the end of the animation
* msec is the number of milliseconds we want to run the animation for
* easing is a timing function that accepts a number between 0 to 1
* and returns the proportion of the interpolation between start and end to move the object to.
*
* Returns: void (performs animation as a side effect)
*/
function animation (args) {
args = args || {};
var easing = args.easing || function (t) { return t }; // default to linear easing
var obj = args.obj;
var style = window.getComputedStyle(obj);
var start_pos = parseInt(style.top.replace("%", ""), 10),
end_pos = args.end !== undefined ? args.end : start_pos,
msec = args.msec || 1000;
// performance.now is guaranteed to increase and gives sub-millisecond resolution
// Date.now is susceptible to system clock changes and gives some number of milliseconds resolution
var start = window.performance.now(),
delta = end_pos - start_pos;
function frame () {
var now = window.performance.now();
var t = (now - start) / msec; // normalize to 0..1
if (t >= 1) { // if animation complete or running over
obj.style.top = end_pos + "%"; // ensure the animation terminates in the specified state
return;
}
var proportion = easing(t);
obj.style.top = (start_pos + proportion * delta) + "%";
requestAnimationFrame(frame); // next frame!
}
requestAnimationFrame(frame); // you can use setInterval, but this will give a smoother animation
}
function clamp (x, min, max) {
return Math.min(Math.max(x, min), max);
}
function bounceFactory (bounces, threshold) {
threshold = threshold || 0.001;
function energy_to_height (energy) {
return energy; // h = E/mg
}
function height_to_energy (height) {
return height; // E = mgh
}
function bounce_time (height) {
return 2 *...