The 2D context
Each <canvas> element has a 2D context object that maintains the drawing state and renders 2D drawings on the <canvas>. To draw and manipulate 2D graphics on the <canvas>, we go through the context and use its drawing functions.
The drawing state
The drawing state of the <canvas> element is stored by the context and it consists of the current:
- transformation matrix;
- clipping region;
- strokeStyle value;
- fillStyle value;
- globalAlpha value;
- lineWidth value;
- lineCap value;
- lineJoin value;
- dash list;
- lineDashOffset value;
- font value;
- textAlign value;
- textBaseline value;
- miterLimit value;
- shadowOffsetX value;
- shadowOffsetY value;
- shadowBlur value;
- shadowColor value; and
- globalCompositeOperation value.
These objects and attributes are discussed in detail in the relevant sections of the documentation.
The current path, bitmap, and hit region list are not part of the drawing state. The current path is persistent, and can only be reset by calling the beginPath() function. The current bitmap and hit region list are properties of the <canvas> element, not the context.
The 2D context’s coordinate space
The 2D context’s coordinate space is a flat Cartesian surface with x-values increasing going to the right, y-values increasing going down, and angles measured clockwise from the positive x-axis. The origin (0, 0) is initially positioned in the top left corner of the <canvas>, but the coordinate space may be translated, rotated, scaled, and otherwise transformed.
Store a reference to the 2D context in a variable
To get a reference to a <canvas> element’s 2D context, use the element’s getContext() function and pass it the string "2d". This reference can be stored in a variable and used to communicate with the context to draw on the <canvas> element.
If we do not have a reference to the <canvas> element stored in a variable, we can get a reference to the 2D context directly:
A <canvas> element only has one 2D context. If getContext("2d") is called multiple times, the same context object with the same current drawing state is returned each time.
Get a reference to the <canvas>
Each context automatically stores a reference to its <canvas> element. We can access this reference using the context’s canvas attribute:
Because I rarely need to access the <canvas> element itself, I typically do not store a reference to the <canvas> in a variable and only access it through its context.
Get the width and the height of the <canvas>
Since the context stores a reference to its <canvas> element, we can get the width and the height of the <canvas> through the context.
Save the current drawing state
Drawing states are stored by the context in a stack. The current drawing state is at the top of the stack. By saving the current drawing state, the context can return to this drawing state at a later point in time.
Restore the context to a previous drawing state
Restoring the context pops the current drawing state off of the stack and restores the last drawing state saved. To restore a drawing state that was saved earlier, keep restoring the context until that drawing state is at the top of the stack. Once a drawing state has been popped off the stack, it cannot be recovered. Basically, the context has an undo option, but not a redo option.
Once a saved drawing state has been restored, it becomes the current drawing state and is no longer saved. To return to this drawing state again later, we need to save it again.
Restore the context to its original state
Removing the reference to the context stored in the ctx variable and calling getContext("2d") a second time does not reinitialize the context or give us a new one. A <canvas> element only has one 2D context, and it is persistent. To restore a context to its original state, we need to save the drawing state before making any changes to it.
A good time to do that is immediately after storing a reference to the context for the first time. Then we can use the context’s restore() function to restore it to this saved original state.
The context can also be restored to its original state by reinitializing the <canvas> element, but that will also clear any drawings.