SVG
là một đặc tả của một bản vẽ giống như một định dạng tệp. SVG là một tài liệu. Bạn có thể trao đổi tệp SVG giống như tệp HTML. Ngoài ra, vì các phần tử SVG và các phần tử HTML chia sẻ cùng một API DOM, nên có thể sử dụng JavaScript để tạo SVG DOM theo cách giống như cách có thể tạo HTML DOM. Nhưng bạn không cần JavaScript để tạo tệp SVG. Một trình soạn thảo văn bản đơn giản là đủ để viết một SVG. Nhưng bạn cần ít nhất một máy tính để tính tọa độ của các hình trong bản vẽ.
CANVAS
chỉ là một khu vực vẽ. Cần phải sử dụng JavaScript để tạo nội dung của canvas. Bạn không thể trao đổi một canvas. Nó không phải là tài liệu. Và các phần tử của canvas không phải là một phần của cây DOM. Bạn không thể sử dụng API DOM để thao tác nội dung của canvas. Thay vào đó, bạn phải sử dụng một API canvas chuyên dụng để vẽ các hình dạng vào canvas.
Ưu điểm của a SVG
là bạn có thể trao đổi bản vẽ như một tài liệu. Ưu điểm của CANVAS
nó là có một API JavaScript ít dài dòng hơn để tạo nội dung.
Đây là một ví dụ cho thấy rằng bạn có thể đạt được kết quả tương tự, nhưng cách thực hiện điều đó trong JavaScript rất khác.
// Italic S in SVG
(function () {
const ns='http://www.w3.org/2000/svg';
let s = document.querySelector('svg');
let p = document.createElementNS (ns, 'path');
p.setAttribute ('id', 'arc');
p.setAttribute ('d', 'M 0.9 -0.9 a 0.8,0.4 -10 0,0 -0.9,0.9');
s.appendChild (p);
let u = document.createElementNS (ns, 'use');
u.setAttribute ('href', '#arc');
u.setAttribute ('transform', 'rotate(180)');
s.appendChild (u);
})();
// Italic S in CANVAS
(function () {
let c = document.querySelector('canvas');
let w = c.width = c.clientWidth;
let h = c.height = c.clientHeight;
let x = c.getContext('2d');
x.lineWidth = 0.05 * w;
x.moveTo (w/2, h/2);
x.bezierCurveTo (w*0.02, h*0.4,
w*0.4, -h*0.02,
w*0.95, h*0.05);
x.moveTo (w/2, h/2);
x.bezierCurveTo (w*(1-0.02), h*(1-0.4),
w*(1-0.4), h*(1+0.02),
w*(1-0.95), h*(1-0.05));
x.stroke();
})();
svg, canvas {
width: 3em;
height: 3em;
}
svg {
vertical-align: text-top;
stroke: black;
stroke-width: 0.1;
fill: none;
}
canvas {
vertical-align: text-bottom;
}
div {
float: left;
}
<div><svg viewBox="-1 -1 2 2"></svg>VG</div>
<div>CANVA<canvas></canvas></div>
Như bạn có thể thấy kết quả gần như giống nhau, nhưng mã JavaScript hoàn toàn khác.
SVG được tạo ra với các API DOM sử dụng createElement
, setAttribute
và appendChild
. Tất cả đồ họa nằm trong chuỗi thuộc tính. SVG có nhiều nguyên thủy mạnh mẽ hơn. Ví dụ, CANVAS không có gì tương đương với đường dẫn vòng cung SVG. Ví dụ CANVAS cố gắng mô phỏng cung SVG với đường cong Bezier. Trong SVG, bạn có thể sử dụng lại các phần tử để biến đổi chúng. Trong CANVAS, bạn không thể sử dụng lại các phần tử. Thay vào đó, bạn phải viết một hàm JavaScript để gọi nó hai lần. SVG có một viewBox
cho phép sử dụng các tọa độ chuẩn hóa, giúp đơn giản hóa các phép quay. Trong CANVAS, bạn phải tự tính toán các tọa độ dựa trên clientWidth
vàclientHeight
. Và bạn có thể tạo kiểu cho tất cả các phần tử SVG bằng CSS. Trong CANVAS, bạn không thể tạo kiểu bất kỳ thứ gì bằng CSS. Vì SVG là một DOM, bạn có thể chỉ định trình xử lý sự kiện cho tất cả các phần tử SVG. Các phần tử trong CANVAS không có DOM và không có trình xử lý sự kiện DOM.
Nhưng mặt khác, mã CANVAS dễ đọc hơn nhiều. Bạn không cần quan tâm đến không gian tên XML. Và bạn có thể gọi trực tiếp các hàm đồ họa, vì bạn không cần phải xây dựng DOM.
Bài học rất rõ ràng: nếu bạn muốn nhanh chóng vẽ một số đồ họa, hãy sử dụng CANVAS. Nếu bạn cần chia sẻ đồ họa, muốn tạo kiểu bằng CSS hoặc muốn sử dụng trình xử lý sự kiện DOM trong đồ họa của mình, hãy xây dựng một SVG.