JSFiddle - React, Tailwind, and code Playground
by jcubed111
HTML
<div id="wrapper">
<canvas id="main" width=800 height=400></canvas>
<canvas id="timePos" width=800 height=400></canvas>
</div>
<canvas id="animation" width=400 height=300></canvas>
CSS
canvas{
background: #fff;
}
#timePos{
background: transparent;
}
#wrapper{
position: relative;
width: 800px;
height: 400px;
margin-bottom: 10px;
}
#main, #timePos{
position: absolute;
top: 0;
left: 0;
}
JavaScript
var forcePoints = [0, .1, .2, .2, .4, .4, .2, .1, -.2, -.2, -.1, 0, .2, .2, .2, .1, -.1, -.2,
-.3, 0, .1, 0, -.1, .1, .1, .1, .2, .4, .5, .5, .5, .5, .5, .2, .2, .2, .2, 0, -.1];
function buildForcePoints(endPadding) {
while(forcePoints.length < (60-endPadding)/0.2) {
let minForce = -0.4;
let maxForce = 1.0;
let variance = 0.4;
let upper, lower;
let prev = forcePoints[forcePoints.length-1];
if(prev + variance > maxForce) {
upper = maxForce;
lower = maxForce - variance*2;
}else if(prev - variance < minForce) {
upper = minForce + variance*2;
lower = minForce;
}else{
upper = prev + variance;
lower = prev - variance;
}
let next = Math.random()*variance*2 + lower;
let num = Math.ceil(Math.random()*5);
for(let i=0; i<num; i++) {
forcePoints.push(next);
}
}
}
/*for(let tStep=1; tStep < 60; tStep++) {
forcePoints[tStep] = forcePoints[tStep-1] + (Math.random() - 0.5)*0.05;
forcePoints[tStep] = tStep % 2;
if(tStep > 5) forcePoints[tStep] = 0;
}*/
function f(t) {
let period = 0.2;
t = t/period;
let i = Math.floor(t);
let n = i+1;
let s = (t % 1);
let start = forcePoints[i] || 0;
let diff = (forcePoints[n] - start) || 0;
return start + diff * s;
}
var minT = 0;
var maxT = 60;
var stepSize = 0.01;
var period = 1.2; // period in seconds
var zeta = 0.35; // damping ratio. zeta < 1 is underdamped
/*
period = 2.2;
zeta = 0.05;
/**/
zeta = 1;
period = 1.2;
var positions = [0];
var velocities = [0];
var frequency = 1.0 / period;
var w1 = 2*Math.PI * frequency; // real angular frequency
var w0 = zeta < 1 ? (w1 / Math.sqrt(1 - zeta*zeta)) : w1;
var lambda = w0*zeta; // exponential decay rate
var timeTo0 = (zeta <= 1) ? (Math.log(0.005)/-lambda + 0.1) : (zeta*1.5/frequency);
timeTo0 = Math.max(2, Math.min(timeTo0, 10));
buildForcePoints(0 && timeTo0);
var k = w0 * w0;
var c = zeta * 2 * w0;
// note: m is 1
var steps = Math.ceil((maxT - minT) / stepSize);
function tStepToT(tStep) {
return tStep * stepSize +...