Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> JavaScript

Ma trận biến đổi (Transformation Matrix) trong HTML5 Canvas

Canvas 2D sử dụng ma trận biến đổi 3x3 (affine transformation matrix) để quản lý hệ tọa độ. Ma trận ban đầu là ma trận đơn vị (identity). Các phương thức biến đổi sửa đổi ma trận này:

  • translate(x, y): Dịch chuyển.
  • rotate(angle): Xoay.
  • scale(x, y): Tỷ lệ.
  • transform(a, b, c, d, e, f): Nhân ma trận hiện tại với ma trận tùy chỉnh.
  • setTransform(a, b, c, d, e, f): Ghi đè ma trận hiện tại bằng ma trận mới.

Cấu trúc ma trận (column-major)

[ a  c  e ]
[ b  d  f ]
[ 0  0  1 ]
  • a, d: scale X, Y.
  • b, c: skew X, Y.
  • e, f: translate X, Y.

Ví dụ: Xoay lặp với transform() và reset với setTransform()

<!DOCTYPE HTML>
<html>
  <head>
    <script>
      function drawShape() {
        var canvas = document.getElementById('mycanvas');
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
          var sin = Math.sin(Math.PI/6); // 30 độ
          var cos = Math.cos(Math.PI/6);
          ctx.translate(200, 200); // dịch gốc ra giữa

          // Vẽ 12 hình vuông xoay dần
          for (var i=0; i<=12; i++) {
            var c = Math.floor(255 / 12 * i);
            ctx.fillStyle = "rgb(" + c + "," + c + "," + c + ")";
            ctx.fillRect(0, 0, 100, 100);
            // Nhân ma trận xoay 30 độ vào ma trận hiện tại
            ctx.transform(cos, sin, -sin, cos, 0, 0);
          }

          // Reset ma trận về trạng thái mới: lật ngang + dịch
          ctx.setTransform(-1, 0, 0, 1, 200, 200);
          ctx.fillStyle = "rgba(100, 100, 255, 0.5)";
          ctx.fillRect(50, 50, 100, 100);
        }
      }
    </script>
  </head>
  <body onload="drawShape();">
    <canvas id="mycanvas" width="400" height="400"></canvas>
  </body>
</html>

Chênh lệch transform() vs setTransform()

Phương thứcHành vi
transform(a,b,c,d,e,f)Nhân ma trận hiện tại × ma trận mới (tích lũy)
setTransform(a,b,c,d,e,f)Ghi đè ma trận hiện tại = ma trận mới (reset)

Dùng setTransform() khi muốn đặt trạng thái biến đổi tuyệt đối (ví dụ reset về identity: setTransform(1,0,0,1,0,0)).