HTML5 Canvas教程(10)

2.2.1 原点的位移

使用 translate() 方法可以将绘图原点向横向和纵向移动指定的距离(x, y),结果表现为整张图像的移动。如:

<script>

  context.translate(x, y); </script>

效果图,translate方法被注释掉的效果

 

效果图,translate方法没有注释掉的效果

 

代码

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

        // 把坐标原点移动到canvas中心点

        // 如果本行被注释掉,结果就是上面第一张图,否则就是第二张图的效果         context.translate(canvas.width / 2, canvas.height / 2);         context.fillStyle = "blue";

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

    </script>

  </head>

  <body>

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

  </body>

</html>

2.2.2 缩放

缩放操作使用 scale() 方法,参数x、y分别代表横向与纵向的缩放比例,两个参数都是浮点数, 1.0表示不缩放,小于1.0表示缩小,大于1.0表示放大。即,元坐标(x1, y1)上的点经 scale(x,

y) 缩放后的点将被移动到(x1*x, y1*y)。

如:

<script>

  context.scale(x, y); </script>

效果图,scale方法被注释掉的效果

 

效果图,scale方法没有被注释掉的效果

 

代码

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

        // 把坐标原点移动到canvas中心点

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

        // 坐标在横向上缩小一半

        context.scale(1, 0.5);

        context.fillStyle = "blue";

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

    </script>

  </head>

  <body>

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

  </body>

</html>

2.2.3 旋转

旋转canvas用的方法是 rotate() 。此方法接受一个以弧度为单位的旋转参数,整个canvas将以坐标原点,也就是由 translate() 所确定的原点为圆心进行旋转。.在本教程中,我们将原点移动到了canvas的中心点上,这样图中的矩形就可以以其中心点进行旋转了。

如:

<script>   context.rotate(angle);

</script>

效果图,scale被注释掉的效果

 

效果图,scale没有注释掉的效果

 

代码

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

        // 把坐标原点移动到canvas中心点

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

        // 顺时针旋转45度

        context.rotate(Math.PI / 4);

        context.fillStyle = "blue";

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

rectHeight);       };

    </script>

  </head>

  <body>

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

  </body>

</html>

2.2.4 用户自定义坐标变换

HTML5可以使用 transform() 方法以用户自定义的变换矩阵对图像坐标进行变换操作。这个方法需要6个参数组成一个 3 x 3 的转换矩阵,坐标的由 (x, y) 到 (x', y') 的转换公式如下所示:

 

<script>

  context.transform(a, b, c, d, e, f);

</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 rectWidth = 150;         var rectHeight = 75;

        // 转换矩阵

        //  1  0  tx

        //  0  1  ty

        //  0  0  1

        var tx = canvas.width / 2;         var ty = canvas.height / 2;

        // 应用用户自定义转换

        context.transform(1, 0, 0, 1, tx, ty);

        context.fillStyle = "blue";

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

rectHeight);

      };

    </script>

  </head>

  <body>

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

  </body>

</html>

2.2.5 剪切变换

如果我们按照下面公式进行坐标变换的话,就可以对图像进行剪切变换。其中 sx 定义了水平方向

的剪切, sy 则定义了垂直方向上的剪切。

 

如:

<script>

  context.transform(1 ,sy, sx, 1, 0, 0); </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 rectWidth = 150;         var rectHeight = 75;

        // 剪切矩阵

        //  1  sx  0

        //  sy  1  0

        //  0  0  1

        var sx = 0.75;         // .75 水平剪切         var sy = 0;

        // 无垂直剪切

        // 把坐标原点移动到中心点

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

        // 应用用户定义转换

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

        context.fillStyle = "blue";

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

rectHeight);

      };

    </script>

      </head>

      <body>

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

      </body>

    </html>

2.2.6 镜面转换

镜面转换只需要在 scale() 方法的参数中使用负值的参数,比如水平镜像就把x参数赋值一个负数,垂直镜像则是把y参数赋值一个负数。

如:

<script>   // 水平镜像

  context.scale(-1,1);

  // 垂直镜像

  context.scale(1,-1); </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中心点

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

        // 水平翻转图像

        context.scale(-1, 1);

        context.font = "30pt Calibri";         context.textAlign = "center";         context.fillStyle = "blue";         context.fillText("Hello World!", 0, 0);       };

    </script>

  </head>

  <body>

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

  </body>

</html>

2.2.7 重置转换如果要将坐标转换为原始状态,需要使用下面的公式调用 setTransform() 方法。

 

如:

<script>

  context.setTransform(1, 0, 0, 1, 0, 0); </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 rectWidth = 150;         var rectHeight = 75;

        // 把坐标原点移动到canvas中心点

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

        context.fillStyle = "blue";

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

        // 重置转换

        // 1 0 0

        // 0 1 0

        // 0 0 1

        // 应用用户自定义转换

        context.setTransform(1, 0, 0, 1, 0, 0);

        context.fillStyle = "red";

        context.fillRect(0, 0, rectWidth, rectHeight);       };

    </script>

  </head>

  <body>

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

  </body>

</html>

     

2.2.8 变换状态栈

使用 save() 和 restore() 方法可以实现对坐标变换状态的保存与恢复。

在本教程中,我们在每次进行坐标转换前把当前的转换状态推进栈中。首先画一个蓝色的矩形,从状态栈中弹出恢复上一个转换状态,然后再画个红色的矩形,从状态栈中再弹出恢复上一个转换状态,再画个黄色的矩形,最后再从状态栈中再弹出恢复上最后一个转换状态,画一个绿色矩形。

如:

<script>   context.save();   context.restore(); </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 rectWidth = 150;         var rectHeight = 75;

        context.save();         // 保存状态 1

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

        context.save();         // 保存状态 2         context.rotate(Math.PI / 4);

        context.save();         // 保存状态 3         context.scale(2, 2);

        context.fillStyle = "blue";

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

        context.restore();                 // 恢复状态 3         context.fillStyle = "red";

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

        context.restore();         // 恢复状态 2

        context.fillStyle = "yellow";

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

        context.restore();         // 恢复状态 1

        context.fillStyle = "green";

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

rectHeight);       };

    </script>

  </head>

  <body>

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

  </body>

</html>

       

2.2.9 椭圆

要画一个椭圆,我们可以这样做,首先保存转换状态,然后将canvas水平拉伸,画一个圆,恢复转换状态,然后应用样式。

效果图

 

代码

<!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 centerX = 0;         var centerY = 0;         var radius = 50;

        // 保存状态         context.save();

        // 移动原点

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

        // 水平缩放

        //context.scale(2, 1);

        // 这里画的圆会被拉伸成椭圆

        context.beginPath();

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

        // 恢复原始状态

        context.restore();

        // 应用样式

        context.fillStyle = "#8ED6FF";

        context.fill();

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

        context.stroke();       };

    </script>

  </head>

  <body>

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

  </body>

</html>