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ức | Hà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)).