HTML5 Canvas 教程:九、變換

九、變換 Transformations

 

譯者注:變換計算中需要用到很多矩陣變換運算,如果不熟悉矩陣變換運算,那麼理解以下代碼會有一定困難,建議先熟悉矩陣變換運算再閱讀以下內容。這裏有一篇很好的文章詳細解釋了矩陣運算:淺談矩陣變換——Matrix

 

9.1平移 Translate

 

爲了在HTML5畫布上實現平移,可以使用上下文對象的translate()方法。平移是一種移動整個畫布的方法。例如,有一個在畫布上繪製複雜圖形的函數,並且需要平移圖形,那麼平移上下文要比調整組成圖形的所有點的x和y位置容易得多。

 

平移首先通過變換畫布上下文,然後再繪製圖形。在本教程中,將平移畫布上下文,然後在位置(0, 0)繪製矩形。由於畫布上下文被平移,矩形也將被平移。

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

      context.fillStyle = 'blue';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上平移一個矩形到居中位置。

 

9.2縮放變換 Scale Transform

 

要縮放HTML5畫布,可以使用scale()方法,此方法可縮放畫布的X和Y兩個方向。

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

 

      // scale y component

      context.scale(10.5);

 

      context.fillStyle = 'blue';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上繪製一個矩形,並在Y方向縮放0.5倍。

 

 

9.3旋轉變換 Rotate Transform

 

要旋轉HTML5畫布,可以使用rotate()轉換方法。旋轉變換需要提供轉過的弧度(注意不是角度)。爲了定義旋轉點,需要首先平移畫布上下文對象,以便上下文的左上角位於所需的旋轉點上。在本教程中,平移了畫布上下文,使得上下文的左上角直接位於矩形的中心,從而產生圍繞矩形中心的旋轉。

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

 

      // rotate 45 degrees clockwise

      context.rotate(Math.PI / 4);

 

      context.fillStyle = 'blue';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了平移畫布,繪製矩形,並將其旋轉一定角度。

 

 

9.4自定義變換 Custom Transform

 

爲了將自定義轉換矩陣應用到HTML5畫布,可以使用transform()方法。根據以下約定,該方法需要3×3矩陣的六個分量:

 

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // translation matrix:

      //  1  0  tx

      //  0  1  ty

      //  0  0  1

      var tx = canvas.width / 2;

      var ty = canvas.height / 2;

      // apply custom transform

      context.transform(1001, tx, ty);

      context.fillStyle = 'blue';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了自定義變換。

 

9.5斜切變換 Shear Transform

 

爲了在HTML5畫布上實現斜切變換,可以使用transform()方法進行矩陣轉換。SX定義水平方向切變,SY定義垂直方向的切變。

 

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // shear matrix:

      //  1  sx  0

      //  sy  1  0

      //  0  0  1

 

      var sx = 0.75;

      // .75 horizontal shear

      var sy = 0;

      // no vertical shear

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

 

      // apply custom transform

      context.transform(1, sy, sx, 100);

 

      context.fillStyle = 'blue';

      context.fillRect(-rectWidth / 2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上繪製一個藍色矩形,並進行X方向的斜切變換。

 

 

9.6鏡像變換 Mirror Transform

 

要使用HTML5 Canvas創建鏡像變換,我們可以在上下文對象的x方向上應用負比例來水平翻轉,或者可以在上下文對象的y方向上應用負比例來垂直翻轉。

 

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

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

 

      // flip context horizontally

      context.scale(-11);

 

      context.font = '30pt Calibri';

      context.textAlign = 'center';

      context.fillStyle = 'blue';

      context.fillText('Hello World!'00);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布的X方向反轉一段文字。

 

 

9.7重置變換 Reset Transform

 

爲了重置HTML5 Canvas矩陣變換,可以使用setTransform()方法執行以下矩陣變換,將轉換矩陣設置爲其默認狀態:

 

<!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 rectWidth = 150;

      var rectHeight = 75;

 

      // translate context to center of canvas

      context.translate(canvas.width / 2, canvas.height / 2);

 

      context.fillStyle = 'blue';

      context.fillRect(-rectWidth / 2, rectHeight / -2, rectWidth, rectHeight);

 

      // Reset Transform

      // 1 0 0

      // 0 1 0

      // 0 0 1

 

      // apply custom transform

      context.setTransform(100100);

 

      context.fillStyle = 'red';

      context.fillRect(00, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上重置變換,並用紅色繪製默認狀態的圖形。

 

 

9.8狀態棧變換 Transformation State Stack

 

爲了用HTML5 Canvas保存和恢復不同的變換狀態,可以使用canvas上下文對象的save()和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 rectWidth = 150;

      var rectHeight = 75;

 

      context.save();

      // save state 1

      context.translate(canvas.width / 2, canvas.height / 2);

 

      context.save();

      // save state 2

      context.rotate(Math.PI / 4);

 

      context.save();

      // save state 3

      context.scale(22);

 

      context.fillStyle = 'blue';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

 

      context.restore();

      // restore state 3

      context.fillStyle = 'red';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

 

      context.restore();

      // restore state 2

      context.fillStyle = 'yellow';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

 

      context.restore();

      // restore state 1

      context.fillStyle = 'green';

      context.fillRect(rectWidth / -2, rectHeight / -2, rectWidth, rectHeight);

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上保存和彈出狀態變換。

 

 

9.9橢圓 Oval

 

要使用HTML5 Canvas創建一個橢圓形,可以爲上下文狀態設置一個保存點,然後水平拉伸畫布上下文,畫一個圓圈,然後再恢復畫布到保存點的狀態,最後應用樣式。

 

<!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 centerX = 0;

      var centerY = 0;

      var radius = 50;

 

      // save state

      context.save();

 

      // translate context

      context.translate(canvas.width / 2, canvas.height / 2);

 

      // scale context horizontally

      context.scale(21);

 

      // draw circle which will be stretched into an oval

      context.beginPath();

      context.arc(centerX, centerY, radius, 02 * Math.PI, false);

 

      // restore to original state

      context.restore();

 

      // apply styling

      context.fillStyle = '#8ED6FF';

      context.fill();

      context.lineWidth = 5;

      context.strokeStyle = 'black';

      context.stroke();

    </script>

  </body>

</html>

 

以上代碼演示了在畫布上設置保存點,然後使畫布在X方向放大2倍,再繪製一個圓(由於受到X方向放大兩倍的影響,這個圓變成了橢圓),然後恢復到保存點並應用樣式,最後爲橢圓描邊的過程。

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