JSFiddle - React, Tailwind, and code Playground

by moritzkobrna

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.5/dat.gui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/victor/1.1.0/victor.js"></script>
<canvas id="canvas" width="800" height="800"></canvas>

<button onClick={window.doStep()}>Step</button>

JavaScript 1.7

const Vector = Victor;
const gui = new dat.GUI();

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

const planets = [
	{
  	position: [180, 140],
    radius: 10,
  },
  {
  	position: [300, 300],
    radius: 10,
  },
];

const emitters = [
	{
  	position: [101, 101],
    angle: -90,
    velocity: 4,
  },
];

let bullets = [];

const step = (frame, ctx) => {
  bullets.filter((b) => b.alive).forEach((bullet) => {
  	const { path, vector } = bullet;
  
  	const [lastX, lastY] = path[path.length - 1];
      
    planets.forEach(({ position: [x, y], radius }) => {
    
    	const dist = (new Vector(lastX, lastY).distance(new Vector(x, y)));
      const force = (1 / Math.pow(dist, 2)) * radius * 100;
      
      
      if (dist <= radius) return bullet.alive = false;
      
      
      const forceDirection = new Vector(x, y).subtract(new Vector(lastX, lastY)).normalize();
    
    	const forceVector = forceDirection.multiply(new Vector(force, force));
    
    	bullet.vector = bullet.vector.add(forceVector);
      
    });
    
    path.push([lastX + bullet.vector.x, lastY + bullet.vector.y]);
  });
};

const draw = (ctx) => {
	// Clear
	ctx.clearRect(0, 0, 800, 800);

	// Draw planets
  planets.forEach(({ position: [x, y], radius }) => {
  	ctx.fillStyle = 'red';
  	ctx.beginPath();
		ctx.arc(x, y, radius, 0, 2 * Math.PI);
		ctx.fill();
  });
  
  // Draw bullets
  bullets.forEach(({ path, vector  }) => {
  	ctx.beginPath();
    const [firstX, firstY] = path.slice().shift();
    
  	ctx.moveTo(path[0][0], path[0][1]);
    
    for (let i = 1; i < path.length - 2; ++i) {
      const dx = (path[i][0] + path[i + 1][0]) / 2
      const dy = (path[i][1] + path[i + 1][1]) / 2
      ctx.quadraticCurveTo(path[i][0], path[i][1], dx, dy)
    }
    
    ctx.quadraticCurveTo(path[path.length - 2][0], path[path.length - 2][1], path[path.length - 1][0], path[path.length - 1][1]);

    ctx.stroke();
  });
};

const simulate = () => {
 ...