- HTML5 Canvas Cookbook
- Eric Rowell
- 724字
- 2021-08-27 12:08:07
Working with the context state stack to save and restore styles
When creating more complex HTML5 canvas applications, you'll find yourself needing a way to revert back to previous style combinations so that you don't have to set and reset dozens of style properties at different points in the drawing process. Fortunately, the HTML5 canvas API provides us with access to the context state stack which allows us to save and restore context states. In this recipe, we'll demonstrate how the state stack works by saving the context state, setting the global alpha, drawing a transparent circle, restoring the state stack to the state before we set the global alpha, and then drawing an opaque square. Let's take a look!

Getting ready...
Before we cover the canvas state stack, it's imperative that you understand how a stack data structure works (if you already do, you can skip to the How it works section).
A stack data structure is a last in, first out (LIFO) structure. Stacks have three major operations – push, pop, and stack top. When an element is pushed onto the stack, it gets added to the top of the stack. When the stack is popped, the top element is removed from the stack. The stack top operation simply returns the element at the top of the stack.

Take a look at the preceding diagram, which represents the state of a stack throughout multiple actions. In step 1, we start out with a stack containing one element, element "a". In step 2, the "b" element is pushed onto the stack. In step 3, the "c" element is pushed onto the stack. In step 4, we pop the stack, which removes the last element pushed onto the stack. Since element "c" was at the top of the stack, it's the element that's removed. In step 5, we again pop the stack, which removes the last element pushed onto the stack. Since element "b" was at the top of the stack, it's the element that's removed.
As we will see in the next section, stacks are a wonderful data structure for saving states as they change over time, and then restoring them by popping the stack.
How to do it...
Follow these steps to draw an opaque square on top of a transparent circle:
- Define a 2D canvas context:
window.onload = function(){ var canvas = document.getElementById("myCanvas"); var context = canvas.getContext("2d");
- Draw a rectangle:
// draw rectangle context.beginPath(); context.rect(150, 30, 130, 130); context.fillStyle = "blue"; context.fill();
- Save the context state with
save()
, set the global alpha of the canvas using theglobalAlpha
property, draw a circle, and then restore the canvas state withrestore()
:// wrap circle drawing code with save-restore combination context.save(); context.globalAlpha = 0.5; // set global alpha context.beginPath(); context.arc(canvas.width / 2, canvas.height / 2, 70, 0, 2 * Math.PI, false); context.fillStyle = "red"; context.fill(); context.restore();
- Draw another rectangle (which will be opaque) to show that the context state has been restored to the state before the global alpha property was set:
// draw another rectangle context.beginPath(); context.rect(canvas.width - (150 + 130), canvas.height - (30 + 130), 130, 130); context.fillStyle = "green"; context.fill(); };
- Embed the canvas tag inside the body of the HTML document:
How it works...
As you can see in the preceding code, by wrapping the circle drawing code with a save-restore combination, we are essentially encapsulating any styles that we use between the save()
method and the restore()
method such that they don't affect the shapes drawn afterwards. Save-restore combinations can be thought of as a way to induce style scoping, similar to the way that a function induces variable scope in JavaScript. Although you might be saying "Well that sounds like a complicated way to set the globalAlpha back to 1!" Hold on partner. In the real world, you'll typically be dealing with lots of different combinations of styles for different sections of code. In this type of scenario, save-restore combinations are a life-saver. Writing complex HTML5 canvas applications without save-restore combinations is a lot like building a complex web application with one big block of JavaScript code using nothing but global variables. Yikes!
There's more...
As we'll see in Chapter 4, Mastering Transformations, another common usage of the state stack is to save and restore transformation states.
See also...
- Handling multiple transforms with the state stack in Chapter 4