Canvas 2D Context

Part 4. Graphics State

Nothing is more elusive than the current state of affairs...
Anonymous politician

Graphics State

Each rendering context maintains a set of drawing states. The current state contains the collection of graphics control parameters. Such path construction and painting attributes as strokeStyle, fillStyle, lineWidth, lineCap, lineJoin, miterLimit can be varied dynamically by using the drawing state stack. The stack is a data structure built on the LIFO (last in, first out) basis. CanvasRenderingContext2D has the save() and restore() methods required for working with the stack:

// pushing the first set of style attributes onto the stack
context.lineWidth=12;
context.lineJoin="round";
context.strokeStyle="crimson";
context.fillStyle="cornsilk";
context.save();

// pushing the second set of style attributes onto the stack
context.lineWidth=7;
context.lineJoin="bevel";
context.strokeStyle="darkblue";
context.fillStyle="floralwhite";
context.save();

// pushing the third set of style attributes onto the stack
context.lineWidth=4;
context.lineJoin="miter";
context.strokeStyle="lightseagreen";
context.fillStyle="lavender";
context.save();

// the last element of the drawing state stack is popping
context.restore();
context.beginPath();
context.rect(10, 10, 400, 100); // this rectangle's contour width is 4; line join style is miter
context.fill(); // lavender color is applied to fill the rectangle
context.stroke(); // lightseagreen color is applied to stroke the contour of the rectangle

// the next set of attributes is popping from the stack
context.restore();
context.beginPath();
context.rect(10, 150, 400, 100); // this rectangle's contour width is 7; line join style is bevel
context.fill(); // floralwhite color is applied to fill the rectangle
context.stroke(); // darkblue color is applied to stroke the contour of the rectangle

// the first element of the stack is popping
context.restore();
context.beginPath();
context.rect(10, 290, 400, 100); // this rectangle's contour width is 12; line join style is round
context.fill(); // cornsilk color is applied to fill the rectangle
context.stroke();// crimson color is applied to stroke the contour of the rectangle

Convenience Methods for Rectangles

The rectangle can be viewed as the main building block in two-dimensional graphics. No wonder, CanvasRenderingContext2D provides a set of convenience methods to draw rectangles directly onto the canvas. The strokeRect(x, y, width, height) method creates the outline of a rectangle with the upper left corner positioned at (x, y) and dimensions specified by width and height parameters. Applying the fillRect(x, y, width, height) method results in filling the interior of a rectangle. And the clearRect(x, y, width, height) clears all pixels within the specified rectangle's outline.

// pushing the set of stroke attributes onto the stack
context.lineWidth=7;
context.lineJoin="round";
context.strokeStyle="crimson";
context.save();

// pushing the fill style attribute onto the stack
context.fillStyle="navy";
context.save();

//filling the rectangle
context.restore();
context.fillRect(10, 10, 400, 100);

// stroking the other rectangle
context.restore();
context.strokeRect(10, 150, 400, 100);

// the area with width=500, height=500 is cleared
canvas.addEventListener(
 "click", // event type
 function(event) { // anonymous function
  context.clearRect(0, 0, 500, 500);
 },
 false
);

Summary: Path Construction / Painting Methods and Properties

starting / ending construction
context.beginPath()
context.moveTo(x, y)
context.closePath()


drawing lines
context.lineTo(x, y)

drawing curves
context.quadraticCurveTo(cpx, cpy, x, y);
context.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y)


drawing arcs
context.arcTo(x1, y1, x2, y2, radius);
context.arc(x, y, radius, startAngle, endAngle, anticlockwise)


drawing / clearing rectangles
context.rect(x, y, width, height)
context.strokeRect(x, y, width, height)
context.fillRect(x, y, width, height)
context.clearRect(x, y, width, height)


stroking
context.stroke()
context.strokeRect(x, y, width, height)
context.strokeStyle
context.lineWidth
context.lineCap
context.lineJoin
context.miterLimit


filling
context.fill()
context.fillStyle
context.fillRect(x, y, width, height)


gradients
context.createLinearGradient(x0, y0, x1, y1)
context.createRadialGradient(x0, y0, radius0, x1, y1, radius1)
gradient.addColorStop(offset, color);


patterns
context.createPattern(HTMLCanvasElement)
context.createPattern(HTMLImageElement)
context.createPattern(HTMLVideoElement)


graphics state
context.save()
context.restore()