HTML5 Canvas教程(9)

2.1.1 阴影

要为图形添加阴影需要用到 shadowColor, shadowBlur, shadowOffsetX 和

shadowOffsetY 属性。

如:

<script>

  context.shadowColor = "black";   context.shadowBlur = 20;   context.shadowOffsetX = 10;   context.shadowOffsetY = 10; </script>

效果图

 

代码

<!DOCTYPE HTML>

<html>

  <head>

    <style>       body {         margin: 0px;         padding: 0px;

      }

      #myCanvas {

        border: 1px solid #9C9898;

      }

    </style>     <script>

      window.onload = function() {

        var canvas = document.getElementById("myCanvas");         var context = canvas.getContext("2d");         context.rect(188, 40, 200, 100);         context.fillStyle = "red";         context.shadowColor = "#999";         context.shadowBlur = 20;         context.shadowOffsetX = 15;         context.shadowOffsetY = 15;         context.fill();       };

    </script>

  </head>

  <body>

    <canvas id="myCanvas" width="578" height="200"></canvas>

  </body>

</html>

2.1.2 透明

设置图形的透明度要用到 globalAlpha 属性。 globalAlpha 属性的值是一个介于 0 到 1 之间的浮点数。 0表示完全透明,而1表示完全不透明。如:

<script>

  context.globalAlpha = 0.5; </script>

效果图

 

代码

<!DOCTYPE HTML>

<html>

  <head>

    <style>       body {         margin: 0px;         padding: 0px;

      }

      #myCanvas {

        border: 1px solid #9C9898;

      }

    </style>     <script>

      window.onload = function() {

        var canvas = document.getElementById("myCanvas");         var context = canvas.getContext("2d");

        // draw blue rectangle         context.beginPath();         context.rect(200, 20, 100, 100);         context.fillStyle = "blue";         context.fill();

        // draw transparent red circle         context.globalAlpha = 0.5;         context.beginPath();

        context.arc(320, 120, 60, 0, 2 * Math.PI, false);         context.fillStyle = "red";         context.fill();       };

    </script>

  </head>

  <body>

    <canvas id="myCanvas" width="578" height="200"></canvas>

  </body>

</html>

2.1.3 裁剪区创建裁剪区的方法是先画一个路径,然后用 clip() 方法。如:

<script>   context.clip(); </script>

效果图

 

代码

<!DOCTYPE HTML>

<html>

  <head>

    <style>       body {         margin: 0px;         padding: 0px;

      }

      #myCanvas {

        border: 1px solid #9C9898;

      }

    </style>     <script>

      window.onload = function() {

        var canvas = document.getElementById("myCanvas");

        var context = canvas.getContext("2d");         var x = canvas.width / 2;         var y = canvas.height / 2;         var radius = 75;         var offset = 50;

        /*

*  save() 的作用是在创建剪裁区之前将 canvas 的当前状态保存起来,

*  这样在后面就可以恢复上下文对象的原始状态了

         */         context.save();         context.beginPath();

        context.arc(x, y, radius, 0, 2 * Math.PI, false);         context.clip();

        // 在剪裁区内部画一个蓝色的源圆圈

        context.beginPath();

        context.arc(x - offset, y - offset, radius, 0, 2 * Math.PI,

false);

        context.fillStyle = "blue";         context.fill();

        // 在剪裁区内部画一个黄色的源圆圈

        context.beginPath();

        context.arc(x + offset, y, radius, 0, 2 * Math.PI, false);         context.fillStyle = "yellow";         context.fill();

        // 在剪裁区内部画一个红色的源圆圈

        context.beginPath();

        context.arc(x, y + offset, radius, 0, 2 * Math.PI, false);         context.fillStyle = "red";         context.fill();

        /*

         * restore() 方法使 canvas 上下文对象恢复到创建剪裁区之前的状态

         */

        context.restore();         context.beginPath();

        context.arc(x, y, radius, 0, 2 * Math.PI, false);

        context.lineWidth = 3;         context.strokeStyle= "black";

        context.stroke();       };

    </script>

  </head>

  <body>

    <canvas id="myCanvas" width="578" height="200"></canvas>

  </body>

</html>

2.1.4 全局组合操作

上下文对象的 globalCompositeOperation 属性定义了组合操作的方式,也就是 canvas 的源与目的的状态。目的是组合操作之前的状态,而源指的是组合操作后面的状态。(译者注:理解起来比

较别扭是吧,看后面的效果示意图就比较好懂了)

共有12种组合操作可供我们选择使用,其中包括: source-atop, source-in, sourceout, source-over, destination-atop, destination-in, destination-out, destination-over, lighter, xor, 和 copy 。默认状态下是 source-over 。

如:

<script>

  context.globalCompositeOperation = 'destination-over'; </script>

各种组合操作的效果图

 

代码

<!DOCTYPE HTML>

<html>

  <head>

    <style>       body {         margin: 0px;         padding: 0px;

      }

      #myCanvas {

        border: 1px solid #9C9898;

      }

    </style>     <script>

      window.onload = function() {

        var canvas = document.getElementById("myCanvas");         var context = canvas.getContext("2d");

        // 注意这里创建了一个临时canvas,可以理解为内存中绘图所用,用于在正式将图形画到页面之前先把完整的图形在这个临时canvas中画完,然后再一下子拷贝到真正用于显示的 myCanvas上,而在页面中的这个临时canvas是不可见的

        var tempCanvas = document.getElementById("tempCanvas");         var tempContext = tempCanvas.getContext("2d");        var squareWidth = 55;         var circleRadius = 35;         var startX = 10;         var startY = 30;

        var rectCircleDistX = 50;         var rectCircleDistY = 50;         var exampleDistX = 150;         var exampleDistY = 140;

        var arr = new Array();         arr.push("source-atop");         arr.push("source-in");         arr.push("source-out");         arr.push("source-over");         arr.push("destination-atop");         arr.push("destination-in");         arr.push("destination-out");         arr.push("destination-over");         arr.push("lighter");         arr.push("darker");         arr.push("xor");         arr.push("copy");

        // 画出十种操作模式

        for(var n = 0; n < arr.length; n++) {           var thisX;           var thisY;           var thisOperation = arr[n];

          // 第一行           if(n < 4) {

            thisX = startX + (n * exampleDistX);             thisY = startY;           }

          // 第二行           else if(n < 8) {

            thisX = startX + ((n - 4) * exampleDistX);             thisY = startY + exampleDistY;           }

          // 第三行           else {

            thisX = startX + ((n - 8) * exampleDistX);             thisY = startY + (exampleDistY * 2);

          }

       

          tempContext.clearRect(0, 0, canvas.width, canvas.height);

          // 画矩形

          tempContext.beginPath();

          tempContext.rect(thisX, thisY, squareWidth, squareWidth);           tempContext.fillStyle = "blue";           tempContext.fill();

          // 设置全局组合模式

          tempContext.globalCompositeOperation = thisOperation;

          // 画圆

          tempContext.beginPath();

          tempContext.arc(thisX + rectCircleDistX, thisY + rectCircleDistY, circleRadius, 0, 2 * Math.PI, false);           tempContext.fillStyle = "red";           tempContext.fill();

          // 恢复成默认状态

          tempContext.globalCompositeOperation = "source-over";

          tempContext.font = "10pt Verdana";           tempContext.fillStyle = "black";

          tempContext.fillText(thisOperation, thisX, thisY + squareWidth + 45);

          // 将图像从 tempCanvas 拷贝到 myCanvas           context.drawImage(tempCanvas, 0, 0);

        }

      }

    </script>

  </head>

  <body>

    <canvas id="myCanvas" width="578" height="430"></canvas>

    <!-- 下面这个canvas就是用作内存中绘图的,样式被设为不可见 -->

    <canvas id="tempCanvas" width="578" height="430" style="display:none;"></canvas>

  </body>

</html>