HTML CANVAS DRAWING DETERMINING COORDINATES ON A BÉZIER CURVE
The HTML 5 canvas API allows you to draw bézier curves and quadratic curves out of the box. The API is easy to use, and the curves come out beautifully. But what if you wanted to draw something else at the halfway point of a curve? You’d have to know the coordinates of a point on the curve to be able to do so. And, if you wanted to draw an arrowhead halfway down the curve in the direction of the curve, you’d have to know the coordinates as well as the angle of the curve at that point.
In this tutorial, we’ll show you simple code that allows you to calculate the coordinate and angle of any point on a HTML 5 canvas bézier or quadratic curve.
Drawing a curve
The HTML 5 API has a method for drawing bézier curves:
The parameters are:
cp1x
: The x axis of the coordinate for the first control point.cp1y
: The y axis of the coordinate for the first control point.cp2x
: The x axis of the coordinate for the second control point.cp2y
: The y axis of the coordinate for the second control point.x
: The x axis of the coordinate for the end point.y
: The y axis of the coordinate for the end point.
A snippet (from MDN) shows how to draw a curve. The control points are red, while the start and end points are blue.
Clearly, the API allows you to provide end point coordinates and control points, but no way to access intermediate coordinates.
How are bezier curves really drawn?
Bézier curves obey a mathematical formula that you can look up on Wikipedia. You’ll find various formulas there; the one we’re interested in is the cubic bézier curve:
This formula allows you to draw your own bézier curves (though you won’t have to, because HTML 5 canvas already takes care of that) as well as calculate the (x,y) coordinates of any point along the curve.
The various P symbols in the formula are (x,y) coordinate pairs with the following meaning:
- P0: Start coordinate pair
- P1: Control point 1
- P2: Control point 2
- P3: End coordinate pair
The t symbol, meanwhile, goes from 0 to 1 and determines how far we are along the curve. For t=0, B will be the start coordinate, for t=1, B will be the end coordinate, and for t=0.5, B will be the coordinate exactly halfway the curve.
Calculating coordinates along a cubic bézier curve in JavaScript
All we have to do is transcribe the Bézier formula to JavaScript.
Now, if we provide a start coordinate sx, sy
, an end coordinate ex, ey
, control points and a value of t
between 0 and 1, we’ll get the (x,y) coordinate of the point on the curve at t
:
Calculating coordinates along a quadratic bézier curve
The HTML 5 canvas API also support quadratic bézier curves. These are actually simpler than cubic bézier curves and only use one control point. They, too, have a formula:
The various P symbols in the formula are (x,y) coordinate pairs with the following meaning:
- P0: Start coordinate pair
- P1: Control point
- P2: End coordinate pair
And, again, we can convert this to a JavaScript function:
Now, if we provide a start coordinate sx, sy
, an end coordinate ex, ey
, a control point and a value of t
between 0 and 1, we’ll get the (x,y) coordinate of the point on the curve at t
:
Calculating the curve angle anywhere along a cubic bézier curve
You may have a use case where you need to find the angle that a bézier curve makes with the x-axis at some point. Maybe you’d like to draw an arrowhead at a point along the curve, neatly pointing in the direction of the curve.
The angle of a cubic bézier curve at any point is determined by calculating the derivative of the cubic bézier curve formula, which looks like this:
We can convert this to a JavaScript function:
… and this will give us the angle (in radians) between the bézier curve and the horizontal x-axis at point t
.
We can put this to use and draw an arrowhead at 20% along the bézier curve, which neatly follows the angle of the curve at that point:
Calculating the curve angle anywhere along a quadratic bézier curve
Of course, we can do the same thing for a quadratic bézier curve. The derivative of the quadratic bézier curve formula looks like this:
And converted to a JavaScript formula:
Happy coding!