You can apply the quadratic equation of a bezier curve, since a parabola is, generally speaking, a special case of a second-order curve, which in particular is also a bezier curve with 3 three control points.
All that needs to be done is to determine the bending point p1
which in the case of a parabola should be equidistant from the initial and final points p0, p2
.
To generate motion points, you must apply the Bezier curve equation.
An example in jsfiddle :
var cnv = document.getElementById("cnv"); var ctx = cnv.getContext("2d"); var path = [], id = 0, speed = 1; var point = { x: 0, y: 0, draw: function() { ctx.beginPath(); ctx.arc(this.x, this.y, 10, 0, 2*Math.PI, true); ctx.fill(); ctx.closePath(); } }; function getCurvePath(x0, y0, x1, y1, xdepth, ydepth) { var p0 = {x: x0, y: y0}, p2 = {x: x1, y: y1}, p1 = {x: xdepth + (p0.x + p2.x) * 0.5, y: ydepth + (p0.y + p2.y) * 0.5}, x, y, t = 0, path = []; for (; t <= 1; t += 0.01) { x = (1 - t)*(1 - t)*p0.x + 2*t*(1 - t)*p1.x + t*t*p2.x; y = (1 - t)*(1 - t)*p0.y + 2*t*(1 - t)*p1.y + t*t*p2.y; path.push({x: x, y: y}); } return path; } function drawCurve(path) { ctx.beginPath(); for (var i = 0; i < path.length; i++) { ctx.lineTo(path[i].x, path[i].y); } ctx.stroke(); ctx.closePath(); } path = getCurvePath(250, 350, 250, 20, 450, 0); var i = 0; function render() { ctx.clearRect(0, 0, cnv.width, cnv.height); drawCurve(path); if (i < path.length) point.x = path[i].x, point.y = path[i].y; else { i = 0; } i += speed; point.draw(); id = requestAnimationFrame(render); } render();
<canvas id="cnv" width="800" height="800"></canvas>
Actually, by changing the points p0, p1, p2
you can get any parabola whose director is parallel to one of the axes, but you should pay attention to the xdepth
and ydepth
one of which must be zero, otherwise the parabola will not work