JSFiddle - React, Tailwind, and code Playground

by Steven Lambert

HTML

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Canvas</title>
    <style>
        body {
          position: relative;
        }
    
        canvas {
            border: 1px solid black;
            background-color: transparent;
        }
        
        #trace {
          position: absolute;
          left: 0;
          top: 0;
          right: 0;
          bottom: 0;
          background-color: rgb(51,51,51);
          z-index: -1;
        }

        body {
            margin: 0;
        }
    </style>
</head>
<body>
    <canvas id="trace"></canvas>
    <canvas id="pendulum"></canvas>
</body>
</html>

JavaScript

var canvas = document.querySelector('#pendulum');
var traceCanvas = document.querySelector('#trace');

w = window.innerWidth
h = window.innerHeight

canvas.width  = traceCanvas.width =  w;
canvas.height = traceCanvas.height = h;
var c = canvas.getContext('2d')
var c2 = canvas.getContext('2d')
var traceCtx = traceCanvas.getContext('2d');

var r1 = 200
var r2 = 200
var m1 = 20
var m2 = 20
var a1 = Math.PI /2
var a2 = Math.PI /2
var a1_v = 0
var a2_v = 0
var g = 1
var trace = []



function animate(){
    requestAnimationFrame(animate);
    c.clearRect(0,0, innerWidth, innerHeight);

    num1 = -g * (2 * m1 + m2) * Math.sin(a1);
  num2 = -m2 * g * Math.sin(a1-2*a2);
  num3 = -2* Math.sin(a1-a2)*m2;
  num4 = a2_v*a2_v*r2+a1_v*a1_v*r1* Math.cos(a1-a2);
  den = r1 * (2*m1+m2-m2* Math.cos(2*a1-2*a2));
  a1_a = (num1 + num2 + num3*num4) / den;

  num1 = 2 * Math.sin(a1-a2);
  num2 = (a1_v*a1_v*r1*(m1+m2));
  num3 = g * (m1 + m2) * Math.cos(a1);
  num4 = a2_v*a2_v*r2*m2* Math.cos(a1-a2);
  den = r2 * (2*m1+m2-m2* Math.cos(2*a1-2*a2));
  a2_a = (num1*(num2+num3+num4)) / den;

    x1 = r1 * Math.sin(a1);
  y1 = r1 * Math.cos(a1);
  x2 = x1 + r2 * Math.sin(a2);
    y2 = y1 + r2 * Math.cos(a2);

    x1 = x1 + w/2;
    y1 = y1 + h/4;

    x2 = x2 + w/2;
    y2 = y2 + h/4;

    if(trace.includes([x2, y2]) != true){
        trace.push([x2,y2]);
        var i = trace.length-1;
        
        if (i > 1) {
          traceCtx.strokeStyle = 'white'
          traceCtx.beginPath();
          traceCtx.moveTo(trace[i][0], trace[i][1])
          traceCtx.lineTo(trace[i-1][0], trace[i-1][1])
          traceCtx.stroke();
        }
    }
    
    // Draw all   
    c.beginPath();
    c.moveTo(w/2, 150);
    c.lineTo(x1, y1);
    c.moveTo(x1, y1);
    c.lineTo(x2, y2);
    c.strokeStyle = 'white';
    c.stroke();
    c.closePath();

    c.beginPath();
    c.arc(x1, y1, m1, 0, 360, false);
    c.arc(x2, y2, m2, 0, 360, false);
    c.fillStyle = 'white';
    c.fill();
    c.closePath();


 ...