Vẽ Pikachu trên Canvas
Bài đăng này đã không được cập nhật trong 4 năm
1.Giới thiệu
Canvas
là một thẻ trong html5 với mục đích vẽ đồ hoạ trên web thông qua Javascript
. Cho đến hiện tại thì hầu hết trình duyệt đều có support Canvas
. Dưới đây là các phiên bản trình duyệt đầu tiên có support Canvas
(source: https://www.w3schools.com)
Trong bài viết này mình sẽ giới thiệu một số API của Canvas
và ứng dụng của chúng để vẽ một ví dụ nho nhỏ
2.API
Để bắt đầu sử dụng Canvas
thì chúng ta cần chèn thẻ <canvas>
vào html
<canvas id="canvas" width="500" height="500"></canvas>
Lệnh trên sẽ tạo ra một Canvas
có kích cỡ 500px x 500px
.
Tiếp theo chúng ta sẽ bắt đầu vẽ trên Canvas
thông qua Javascript
var c = document.getElementById("canvas"); (Lấy tham chiếu của phần tử canvas và gán nó vào biến c)
var ctx = c.getContext("2d"); (chọn kiểu vẽ là 2d)
Sau đó chúng ta có thể sử dụng các API để bắt đầu vẽ
Vẽ một đường thẳng
ctx.moveTo(0, 0);
ctx.lineTo(100, 100);
ctx.stroke();
Vẽ một hình tròn
ctx.beginPath();
ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.stroke();
Vẽ một đường cong có 1 control point
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.quadraticCurveTo(50, 50, 0, 100);
ctx.stroke();
Vẽ một đường cong có 2 control point
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.bezierCurveTo(50, 50, 0, 100, 50, 150);
ctx.stroke();
3.Pikachu
Giờ chúng ta sẽ bắt đầu sử dụng các API phía trên để vẽ 1 nhân vật rất nổi tiếng
Chúng ta khai báo một Canvas
trong code html
<canvas id="myC" width="500px" height="400px"></canvas>
Và Javascript
var c = document.getElementById("myC");
var ctx=c.getContext("2d");
Chúng ta sẽ bắt đầu vẽ từ phần đuôi đầu tiên
ctx.beginPath();
ctx.moveTo(293,265);
ctx.lineTo(320,255);
ctx.lineTo(305,240);
ctx.lineTo(360,215);
ctx.lineTo(320,170);
ctx.lineTo(390,150);
ctx.lineTo(420,80);
ctx.quadraticCurveTo(380,75,220,160);
ctx.lineTo(300,210);
ctx.lineTo(272,230);
ctx.quadraticCurveTo(270,240,293,265);
ctx.lineWidth = 2;
ctx.stroke();
ctx.fillStyle = '#fcd822';
ctx.fill();
Tiếp theo là phần thân (trick ở đây là vẽ đối xứng qua một điểm)
ctx.beginPath();
ctx.moveTo(130,210);
ctx.quadraticCurveTo(135,230,120,250);
ctx.quadraticCurveTo(90,280,100,310);
ctx.bezierCurveTo(65,280,50,290,60,310);
ctx.bezierCurveTo(90,350,120,380,130,350);
ctx.bezierCurveTo(150,340,250,340,270,350);
ctx.bezierCurveTo(280,380,310,350,340,310);
ctx.bezierCurveTo(350,290,340,280,300,310);
ctx.quadraticCurveTo(310,280,280,250);
ctx.quadraticCurveTo(265,230,270,210);
ctx.lineWidth = 3;
ctx.fillStyle = '#fcd822';
ctx.stroke();
ctx.fill();
Tiếp theo là phần đầu
ctx.beginPath();
ctx.moveTo(240,230);
ctx.quadraticCurveTo(305,200,275,160);
ctx.quadraticCurveTo(280,135,270,120);
ctx.quadraticCurveTo(320,90,325,25);
ctx.quadraticCurveTo(280,40,250,100);
ctx.bezierCurveTo(230,80,170,80,150,100);
ctx.quadraticCurveTo(120,40,75,25);
ctx.quadraticCurveTo(80,90,130,120);
ctx.quadraticCurveTo(120,135,125,160);
ctx.quadraticCurveTo(95,200,160,230);
ctx.stroke();
ctx.fill();
Tiếp theo là 2 tay
ctx.beginPath();
ctx.moveTo(130,280);
ctx.quadraticCurveTo(130,310,160,345);
ctx.lineTo(157,350);
ctx.lineTo(165,347);
ctx.lineTo(163,352);
ctx.lineTo(170,347);
ctx.lineTo(175,355);
ctx.lineTo(180,347);
ctx.lineTo(185,352);
ctx.lineTo(185,343);
ctx.quadraticCurveTo(190,310,180,255);
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.moveTo(270,280);
ctx.quadraticCurveTo(270,310,240,345);
ctx.lineTo(243,350);
ctx.lineTo(235,347);
ctx.lineTo(237,352);
ctx.lineTo(230,347);
ctx.lineTo(225,355);
ctx.lineTo(220,347);
ctx.lineTo(215,352);
ctx.lineTo(215,343);
ctx.quadraticCurveTo(210,310,220,255);
ctx.stroke();
ctx.fill();
Vẽ chi tiết hơn cho 2 chân
ctx.beginPath();
ctx.moveTo(70,290);
ctx.lineTo(90,310);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(58,295);
ctx.lineTo(75,312);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(100,309);
ctx.lineTo(110,317);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(130,350);
ctx.quadraticCurveTo(132,345,130,335);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(340,290);
ctx.lineTo(310,310);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(345,296);
ctx.lineTo(320,320);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(300,309);
ctx.lineTo(290,317);
ctx.lineWidth = 1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(270,350);
ctx.quadraticCurveTo(268,345,270,335);
ctx.lineWidth = 1;
ctx.stroke();
Sau đó là chi tiết cho 2 tai
ctx.beginPath();
ctx.moveTo(102,40);
ctx.lineTo(90,80);
ctx.quadraticCurveTo(73,40,75,25);
ctx.quadraticCurveTo(106,40,102,40);
ctx.fillStyle = '#000';
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.moveTo(298,40);
ctx.lineTo(310,80);
ctx.quadraticCurveTo(327,40,325,25);
ctx.quadraticCurveTo(294,40,298,40);
ctx.fillStyle = '#000';
ctx.stroke();
ctx.fill();
Và cuối cùng là vẽ mặt
/* left eye */
ctx.beginPath();
ctx.arc(160, 140, 14, 0, Math.PI*2);
ctx.fillStyle = '#000';
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.arc(165,133, 6, 0, Math.PI*2);
ctx.fillStyle = '#fff';
ctx.stroke();
ctx.fill();
/* right eye */
ctx.beginPath();
ctx.arc(240, 140, 14, 0, Math.PI*2);
ctx.fillStyle = '#000';
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.arc(235,133, 6, 0, Math.PI*2);
ctx.fillStyle = '#fff';
ctx.stroke();
ctx.fill();
/* nose */
ctx.beginPath();
ctx.moveTo(195,160);
ctx.lineTo(205,160);
ctx.lineTo(200,165);
ctx.lineTo(195,160);
ctx.fillStyle = '#000';
ctx.stroke();
ctx.fill();
/* mouth */
ctx.beginPath();
ctx.moveTo(180,175);
ctx.quadraticCurveTo(190,185,200,175);
ctx.quadraticCurveTo(210,185,220,175);
ctx.lineWidth =1;
ctx.stroke();
ctx.beginPath();
ctx.moveTo(125,160);
ctx.bezierCurveTo(150,160,150,200,120,200);
ctx.quadraticCurveTo(110,180,125,160);
ctx.fillStyle = '#FF0000'
ctx.stroke();
ctx.fill();
ctx.beginPath();
ctx.moveTo(275,160);
ctx.bezierCurveTo(250,160,250,200,280,200);
ctx.quadraticCurveTo(290,180,275,160);
ctx.fillStyle = '#FF0000'
ctx.stroke();
ctx.fill();
Vậy là chúng ta đã hoàn thành bản vẽ Pikachu chỉ với một vài API đơn giản. Hi vọng qua bài viết này các bạn sẽ có cái nhìn sơ lược về canvas
All rights reserved