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中,這種影響主要是指畫面閃爍。

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