JSFiddle - React, Tailwind, and code Playground

by Guido Belluomo

HTML

<canvas id="canvas" width="300" height="300"></canvas>

JavaScript

function ApproxSpring(value, targetValue, strength, damping) {
    let vel = 0;

    this.calc = function (deltaTime) {
        vel += (targetValue - value) * strength * deltaTime;
        vel *= Math.pow(damping, deltaTime);
        value += vel * deltaTime;
    }

    this.set = function (newValue, newTargetValue, newStrength, newDamping)
    {
        value = newValue
        targetValue = newTargetValue
        strength = newStrength
        damping = newDamping
    }

    this.setValue = function (newValue)
    {
        value = newValue;
    }

    this.setTargetValue = function (newTargetValue)
    {
        targetValue = newTargetValue;
    }

    this.setStrength = function (newStrength)
    {
        strength = newStrength;
    }

    this.setDamping = function (newDamping)
    {
        damping = newDamping;
    }

    this.getValue = function ()
    {
        return value;
    }

    this.getTargetValue = function ()
    {
        return targetValue;
    }

    this.getStrength = function ()
    {
        return strength;
    }

    this.getDamping = function ()
    {
        return damping;
    }
}

const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
const springX = new ApproxSpring(150, 150, 200, 0.0001);
const springY = new ApproxSpring(150, 150, 200, 0.0001);

function updateCircle()
{
	ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.beginPath();
  ctx.arc(springX.getValue(), springY.getValue(), 20, 0, 2 * Math.PI);
  ctx.fillStyle = 'black';
  ctx.fill();
}

let lastUpdate = 0;
function update()
{
	const curTime = performance.now();
  const deltaTime = (curTime - lastUpdate) / 1000;
  lastUpdate = curTime;
  
	requestAnimationFrame(update);
  springX.calc(deltaTime);
  springY.calc(deltaTime);
}

function animate()
{
	updateCircle();
	requestAnimationFrame(animate);
}

update();
animate();

function bounceAround()
{
  setTimeout(function() {
    springX.setTargetValue(100)
    setTimeout(function() {
   ...