The default line width is 2 pixels. It can be changed by setting the context
ctx.lineWidth = 10;
This property can also be inspected, of course.
Draw lines of various widths.
A cap is the shape at the start or end of a line; a join is the shape where two segments of a polyline meet. Both caps and joins can be set to three different styles. These styles are easier to distinguish when the lines are thicker.
The context property
lineCap allows the string values
ctx.lineCap = "round";
A square cap or round cap extends half of the line’s width beyond the nominal endpoints of the line. A butt cap is really no cap at all; the line end is square, so it looks like a square cap, but it does not extend any further than the nominal endpoints.
The context property
lineJoin allows the values
ctx.lineJoin = "bevel";
If you don’t know what beveled or mitered corners are, it’s easier to look at a picture than to read a verbal explanation, so …
Draw lines and polylines with various caps and joins.
According to the specification, we should be able to set up the context to draw dashed lines. For example:
ctx.setLineDash([1, 4, 6, 3]);
The array argument is a list of line on, line off lengths. In this example, the line should draw a 1-pixel segment, skip 4 pixels, draw 6 pixels, skip 3 pixels, and then repeat that pattern for the rest of the line.
There should also be a
getLineDash method and a
These features are not yet implemented in Firefox or Chromium, so we’ll have to wait for them.
Draw various dashed lines.
Besides circles and arcs (and ellipses, if they were implemented), there are also quadratic and cubic Bézier curves. These curves were simultaneously developed (discovered/invented) by Paul de Casteljau and Pierre Bézier around 1960.1
There are infinitely many kinds, or orders, of Bézier curves.
Quadratic and cubic Bézier curves are the forms most commonly used in computer graphics (other than straight lines, of course), and these are the kinds we can draw on the HTML5 canvas.
A quadratic (second order) Bézier curve is defined by three points. Two of these are end points; the other is a control point (or as some would say, all three are control points). Let’s call them P1, P2, P3. The curve starts at P1, heading initially towards P2, then gradually curves around and ends at P3.
Think of it as a rubber band or string stretched between P1 and P3, but distorted by an attraction towards P2.
A quadratic Bézier curve is also a segment of a parabola.
Here are some examples:
This section is optional (so if you’re mathematically challenged, don’t panic—but I should tell you that to really shine in computational graphics, you should improve your understanding of geometry and mathematics in general—and I could say that of myself as well).
The quadratic curves are described by parametric equations for the functions x(t), y(t), where the variable t takes on all real number values between 0 and 1:
x(t) = x1(1 − t)2 + 2x2(1 − t)t + x3t2
y(t) = y1(1 − t)2 + 2y2(1 − t)t + y3t2
where P1 = (x1, y1), P2 = (x2, y2), P3 = (x3, y3).
These are quadratic equations in t, because the highest exponent of t is 2; that is why we call the curves “quadratic.”
Think of these equations as a “program” for generating all of the (x, y) coordinates by varying the parameter t. Of course, such a “program” would never finish running on any real computer, because there are infinitely many values of t, namely the real numbers between 0 and 1, inclusive. For each one of these infinitely many numbers t, the equations give us a point (x(t), y(t)) on the curve.
Note that when t = 0, the coefficients of x1 and y1 are 1, while the coefficients of x2, y2, x3, and y3 are 0. As t increases, the value of (1 − t)t, which is the coefficient of x2 and y2, increases until it reaches a maximum at t = 1 / 2. Thus the “influence” of P2 is at a maximum when t = 0. 5. As t continues to increase, the influence of P3 increases, eventually reaching 100% when t = 1.
The following statements draw the quadratic curve defined by P1 = (x1, y1), P2 = (x2, y2), P3 = (x3, y3):
ctx.moveTo(x1, y1); ctx.quadraticCurveTo(x2, y2, x3, y3);
Note that the context method
quadraticCurveTo draws a curve from wherever we are on the canvas (so it is not necessary to use
moveTo if you are already there), “through” (x2, y2), though not really through the point but influenced by it, to (x3, y3).
Click the mouse to set the middle control point in a quadratic Bézier curve.
A cubic (third order) Bézier curve is defined by four points. Two of these are end points; the other two are control points (or as some would say, all four are control points). Let’s call them P1, P2, P3, P4. The curve starts at P1, heading initially towards P2, then gradually curves around towards P3, then gradually curves around towards P4, where it ends.
Think of it as a rubber band or string stretched between P1 and P4, but distorted by attractions towards P2 and P3.
Here are some examples:
x(t) = x1(1 − t)3 + 3x2(1 − t)2t + 3x3(1 − t)t2 + x4t3
y(t) = y1(1 − t)3 + 3y2(1 − t)2t + 3y3(1 − t)t2 + y4t3
These are cubic equations in t, because the highest exponent of t is 3; that is why we call the curves “cubic.”
As with quadratic curves, when t = 0, the influence of P1 is 100%. As t increases, the influence of P2 grows, until it reaches a certain maximum; the infuence of P3 then surpasses it; and finally the influence of P4 becomes dominant.
The following statements draw the cubic curve defined by P1 = (x1, y1), P2 = (x2, y2), P3 = (x3, y3), P4 = (x4, y4:
ctx.moveTo(x1, y1); ctx.bezierCurveTo(x2, y2, x3, y3, x4, y4);
quadraticCurveTo, the method
bezierCurveTo makes the curve go from wherever we are on the canvas, through the influence of the intermediate points, but not really to them; it only goes to the final point (x4, y4).
Click the mouse to set the middle control points (left click for P2, shift left click for P3) in a cubic Bézier curve.
Have you noticed that with a quadratic (order 2) curve you get one “attractor” or one “bump” in the curve, and with cubic (order 3) curves you get two “attractors” or “bumps”? In general, in an order N curve, you would get to have N − 1 attractors or bumps in the curve.
Although higher-order Bézier curves (N > 3) exist mathematically, they are computationally more difficult, and therefore less used in practical computer graphics. Instead, we tend to chain together curves of the 2nd or 3rd order. These are called “paths” in some drawing programs (see next section).
It is extremely hard to design Bézier curves numerically: you would have to do a lot of educated guessing and trial and error to get the numbers right. There is little point in doing this. What I prefer to do is use a visual graphics editor such as Inkscape or GIMP to design the curves. These programs allow you to create what they call “paths.” These “paths” are not the same as the “paths” in the HTML5 canvas; they are just sequences of connected Bézier curves. Once you have designed the path visually, you can then extract the control point data from the graphics editor for use with a canvas script or (as we’ll see later) SVG graphics. In fact, Inkscape is an SVG editor, so you can directly save or export the SVG file.
Bézier curves are not only used for the HTML5 canvas. They are widely used in all sorts of graphics applications—GIMP and Inkscape, already mentioned; Cairo 2D graphics API, SVG (covered later in this course), 3D generalizations, and animations. So, no matter what tool or API you are using for graphics work, it is useful to know about Bézier curves!