Animate circle along curved line

Canvas & quadraticCurve

by bradoyler

HTML

<h2>Flight Sim (canvas)</h2>
<div class="container">
  <img src="https://user-images.githubusercontent.com/425966/30492475-9657eea0-9a0e-11e7-8c44-623a1f994eec.png" alt="">
  <canvas id="canvas" width="680" height="480"></canvas>
</div>

CSS

#canvas {
  border: 1px solid #ccc;
  position: absolute;
  left: 0;
  top: 0;
}

.container {
  height: 600px;
  position: relative;
}

JavaScript

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

const points = generatePoints(600)

// set starting values
var fps = 20;
var percent = 0
var direction = 1;

animate();

function animate() {
  percent += direction;
  if (percent < 0) {
    percent = 0;
    direction = 1;
  }
  
  if (percent > 100) {
    percent = 100;
    direction = -1;
  }

  draw(percent);

  // request another frame
  setTimeout(function() {
    if (direction !== 0) {
    	requestAnimationFrame(animate);
    }
  }, 1000 / fps);
}

// draw the current frame based on sliderValue
function draw(percent) {
  // redraw path
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  
  function eachPoint(point) {
    var startPoint = point.start
    var endPoint = point.end
    // console.log(startPoint, '>>')
    var wayPoint = getWaypoint(startPoint, endPoint, 30)
    var controlPt = {
      x: wayPoint.x,
      y: wayPoint.y - 50
    }
    ctx.lineWidth = 2;

    ctx.beginPath();
    ctx.moveTo(startPoint.x, startPoint.y);
    // ctx.quadraticCurveTo(controlPt.x, controlPt.y, endPoint.x, endPoint.y);
    // ctx.lineTo(endPoint.x, endPoint.y);
    ctx.strokeStyle = '#eee';
    ctx.stroke();

    // draw the tracking rectangle
    var percentFactor = percent / 100;
    var xy = getQuadraticBezierXY(startPoint, controlPt, endPoint, percentFactor);
    drawDot(xy, 'blue');
  }
  
  // var startPoint = { x: 47, y: 260}
  // var endPoint = { x: 612, y: 170}
  points.forEach(eachPoint)
}

// draw tracking dot at xy
function drawDot(point, color) {
  ctx.fillStyle = color;
  ctx.strokeStyle = color;
  ctx.lineWidth = 2;
  ctx.beginPath();
  ctx.arc(point.x, point.y, 1.5, 0, Math.PI * 2, false);
  ctx.closePath();
  ctx.fill();
  ctx.stroke();
}

// just for demo
function generatePoints (count) {
  var points = []
  var evenPoint = { start: { x: 10, y: 10 }, end: { x: 450, y: 15 }}
  var oddPoint = {start: { x: 450, y: 15 },end: { x: 10, y: 10 }}

  for (var i = 0; i <...