Cách vẽ một hình đơn giản trong Canvas
Bài đăng này đã không được cập nhật trong 3 năm
Canvas hiểu đơn giản là một thẻ tag mới của HTML5, được xây dựng từ Javascript, dùng để vẽ hình, tạo hiệu ứng, thậm chí có thể làm game đơn giản ngay trên trang web của bạn. Trong bài viết này mình sẽ không nói nhiều về định nghĩa, hay các hàm trong Canvas, những cái đấy đã có rất nhiều trang web giải thích rồi. Tuy nhiên đọc chay như vậy khá là nhàm chán và khó nhớ, vì vậy bài viết này mình sẽ hướng dẫn bạn tạo một hình vẽ đơn giản bằng Canvas.
Bạn có thể thực hành ngay lập tức trên trang https://fiddle.jshell.net
Một lưu ý nhỏ là có một số trình duyệt chưa hỗ trợ hoặc hỗ trợ một cách đầy đủ Canvas, bạn có thể thấy kết quả hơi khác một chút, như thế này:
Đầu tiên hãy bắt đầu với file HTML, chúng ta chỉ cần khai báo thẻ tag <canvas>
cùng với độ dài rộng của hình ảnh.
<canvas id="canvasId" width="165" height="145"></canvas>
Giờ chúng ta có một ảnh canvas trống, tất nhiên là chưa nhìn thấy gì ) Thẻ <canvas>
chỉ tạo ra một khu vực để chúng ta dùng javascript để vẽ. Chúng ta không vẽ trên canvas, giống như chúng ta không vẽ lên bàn. Chúng ta vẽ lên một cái gì đó trên bàn, trong trường hợp này là context
var context = document.getElementById("canvasId").getContext("2d");
Chúng ta sử dụng phương thức getContext
với tham số "2d" để vẽ hình 2d, trên hệ trục tọa độ (x, y). Giờ chúng ta bắt đầu vẽ. Đầu tiên vẽ hình tam giác:
var width = 125; // Triangle Width
var height = 105; // Triangle Height
var padding = 20;
// Draw a path
context.beginPath();
context.moveTo(padding + width/2, padding); // Top Corner
context.lineTo(padding + width, height + padding); // Bottom Right
context.lineTo(padding, height + padding); // Bottom Left
context.closePath();
// Fill the path
context.fillStyle = "#ffc821";
context.fill();
Phương thức beginPath()
dùng để bắt đầu một hình vẽ, kết thúc với closePath()
. Tuy nhiên để có thể nhìn thấy, ta cần thêm màu cho nó, có 2 cách, một là dùng stroke()
, ta sẽ có một hình tam giác rỗng, còn trong trường hợp này mình dùng fill()
, ta sẽ có một hình tam giác đặc, mặc định sẽ có màu đen, mình muốn tô màu vàng nên thêm fillStyle
để truyền vào mã màu mà mình muốn.
Hình tam giác của chúng ta nhìn có vẻ hơi nhàm chán. Ta sẽ thay một màu bằng một dải màu. Đầu tiên ta tạo ra dải màu với phương phức createLinearGradient
, và phương thức addColorStop
để quy ước màu cho dải màu.
// Create fill gradient
var gradient = context.createLinearGradient(0, 0, 0, height);
gradient.addColorStop(0, "#ffc821");
gradient.addColorStop(1, "#faf100");
// Fill the path
context.fillStyle = gradient;
context.fill();
Giờ thêm một chút đổ bóng tạo chiều sâu bằng shadowBlur
và shadowColor
, nhưng nhớ phải thêm vào trước khi fill()
// Create fill gradient
//...
// Add a shadow around the object
context.shadowBlur = 10;
context.shadowColor = "black";
// Fill the path
// ...
10 là độ rộng của bóng, số này càng to thì bóng càng mờ. Giờ ta sẽ thêm một dải màu nữa
// Add a horizon reflection with a gradient to transparent
gradient = context.createLinearGradient(0,padding,0,padding+height);
gradient.addColorStop(0.5, "transparent");
gradient.addColorStop(0.5, "#dcaa09");
gradient.addColorStop(1, "#faf100");
// Fill the path
context.fillStyle = gradient;
context.fill();
Lần này ta có dùng thêm màu transparent (màu trong suốt), để dài màu này sẽ có màu bắt đầu từ giữa hình tam giác, sau đó chuyển dần sang màu nền. Giờ thêm đường viền màu đen
// Stroke the inner outline
context.lineWidth = 5;
context.lineJoin = "round";
context.strokeStyle = "#333";
context.stroke();
lineWidth
là độ rộng của đường đường thẳng, lineJoin
là hình dáng góc khi 2 đường thẳng gặp nhau, trong trường hợp này là bo tròn. Ở đây ta chỉ muốn kẻ viền nên dùng stroke()
thay vì fill()
.
Giờ thêm 1 đường viền khác có màu trùng với màu nền
context.lineWidth = 20;
context.lineJoin = "round";
context.strokeStyle = gradient;
context.stroke();
Giờ chỉ thiếu một dấu chấm than để hoàn thiện. Ta dùng phương thức fillText
. Đừng quên thêm try/catch
để tránh trường hợp bị lỗi trên Internet Explorer 8.0.
context.textAlign = "center";
context.textBaseline = "middle";
context.font = "bold 60px 'Times New Roman', Times, serif";
context.fillStyle = gradient;
try{
context.fillText("!", canvasWidth/2, padding + height/1.5);
}catch(ex){}
Vậy là hoàn thành, không khó đúng ko? Trong này mình dùng khá nhiều phương thức nên mình không thể giải thích cụ thể từng phương thức được, nếu bạn muốn tìm hiểu thêm có thể tham khảo ở đây Để nâng cao hơn, bạn có thể tạo thêm 1 cái bóng ở phía dưới cho nó, như thế này:
Nguồn: http://www.williammalone.com/articles/html5-canvas-example (Trong này có source code, bạn có thể down về để tham khảo)
All rights reserved