Canvas cơ bản

Trần Đức Lĩnh

Canvas là một phần tử của HTML5, có thể trích xuất đồ họa của các đối tượng hai chiều trên trang web. Bạn có biết rằng canvas chiếm một khu vực nhất định trong trang web với chiều rộng và chiều cao đã được định trước, chỉ có thể sử dụng JavaScript truy cập vào khu vực này để vẽ thông qua một tập các hàm đồ họa tương tự như API 2D khác.

Muc lục

Bài viết kiên quan: Tìm hiểu đồ hoạ Website, Thao tác DOM.

Bắt đầu nào.

Những kiến thức cơ bản sẽ không được giải thích lại. Tớ chỉ nêu ra những cách thức để dựng một số hình vẽ, vector,... cơ bản nhất. Từ đó có thể áp dụng vào những dự án thực tế.

Trong thẻ <body></body> buộc phải khai báo thẻ <canvas></canvas>.

<body>
    <canvas width = "300" height = "300"></canvas>
</body>

Bạn có biết ?:

  • Trước khi canvas có thể trích xuất đồ họa các đối tượng hai chiều, bạn cần phải xác định chiều rộng X chiều cao cho trước.
  • Nếu không khai báo chiều rộng X chiều dài, mặc định sẽ là 300x150.
  • Thật không may, muốn xác định được khu vực của canvas, không nên khai báo giá trị px sau mỗi tham số được định trước, mỗi tham số nên khuyến khích là số chẵn. Trên màng hình chỉ hiển thị 1 điểm ảnh, không hiển thị 0.5 điểm ảnh, khi đó mọi thứ đều mờ nhạt và không rõ nét.

Quan trọng.

Từ mục này trở đi, mọi thứ đều liên quan đến JavaScript.

Việc đầu tiên là tạo riêng một tệp tin main.js...src="main.js"... vào bên trong thẻ <body></body>.

var canvas = document.querySelector('canvas');
// Sử dụng DOM để lấy thẻ <canvas> đầu tiên mà nó tìm thấy.

var c = canvas.getContext('2d');
// Sử dụng đồ họa 2D.

Xác định tọa độ X-Y.

Tọa độ X-Y được xác định với điểm xuất phát từ gốc trên cùng bên trái với tọa độ là (0, 0). Từ điểm đã được xác định, bạn có thể sử

image-title-here

  • X có màu đỏ.
  • Y có màu xanh.

1) Vẽ đường thẳng (Line Canvas).

image-title-here

c.beginPath();
c.moveTo(50, 50);
c.lineTo(250, 250);
c.stroke();
  • beginPath() : Mở đầu cho mỗi nét vẽ.
  • moveTo(x,y) : Điểm bắt đầu vẽ.
  • lineTo(x,y) : Tạo đường vẽ từ điểm bắt đầu đến điểm cuối.
  • stroke() : Tạo nét.

2) Vẽ đường dẫn (Subpath Canvas).

image-title-here

c.beginPath();
c.moveTo(0, 0);
c.lineTo(160, 20);
c.lineTo(210, 150);
c.closePath();
c.lineTo(50, 250);
c.stroke();
  • Tất nhiên bạn có thể tái sử dụng .lineTo(x, y) nhiều lần cho các nét vẽ tiếp theo.
  • closePath() : Nối điểm cuối cùng của nét vẽ cuối* đến điểm bắt đầu nét vẽ.

Lưu ý !:

  • Nếu bạn có ý định tạo một nét vẽ mới, nên sử dụng beginPath() mới và kết thúc chúng ngay khi dùng stroke(), thay vì viết đè như ví dụ trên.

3) Độ rộng nét vẽ (lineWidth).

image-title-here

c.beginPath();
c.moveTo(40, 20);
c.lineTo(40, 220);
c.lineWidth = 40;
c.strokeStyle = '#273c75';
c.stroke();

c.beginPath();
c.moveTo(120, 20);
c.lineTo(120, 220);
c.lineWidth = 45;
c.strokeStyle = '#ED4C67';
c.stroke();
  • lineWidth = number : Tăng độ rộng cho nét vẽ.
  • strokeStyle = '?' : Màu nét vẽ, có thể là màu hsl(), rgb(), rgba(), hex()....

Lưu ý !:

  • Cột màu xanh lơ và cột màu hồng có sự khác nhau về đường nét. Canvas không thể chọn 0.5 điểm ảnh cho mỗi bên, vì thế trong canvas đừng nên dùng số lẻ.

4) Hình dạng hai điểm nút (lineCap).

Bạn có thể tùy chỉnh 2 điểm nút bằng hình dạng bo tròn hoặc vuông.

image-title-here

c.lineWidth = 25;

c.beginPath();
c.moveTo(40, 20);
c.lineTo(40, 220);
c.strokeStyle = 'red';
c.lineCap = 'butt';
c.stroke();

c.beginPath();
c.moveTo(120, 20);
c.lineTo(120, 220);
c.strokeStyle = 'green';
c.lineCap = 'round';
c.stroke();

c.beginPath();
c.moveTo(200, 20);
c.lineTo(200, 220);
c.strokeStyle = 'blue';
c.lineCap = 'square';
c.stroke();
  • lineCap = '?' : Điểm nút giữa 2 đầu.

    • butt : Dạng mặt định.
    • round : Bo tròn.
    • square : Vuông.

5) Tùy chọn sau mỗi nét gãy (lineJoin).

image-title-here

c.lineWidth = 30;

c.beginPath();
c.moveTo(80, 20);
c.lineTo(20, 100)
c.lineTo(80, 220);
c.strokeStyle = 'red';
c.lineJoin = 'miter';
c.stroke();

c.beginPath();
c.moveTo(130, 20);
c.lineTo(70, 100);
c.lineTo(130, 220);
c.strokeStyle = 'green';
c.lineJoin = 'round';
c.stroke();

c.beginPath();
c.moveTo(180, 20);
c.lineTo(120, 100);
c.lineTo(180, 220);
c.strokeStyle = 'blue';
c.lineJoin = 'bevel';
c.stroke();
  • lineJoin = '?' : Giữa nét gãy.

    • miter : Dạng mặt định.
    • round : Bo tròn.
    • bevel : Xén.

6) Sự khác nhau giữa lấp đầy và tạo nét (stroke & fill).

image-title-here

c.beginPath();
c.moveTo(60, 40);
c.lineTo(60, 220);
c.lineTo(90, 250);
c.lineTo(90, 80)
c.closePath();
c.stroke();

c.beginPath();
c.moveTo(180, 40);
c.lineTo(180, 250);
c.lineTo(210, 220);
c.lineTo(210, 80)
c.closePath();
c.fill();
  • Cần xác định tọa độ trước khi vẽ.

    • moveTo()

img

Stroke bao gồm:

  • stroke() : Tạo nét.
  • strokeRect(x, y, w, h) : Tạo nét hình 4 cạnh.
  • strokeStyle = '?' : Màu nét vẽ.
  • strokeText('text', x, y, maxWidth) : Tạo nét chữ.

Fill bao gồm:

  • fill() : Lấp đầy.
  • filltrokeRect(x, y, w, h) : Lấy đầy hình 4 cạnh.
  • fillStyle = '?' : Màu lấp đầy.
  • fillText('text', x, y, maxWidth) : Lấp đầy nét chữ.

7) Loại bỏ một vùng chứa (clearRect).

image-title-here

c.fillStyle = 'red';
c.fillRect(20, 20, 280, 280);
c.clearRect(40, 40, 110, 110);
  • clearReact(x, y, w, h) : Loại bỏ 1 vùng chứa có dạng hình 4 cạnh.

8) Vẽ đường tròn (arc).

img

c.beginPath();
c.moveTo(10, 100);
c.lineWidth = 5;
c.arc(140, 150, 60, 0, Math.PI * 1.8 , false);
c.stroke();
  • arc(x, y, radius, start, end, anticlockwise) : Tạo đường tròn.

9) Bo cong đường tròn (arcTo).

img

c.beginPath();
c.moveTo(10, 200);
c.lineTo(140, 20)
c.lineTo(220, 200)
c.stroke();

c.beginPath();
c.moveTo(10, 200);
c.arcTo(140, 20, 220, 200, 80)
c.lineWidth = 10;
c.strokeStyle = '#ff0000';
c.stroke();
  • arcTo(x1, y1, x2, y2, radius) : Bo cong đường tròn nội tiếp.

img

10) Tạo đường cong với 2 điểm 1 kiểm soát (quadraticCurveTo).

img

c.beginPath();
c.moveTo(200, 250);
c.quadraticCurveTo(20, 3, 50, 250);
c.stroke();
  • quadraticCuveTo(cx, cy, x, y) : Tạo đường cong với 2 điểm 1 kiểm soát bất kỳ.
11) Tạo đường cong với 2 điểm 2 kiểm soát (bezierCurveTo).

img

c.beginPath();
c.moveTo(20, 50);
c.bezierCurveTo(80, 150, 250, 250, 250, 40);
c.stroke();
  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) : Tạo đường cong với 2 điểm 2 kiểm soát bất kỳ.

(Còn nữa...)