JIT
Grid - Untitled
In one html file create a triple pendulum animation that follows the laws of gravity. No controls, no interactions, simply the animation. Make sure each intercept from one pendulum to another leaves a trail.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Triple Pendulum Animation</title> <style> body, html { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; background: #000; } canvas { display: block; width: 100%; height: 100%; } </style> </head> <body> <canvas id="canvas"></canvas> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight;
const G = 0.5; // Gravity constant
const trails = [];
const pendulumCount = 3;
const pendulums = [];

class Pendulum {
  constructor(x, y, length, angle, velocity, mass) {
    this.x = x;
    this.y = y;
    this.length = length;
    this.angle = angle;
    this.velocity = velocity;
    this.mass = mass;
  }

  update() {
    const acceleration = (-G / this.length) * Math.sin(this.angle);
    this.velocity += acceleration;
    this.angle += this.velocity;
    this.x = pendulums[pendulums.indexOf(this) - 1]?.x || this.x + this.length * Math.sin(this.angle);
    this.y = pendulums[pendulums.indexOf(this) - 1]?.y || this.y + this.length * Math.cos(this.angle);
  }

  draw() {
    ctx.beginPath();
    ctx.moveTo(pendulums[pendulums.indexOf(this) - 1]?.x || this.x, pendulums[pendulums.indexOf(this) - 1]?.y || this.y);
    ctx.lineTo(this.x, this.y);
    ctx.strokeStyle = '#fff';
    ctx.lineWidth = 2;
    ctx.stroke();
    ctx.closePath();
  }
}

function init() {
  for (let i = 0; i < pendulumCount; i++) {
    const length = 100 + i * 50;
    const angle = Math.PI / 4;
    const velocity = 0;
    const mass = 1;
    const x = canvas.width / 2;
    const y = canvas.height / 2;
    pendulums.push(new Pendulum(x, y, length, angle, velocity, mass));
  }
}

function drawTrails() {
  trails.forEach((trail, index) => {
    ctx.strokeStyle = `rgba(255, 255, 255, ${1 - index / trails.length})`;
    ctx.beginPath();
    ctx.moveTo(trail[0].x, trail[0].y);
    for (let i = 1; i < trail.length; i++) {
      ctx.lineTo(trail[i].x, trail[i].y);
    }
    ctx.stroke();
    ctx.closePath();
  });
}

function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  pendulums.forEach(pendulum => {
    pendulum.update();
    pendulum.draw();
  });

  trails.push(pendulums.map(p => ({ x: p.x, y: p.y })));
  if (trails.length > 100) trails.shift();
  drawTrails();

  requestAnimationFrame(animate);
}

init();
animate();
</script> </body> </html>
Updated files
v1