官术网_书友最值得收藏!

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!

Working with the context state stack to save and restore styles

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.

Getting ready...

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:

  1. Define a 2D canvas context:
    window.onload = function(){
        var canvas = document.getElementById("myCanvas");
        var context = canvas.getContext("2d");
  2. Draw a rectangle:
        // draw rectangle
        context.beginPath();
        context.rect(150, 30, 130, 130);
        context.fillStyle = "blue";
        context.fill();
  3. Save the context state with save(), set the global alpha of the canvas using the globalAlpha property, draw a circle, and then restore the canvas state with restore():
        // 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();
  4. 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();
    };
  5. Embed the canvas tag inside the body of the HTML document:
    <canvas id="myCanvas" width="600" height="250" style="border:1px solid black;">
    </canvas>
    

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
主站蜘蛛池模板: 九龙坡区| 屯门区| 徐闻县| 潜江市| 宜章县| 柳江县| 呈贡县| 都江堰市| 阿拉尔市| 额济纳旗| 汉中市| 准格尔旗| 临沂市| 桂阳县| 青川县| 黑龙江省| 扎兰屯市| 桐城市| 永昌县| 广宁县| 大足县| 彩票| 进贤县| 禹州市| 蒲江县| 凌云县| 苍山县| 和林格尔县| 阳泉市| 西城区| 漳州市| 九龙坡区| 根河市| 平利县| 东乌珠穆沁旗| 浦县| 陇川县| 嘉义县| 海原县| 乌兰察布市| 铁岭县|