JSFiddle - React, Tailwind, and code Playground

by ghostoy

HTML

<canvas id="painter" width="600" height="400"></canvas>

JavaScript

var R = 50;
var L = 50;
var M = 1;
var m = 1;
var g = 9.8;
var x = -R;
var y = 0;
var vx = 0;
var vy = 0;
var ax = 0;
var ay = -g;
var V = 0;
var X = 0;
var time = 0;
var t;
var LIMIT = 500;
var limit_count = 0;
var ctx = document.getElementById('painter').getContext('2d');

function calcAndPaint() {
  var x1 = x + vx * t;
  var y1 = y + vy * t;
  var vx1 = vx + ax * t;
  var vy1 = vy + ay * t;
	var ax1 = ((vx*vx + vy*vy) / R + g * Math.abs(y) / R) * Math.abs(x) / R;
  var ay1 = -g + ((vx*vx + vy*vy) / R + g * Math.abs(y) / R) * Math.abs(y) / R;
  x = x1;
  y = y1;
  vx = vx1;
  vy = vy1;
  ax = ax1;
  ay = ay1;
  if (t === 0) {
  	ctx.moveTo(x1, y1);
  } else {
  	ctx.lineTo(x1, y1);
    ctx.stroke();
  }
}

ctx.save();
ctx.translate(300, 200);
ctx.scale(1, -1);
ctx.arc(0, 0, R, Math.PI, Math.PI * 3 / 2);
ctx.stroke();
ctx.restore();
ctx.beginPath();
ctx.strokeStyle = 'red';

function draw() {
  ctx.save();
  ctx.translate(300, 200);
  ctx.scale(1, -1);
	if (time === 0) {
  	t = 0;
  } else {
  	t = (Date.now() - time) / 1000;
  }
  time = Date.now();
  calcAndPaint();
  ctx.restore();
  if (x <= 0) {
    limit_count ++;
    if (limit_count > LIMIT) {
    	alert('模拟次数超过' + LIMIT + '次,终止')
    } else {
  		requestAnimationFrame(draw);
    }
  }
}

draw();