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

Dịch chuyển (translate) Canvas HTML5

Phương thức context.translate(x, y) dịch chuyển gốc tọa độ (0,0) của canvas đến vị trí mới. Tất cả các lệnh vẽ sau đó sẽ được tính toán từ gốc mới này.

Tham số

  • x: Khoảng dịch chuyển theo chiều ngang (dương = phải, âm = trái).
  • y: Khoảng dịch chuyển theo chiều dọc (dương = xuống, âm = lên).

Ví dụ hoàn chỉnh: Vẽ nhiều spirograph lặp lại

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      #test { width: 100px; height: 100px; margin: 0 auto; }
    </style>
    <script>
      function drawShape() {
        var canvas = document.getElementById('mycanvas');
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
          ctx.fillRect(0, 0, 300, 300); // nền

          for (var i = 0; i < 3; i++) {
            for (var j = 0; j < 3; j++) {
              ctx.save(); // lưu trạng thái
              ctx.strokeStyle = "#FF0066";
              // Dịch chuyển đến vị trí ô (i,j)
              ctx.translate(50 + j * 100, 50 + i * 100);
              drawSpirograph(ctx, 10 * (j + 3) / (j + 2), -2 * (i + 3) / (i + 1), 10);
              ctx.restore(); // khôi phục trạng thái
            }
          }
        } else {
          alert('Trình duyệt không hỗ trợ Canvas');
        }
      }

      function drawSpirograph(ctx, R, r, O) {
        var x1 = R - O, y1 = 0, i = 1;
        ctx.beginPath();
        ctx.moveTo(x1, y1);
        do {
          if (i > 20000) break;
          var x2 = (R + r) * Math.cos(i * Math.PI / 72) - (r + O) * Math.cos(((R + r) / r) * (i * Math.PI / 72));
          var y2 = (R + r) * Math.sin(i * Math.PI / 72) - (r + O) * Math.sin(((R + r) / r) * (i * Math.PI / 72));
          ctx.lineTo(x2, y2);
          x1 = x2; y1 = y2; i++;
        } while (x2 != R - O && y2 != 0);
        ctx.stroke();
      }
    </script>
  </head>
  <body id="test" onload="drawShape();">
    <canvas id="mycanvas" width="400" height="400"></canvas>
  </body>
</html>

Kỹ thuật quan trọng: save() / restore()

Trong vòng lặp, dùng ctx.save() trước khi translate và ctx.restore() sau khi vẽ xong. Điều này đảm bảo:

  • Gốc tọa độ quay về (0,0) gốc cho lần lặp tiếp theo.
  • Style (strokeColor, lineWidth...) không bị ảnh hưởng lẫn nhau.

Đây là pattern chuẩn khi làm việc với transform (translate, rotate, scale) trên Canvas.