HTML5 Canvas 教程:十、合成

十、合成 Composites

 

10.1阴影 Shadows

 

要用HTML5画布添加阴影,可以使用画布上下文对象的shadowColor、shadowBlur、shadowOffsetX和shadowOffsetY属性。

 

<!DOCTYPE HTML>

<html>

  <head>

    <style>

      body {

        margin: 0px;

        padding: 0px;

      }

    </style>

  </head>

  <body>

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

    <script>

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

      var context = canvas.getContext('2d');

 

      context.rect(18840200100);

      context.fillStyle = 'red';

      context.shadowColor = '#999';

      context.shadowBlur = 20;

      context.shadowOffsetX = 15;

      context.shadowOffsetY = 15;

      context.fill();

    </script>

  </body>

</html>

 

以上代码演示了在画布上绘制一个矩形,并设置阴影参数。

 

 

10.2透明度 Alpha

 

为了用HTML5画布设置元素的不透明度,我们可以将画布上下文的globalAlpha属性设置为0到1之间的实数,其中0是完全透明的,1是完全不透明的。

 

<!DOCTYPE HTML>

<html>

  <head>

    <style>

      body {

        margin: 0px;

        padding: 0px;

      }

    </style>

  </head>

  <body>

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

    <script>

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

      var context = canvas.getContext('2d');

 

      // draw blue rectangle

      context.beginPath();

      context.rect(20020100100);

      context.fillStyle = 'blue';

      context.fill();

 

      // draw transparent red circle

      context.globalAlpha = 0.5;

      context.beginPath();

      context.arc(3201206002 * Math.PI, false);

      context.fillStyle = 'red';

      context.fill();

    </script>

  </body>

</html>

 

以上代码演示了在画布上重叠两个半透明的图形。

 

 

10.3剪辑区域 Clipping Region

 

若要使用HTML5画布定义剪辑区域,可以绘制路径,然后使用上下文对象的clip()方法。随后绘制的所有图形将被绑定在剪辑区域内。一旦我们在裁剪区域内完成了绘图,可以使用restore()方法将画布上下文返回到其原始状态,以便进一步的绘图不绑定到裁剪区域。

 

在本教程中,我们将通过绘制一个圆,然后使用clip()来定义一个圆形裁剪区域,然后绘制几个在圆形路径内裁剪的圆。接下来,我们将使用restore()方法将画布上下文恢复到其原始状态,然后在原始剪辑区域周围绘制一个环。

 

<!DOCTYPE HTML>

<html>

  <head>

    <style>

      body {

        margin: 0px;

        padding: 0px;

      }

    </style>

  </head>

  <body>

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

    <script>

      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() allows us to save the canvas context before

       * defining the clipping region so that we can return

       * to the default state later on

       */

      context.save();

      context.beginPath();

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

      context.clip();

 

      // draw blue circle inside clipping region

      context.beginPath();

      context.arc(x - offset, y - offset, radius, 02 * Math.PI, false);

      context.fillStyle = 'blue';

      context.fill();

 

      // draw yellow circle inside clipping region

      context.beginPath();

      context.arc(x + offset, y, radius, 02 * Math.PI, false);

      context.fillStyle = 'yellow';

      context.fill();

 

      // draw red circle inside clipping region

      context.beginPath();

      context.arc(x, y + offset, radius, 02 * Math.PI, false);

      context.fillStyle = 'red';

      context.fill();

 

      /*

       * restore() restores the canvas context to its original state

       * before we defined the clipping region

       */

      context.restore();

      context.beginPath();

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

      context.lineWidth = 10;

      context.strokeStyle = 'blue';

      context.stroke();

    </script>

  </body>

</html>

 

以上代码演示了在画布上设置状态保存点,然后设置剪辑区域,然后在剪辑区域内绘图,然后恢复到保存点,并用蓝色为剪辑区域描边。

 

 

10.4全局合成操作 Global Composite Operations

 

要使用HTML5画布执行合成操作,可以使用画布上下文的globalCompositeOperation属性。此属性定义画布的源和目的地状态之间的合成操作。目的地定义为合成操作之前的画布状态,源定义为复合操作后的画布状态。

 

可以执行十二个种合成操作之一,包括:source-atop、source-in、source-out、source-over、destination-atop、destination-in、destination-out、destination-over、lighter、xor和copy。除非另有声明,否则默认的复合操作为source-over。

 

需要注意的是,画布上下文只能在整个生命周期中支持一次合成操作。如果想要使用多次合成操作,要如本教程所示,首先在一个不可见的画布上进行绘图操作,然后将绘制结果复制到可见画布上。

 

<!DOCTYPE HTML>

<html>

  <head>

    <style>

      body {

        margin: 0px;

        padding: 0px;

      } 

    </style>

  </head>

  <body>

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

    <script>

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

      var context = canvas.getContext('2d');

      var tempCanvas = document.createElement('canvas');

      var tempContext = tempCanvas.getContext('2d');

 

      var squareWidth = 55;

      var circleRadius = 35;

      var shapeOffset = 50;

      var operationOffset = 150;

      var arr = [];

 

      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');

 

      // translate context to add 10px padding

      context.translate(1010);

 

      // draw each of the operations

      for(var n = 0; n < arr.length; n++) {

        var thisOperation = arr[n];

 

        tempContext.save();

        

        // clear temp context

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

 

        // draw rectangle (destination)

        tempContext.beginPath();

        tempContext.rect(00, squareWidth, squareWidth);

        tempContext.fillStyle = 'blue';

        tempContext.fill();

 

        // set global composite

        tempContext.globalCompositeOperation = thisOperation;

 

        // draw circle (source)

        tempContext.beginPath();

        tempContext.arc(shapeOffset, shapeOffset, 

                         circleRadius, 02 * Math.PI, false);

        tempContext.fillStyle = 'red';

        tempContext.fill();

        tempContext.restore();

 

        // draw text

        tempContext.font = '10pt Verdana';

        tempContext.fillStyle = 'black';

        tempContext.fillText(thisOperation, 0, squareWidth + 45);

 

        // translate visible context so operation is drawn in the right place

        if(n > 0) {

          if(n % 4 === 0) {

            context.translate(operationOffset * -3, operationOffset);

          }

          else {

            context.translate(operationOffset, 0);

          }

        }

 

        // copy drawing from tempCanvas onto visible canvas

        context.drawImage(tempCanvas, 00);

      }

    </script>

  </body>

</html>

 

以上代码演示了创建不可见的临时画布,并在临时画布上分别执行不同类型的多次合成操作,并将绘制内容复制到可见画布的过程。本例也演示了不同的合成操作之间的差异。

 

对于这种首先在不可见画布绘图然后再复制到可见画布的操作,又称之为双缓冲区机制double buffer,其特点是在绘制过程中不会影响可见画布的显示,在很多其他开发语言入Java中,这种影响主要是指画面闪烁。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章