CANVAS
– Canvas là gì
Canvas HTML5 là một phần tử vẽ và tạo hình ảnh động vô cùng có ích. Canvas sử dụng JavaScript để vẽ đồ họa trực tiếp trên trang web. Đây là vùng chữ nhật mà bạn định nghĩa và điều khiển và nó cho phép dựng hình 2D và hình ảnh bitmap động, theo bảng kịch bản lệnh.
Canvas HTML5 là lý tưởng để sản xuất tài liệu hình ảnh thú vị nhằm nâng cao các UI, các bản vẽ, các album ảnh, các biểu đồ, các đồ thị, các hình ảnh động, và các ứng dụng bản vẽ nhúng. Phần tử Canvas có một số phương thức để vẽ các đường, hình chữ nhật, hình tròn, và các nhân vật.
Các tọa độ canvas
Một điều kiện tiên quyết để vẽ trên canvas (khung nền ảnh) là phải biết rõ về vùng lưới hoặc vùng tọa độ. Các phép đo vùng khung nền này theo chiều rộng và chiều cao được tính bằng pixel (điểm ảnh). Canvas được dựng lên xung quanh việc sử dụng các tọa độ x và y. Các tọa độ của canvas tại x=0, y=0 nằm ở góc trên bên trái.
Các thuộc tính mặc định cho vùng hình chữ nhật của canvas có chiều rộng là 300 pixels và chiều cao là 150 pixels, nhưng bạn có thể xác định kích thước chính xác của phần tử canvas này bằng cách quy định chiều rộng và chiều cao. Bản vẽ trong Hình 1 cho thấy cách triển khai thực hiện tọa độ x và y.
- Các góc trên bên trái có x=0, y=0.
- Giá trị x tăng theo chiều ngang, và giá trị y tăng theo chiều dọc.
- Góc dưới cùng bên phải có x=100, y=100.
- Tâm điểm có x=50, y=50.
Để đặt bất cứ thứ gì trên canvas (khung nền ảnh), trước tiên phải định nghĩa canvas trong tệp HTML. Tạo mã JavaScript để truy cập thẻ <canvas> và giao tiếp với Canvas API của HTML5 để vẽ hình ảnh.
Cấu tạo chính của thẻ <canvas> là:
Một phần tử canvas có hai thuộc tính riêng của nó: width (chiều rộng) và height (chiều cao). Ngoài ra, phần tử canvas còn sở hữu tất cả các thuộc tính HTML5 quan trọng, chẳng hạn như class (lớp), id (mã định danh), và name (tên). Thuộc tính id thường dùng trong các mã được hiển thị ở trên. JavaScript sử dụng id của phần tử canvas được tạo ở đây để xác định phần tử canvas để vẽ lên. JavaScript xác định phần tử canvas thích hợp bằng cách sử dụng phương thức document.getElementById(), như được hiển thị dưới đây:
var canvas = document.getElementById("myCanvas");
Mỗi phần tử canvas phải có một định nghĩa ngữ cảnh, như hình dưới đây. Hiện nay, đặc tả chính thức chỉ công nhận môi trường 2D:
var context = canvas.getContext("2d");
Các công cụ vẽ, các hiệu ứng, và các phép biến đổi
Cuộc thảo luận này về Canvas của HTML5 đi qua các công cụ vẽ, các hiệu ứng, và các phép chuyển đổi khác nhau. Các công cụ vẽ bao gồm:
- Các đường kẻ
- Các hình chữ nhật
- Các cung tròn
- Các đường cong Bezier và đường cong bậc hai
- Các hình tròn và hình bán nguyệt
- Các hiệu ứng Canvas mà bạn sẽ sử dụng là:
- Tô đầy và các nét
- Các gradien tuyến tính và xuyên tâm
- Các phép biến đổi được thảo luận bao gồm:
- Tỉ lệ
- Quay tròn
- Tịnh tiến
Các đường vẽ
Để vẽ một đường trên canvas, sử dụng các phương thức moveTo(), lineTo(), và stroke(). Ngoài ra, bạn sử dụng phương thức beginPath() để thiết lập lại đường dẫn hiện tại:
- context.beginPath();
- Context.moveTo(x,y);
- Context.lineTo(x,y);
- Context.stroke(x,y);
Phương thức beginPath() bắt đầu một đường dẫn mới. Trước khi bạn vẽ một đường kẻ mới với các đường dẫn nhỏ khác nhau, bạn phải sử dụng phương thức beginPath() để cho biết rằng một điểm khởi đầu mới cho hướng đi của bản vẽ. Không cần phải gọi phương thức beginPath() khi bạn vẽ đường thẳng đầu tiên.
Phương thức moveTo() cho biết nơi bắt đầu đường dẫn nhỏ mới. Phương thức lineTo() tạo các đường dẫn nhỏ. Bạn có thể thay đổi sự xuất hiện của đường kẻ bằng các phần tử lineWidth và strokeStyle. Phần tử lineWidth thay đổi độ dày của đường này, và strokeStyle thay đổi màu sắc.
Đường kẻ màu xanh dương có hai đầu làm tròn được tạo ra bằng cách đầu tiên thiết lập một đường dẫn mới để bắt đầu:
- context.beginPath(). Tiếp theo là:
- context.moveTo(50, 50), đặt điểm đầu cho đường dẫn này (x=50, y-50)
- context.lineTo(300,50), xác định điểm cuối cho đường kẻ này
- context.lineWidth = 10, là độ rộng của đường kẻ này
- context.strokeStyle = “#0000FF”, là màu sắc của đường kẻ này
- context.lineCap = “round”, làm tròn các đầu đường kẻ
- context.stroke(), thực sự vẽ đường kẻ này trên canvas
Tất cả các đường kẻ đều có chiều dài là 50 pixel, mặc dù chúng xuất hiện có các chiều dài khác nhau — một ảo giác gây ra bởi các mũ đường kẻ khác nhau. Có ba kiểu mũ đường kẻ có thể:
- Context.round (xanh dương)
- Context.square (xanh lá cây)
- Context.butt (màu đỏ tía — mặc định)
Mũ ghép là giá trị mặc định. Khi sử dụng một kiểu mũ tròn hoặc hình vuông, chiều dài của đường kẻ này tăng lên một lượng đúng bằng chiều rộng của đường kẻ này. Ví dụ, một đường kẻ dài 200 pixel và rộng 10 pixel có kiểu mũ tròn hoặc vuông sẽ có chiều dài đường kẻ là 210 pixel, bởi vì mỗi nắp sẽ bổ sung thêm 5 pixel cho mỗi đầu của đường kẻ này. Một đường kẻ dài 200 pixel và rộng 20 pixel có kiểu mũ tròn hoặc vuông sẽ có chiều dài đường kẻ kết quả là 220 pixel, vì mỗi mũ sẽ thêm 10 pixel cho mỗi đầu của đường kẻ này.
Vẽ các hình chữ nhật
Có ba phương thức để xử lý một vùng hình chữ nhật trên canvas:
- fillRect(x,y,width,height), vẽ một hình chữ nhật thêm vào
- strokeRect(x,y,width,height), vẽ nét ngoài của một hình chữ nhật
- clearRect(x,y,width,height), xóa vùng cụ thể và làm cho nó hoàn toàn trong suốt
Đối với một trong ba phương thức nói trên, x và y chỉ ra vị trí trên canvas tương đối so với góc trên bên trái của hình chữ nhật (x=0, y=0), và width và height tương ứng là chiều rộng và chiều cao của hình chữ nhật.
Phương thức fillRect() tạo ra một hình chữ nhật được tô đầy bằng màu đen mặc định. Phương thức clearRect() xóa một vùng hình chữ nhật ở giữa hình chữ nhật đầu tiên. Phương thức strokeRect() tạo ra một hình chữ nhật chỉ có đường viền màu đen nhìn thấy được.
Vẽ các cung, các đường cong, các hình tròn, và các hình bán nguyệt
Cả hai hình tròn và hình bán nguyệt đều sử dụng phương thức arc(). Phương thức arc() có sáu đối số:
context.arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);
Các đối số centerX và centerY là các tọa độ của tâm hình tròn. Đối số radius (bán kính) giống như với toán học là: một đường thẳng từ tâm đến chu vi. Cung được tạo ra sẽ là một phần của hình tròn đã định. Các đối số startAngle và endAngle tương ứng là điểm đầu và điểm cuối của cung tính bằng radian. Đối số anticlockwise (ngược chiều kim đồng hồ) là một giá trị Boolean. Khi giá trị này true (đúng) thì cung được vẽ ngược chiều kim đồng, khi là false (sai) thì cung được vẽ theo chiều kim đồng hồ.
Để vẽ một hình tròn bằng phương thức arc(), hãy định nghĩa góc đầu là 0 và góc cuối là 2*PI
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
Để vẽ một hình bán nguyệt bằng phương thức arc(), hãy xác định góc cuối là startingAngle + PI
context.arc(centerX, centerY, radius, startingAngle, startingAngle + Math.PI, false);
Đường cong bậc hai
Bạn tạo một đường cong bậc hai bằng cách sử dụng phương thức quadraticCurveTo() được hiển thị dưới đây. Các đường cong bậc hai được xác định bởi điểm ngữ cảnh, một điểm điều khiển, và một điểm cuối. Điểm điều khiển xác định độ cong của đường thẳng này.
context.moveTo(x, y); context.quadraticCurveTo(controlX, controlY, endX, endY);
Đường cong Bezier
Cũng như với đường cong bậc hai, đường cong Bezier có một điểm đầu và cuối; nhưng không giống đường cong bậc hai, nó có hai điểm điều khiển:
context.moveTo(x, y); context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
Tạo một đường cong Bezier bằng phương thức bezierCurveTo(). Vì đường cong Bezier được định nghĩa có hai điểm điều khiển chứ không phải chỉ có một, nên bạn có thể tạo các độ cong phức tạp hơn.
Arcs, Curves, Circles, & Semicircles
Các phép biến đổi: tịnh tiến, tỷ lệ, và quay tròn
Các phương thức translate(), scale(), và rotate() tất cả đều sửa đổi ma trận hiện tại. Phương thức translate(x, y) di chuyển các mục trên canvas đến một điểm khác trên lưới. Trong phương thức translate(x,y), các tọa độ (x,y) cho biết số điểm ảnh mà ảnh nên được di chuyển theo hướng-x và số điểm ảnh mà ảnh phải được di chuyển theo hướng-y.
Nếu bạn vẽ một ảnh tại (15,25) bằng phương thức drawImage(), bạn có thể sử dụng phương thức translate() có các đối số (20,30), để đặt ảnh này ở vị trí (15+20, 25+30) = (35, 55).
Phương thức scale(x,y) thay đổi kích thước của một ảnh. Đối số x xác định rõ hệ số tỷ lệ theo chiều ngang, và đối số y xác định rõ hệ số tỷ lệ theo chiều dọc. Ví dụ, scale(1.5, .75) sẽ tạo một ảnh lớn hơn 50% theo hướng x và chỉ bằng 75% kích thước hiện tại theo hướng y. Phương thức rotate(angle) chuyển đổi một đối tượng dựa trên góc đã định.
Transformations Example
Gradien
Một gradien là một vùng tô đầy di chuyển từ một màu này sang màu khác, pha trộn các màu ở nơi chúng giao nhau. Có hai kiểu gradien mà bạn có thể tạo trong Canvas là: tuyến tính và xuyên tâm.
Tạo ra một gradien tuyến tính bằng phương thức createLinearGradient(). Phương thức createLinearGradient(x0,y0,x1,y1) tạo ra một gradien dọc theo một đường thẳng được xác định bởi hai điểm: (x0,y0) và (x1,y1)— tương ứng, là điểm đầu và điểm cuối của gradien. Phương thức này trả về một đối tượng.
Một gradien màu có thể có nhiều màu sắc. Phương thức addcolorStop(offset, color) xác định rõ sự lưu lại màu với màu sắc được chỉ ra cho gradien ở giá trị bù cụ thể. Phương thức addColorStop() cho phép bạn chỉ rõ một giá trị bù giữa 0 và 1, ở đây quá trình chuyển tiếp sang màu bên cạnh bắt đầu. Giá trị 0 là giá trị bù ở một đầu của gradien; 1 là giá trị bù ở đầu kia. Sau khi đã định nghĩa gradien màu, đối tượng gradien có thể được gán cho phương thức fillStyle(). Bạn cũng có thể vẽ văn bản bằng một gradien bằng cách sử dụng phương thức fillText().
Gradien xuyên tâm —createradialGradient(x0,y0,r0,x1,y1,r1)— kết hợp hai hoặc nhiều màu trong một mẫu hình tròn hoặc hình nón bằng cách sử dụng sáu đối số:
- (x0,y0). Tâm của hình tròn đầu tiên của một hình nón
- r0. Bán kính của hình tròn đầu tiên
- (x1,y1). Tâm của hình tròn thứ hai của hình nón
- r1. Bán kính của hình tròn thứ hai
Cắt ảnh
Cắt trên canvas là một hàm chất tải lên phương thức drawImage(). Phương thức drawImage() có ba tùy chọn. Bạn có thể sử dụng hoặc ba, năm, hoặc chín đối số.
Cấu hình ba-đối số —drawImage(image, dx, dy)— vẽ ảnh này trên canvas ở tọa độ đích (dx, dy). Các tọa độ này thiết lập góc trên bên trái của hình ảnh.
Cấu hình năm-đối số —drawImage(image, dx, dy, dw, dh)—đưa ra chiều rộng và chiều cao của ảnh đích. Hình ảnh này được điều chỉnh để phù hợp với chiều rộng và chiều cao của đích này.
Cấu hình chín-đối số —drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)— lấy một hình ảnh, cắt rời ra một vùng hình chữ nhật bắt đầu ở các tọa độ nguồn (sx,sy) với chiều rộng và chiều cao (sw,sh), và điều chỉnh nó cho phù hợp với chiều rộng và chiều cao (dw,dh) của đích này, đặt nó trên canvas tại (dx,dy).
Ảnh gốc
Crop Example
Ảnh đã cắt xong
Hình ảnh động và nhiều canvas
Các lớp cho phép các thành phần được tách rời nhau, làm cho việc mã hóa và gỡ lỗi dễ dàng hơn và hiệu quả hơn. Canvas API không có các lớp, nhưng bạn có thể tạo nhiều khung nền ảnh (canvas).
Hình ảnh động phải được kiểm soát theo thời gian. Vì vậy, để tạo một hình ảnh động, phải giải quyết từng khung hình của hình ảnh động. Canvas API có hạn chế chủ yếu khi nó tạo hình ảnh động: Sau khi một hình được gỡ khỏi canvas, nó vẫn như vậy. Để di chuyển hình này, cần phải vẽ lại nó.
Để tạo một hình ảnh động:
- 1. Hãy xóa canvas của các hình bất kỳ đã được vẽ trước đó.
- 2. Lưu lại trạng thái canvas để đảm bảo trạng thái ban đầu được sử dụng mỗi khi một khung được vẽ.
- 3. Thực hiện các bước để hiển thị các khung hình.
- 4. Nếu bạn đã lưu trạng thái đó, hãy khôi phục lại nó trước khi vẽ một khung mới.
Bạn có thể điều khiển hình ảnh động theo hai cách: bằng cách sử dụng các hàm setInterval hay setTimeout, mỗi hàm có thể được dùng để gọi một hàm theo một khoảng thời gian đặt trước. Hàm setInterval thực hiện mã được cung cấp lặp lại nhiều lần. Hàm setTimeout chỉ thực hiện một lần sau khi thời gian đặt trước đã trôi qua.
Người bơi này sử dụng một gradien tuyến tính để tạo nước. Nước có bốn sắc thái của màu xanh, cung cấp một ảo giác hợp lý của nước. Bạn tạo chuyển động cho người bơi bằng cách sử dụng các giá trị positionX và positionY, để làm thay đổi các tư thế của ảnh. Bạn tạo đầu của người bơi bằng cách sử dụng phương thức arc(). Các chân và cánh tay của người bơi được tạo bằng cách vẽ các đường kẻ rồi thay đổi các vị trí lineTo() của chúng. Bạn thay đổi thân bằng cách thay đổi vị trí moveTo(). Vì đây là một hình ảnh động, nên bạn sẽ phải thực hiện đoạn mã này để xem người bơi chuyển động như thế nào.
Animation & Multiple Canvas Example
[highlighter]