JSFiddle - React, Tailwind, and code Playground
HTML
<center><canvas id="myCanvas" width="600" height="400" style="background-color:rgba(100,100,255,1); border:3px solid rgba(0,0,0,1);"></canvas></center>
<script>
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
var i;
var g = 1;
var bob = [{m:1,x:20,y:20,vx:0,vy:0,ax:0,ay:0,fx:0,fy:0}];
var rod = [];
for(i=0; i<bob.length; i++){
rod.push({x1:canvas.width/2,y1:0,x2:bob[i].x,y2:bob[i].y,a:0,t:0,l:0});
rod[i].l = Math.pow( Math.pow(rod[i].x2-rod[i].x1,2) + Math.pow(rod[i].y2-rod[i].y1,2) ,0.5);
}
var int=self.setInterval(function(){loop()},40); function loop() {
context.clearRect(0,0,canvas.width,canvas.height);
for(i=0; i<rod.length; i++){
rod[i].a = Math.atan( (rod[i].x2-rod[i].x1) / (rod[i].y2-rod[i].y1) );
//rod[i].l = Math.pow( Math.pow(rod[i].x2-rod[i].x1,2) + Math.pow(rod[i].y2-rod[i].y1,2) ,0.5);
rod[i].t = Math.cos(rod[i].a)*bob[i].m*g + bob[i].m*(Math.pow(bob[i].vx,2)+Math.pow(bob[i].vy,2))/rod[i].l;
}
for(i=0; i<bob.length; i++){
//resolve forces
bob[i].fx = bob[i].fy = 0;
bob[i].fx -= Math.sin(rod[i].a)*rod[i].t;
bob[i].fy -= Math.cos(rod[i].a)*rod[i].t;
bob[i].fy += bob[i].m*g;
//acceleration
bob[i].ax = bob[i].fx/bob[i].m;
bob[i].ay = bob[i].fy/bob[i].m;
//velocity
bob[i].vx += bob[i].ax;
bob[i].vy += bob[i].ay;
//position
bob[i].x += bob[i].vx;
bob[i].y += bob[i].vy;
}
for(i=0; i<rod.length; i++){
rod[i].x2=bob[i].x;
rod[i].y2=bob[i].y;
}
drawRod(rod[0].x1,rod[0].y1,rod[0].x2,rod[0].y2);
drawBob(bob[0].x,bob[0].y,bob[0].r);
}
function drawBob(x,y){
context.beginPath();
context.arc(x,y,10,0,Math.PI*2);
context.fillStyle = 'rgba(200,10,50,1)';
context.fill();
context.lineWidth = 3;
context.strokeStyle = 'rgba(0,0,0,1)';
context.stroke();
}
function drawRod(x1,y1,x2,y2){
context.beginPath();
context.moveTo(x1,y1);
context.lineTo(x2,y2);
context.lineWidth =...