Vai trò của tác giả HTML5, một sự kết hợp dũng cảm của nhà thiết kế và nhà
phát triển, là để xây dựng các ứng dụng Internet phong phú có hiệu quả
(RIA) và đặc biệt là các UI phong phú. Về hiệu quả tôi muốn nói
về việc tạo các cải tiến nói chung và các cải tiến có tính hệ thống mà về
mặt kỹ thuật số làm cho đàm thoại dễ dàng giữa chủ sở hữu trang web, các
đại lý của chủ sở hữu và người sử dụng của trang web.
Các RIA là nguồn gốc và phương tiện truyền bá kinh nghiệm làm thỏa mãn
người dùng và, do đó, là một phần thiết yếu của bất kỳ công việc kinh
doanh lấy mạng làm trung tâm thành công nào. Theo tự nhiên, các hoạt động
lấy mạng làm trung tâm có tính chất cộng tác ở mức độ này hay khác. Một
cách tiếp cận thành công với sự cộng tác kỹ thuật số là cần thiết cho sự
thành công của đại lý ở tất cả các cấp, bao gồm tiếp thị và quản lý. Cần
vượt qua khả năng để trang web đáp ứng được những mong đợi về chất lượng
của khách truy cập của nó.
HTML5, như bạn đã thấy, là hoàn toàn thích hợp cho "một thế giới web" có
tính cộng tác về các khả năng xuyên qua các nền tảng, hội tụ viễn thông,
ngôn ngữ thống nhất, điện toán ở khắp nơi, và các hệ thống mở. Ba bài đăng
đầu tiên của loạt bài này tập trung vào ngữ nghĩa, các phương thức mã hóa
thích hợp, đầu vào đóng vai trò trong quá trình trao đổi quan trọng, và
các cách thực hành tốt nhất về quản lý trang web, tất cả đều được thiết kế
để đặt nền móng tạo ra các RIA theo cách có tổ chức và hợp lý. Các chủ đề
phổ biến trong mỗi bài viết đã đăng là việc sản xuất và quản lý một trải
nghiệm người dùng phong phú là rất quan trọng để đạt được các mục tiêu đại
lý của chủ sở hữu trang web đó. Canvas của HTML5 đóng một vai trò quan
trọng trong sự phát triển các RIA hiệu quả.
Canvas là?
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
.
Hình 1. Các tọa độ canvas
Hình 1 cho thấy một vùng canvas 100 pixel x 100 pixel:
- 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
.
Bắt đầu
Để đặt bất cứ thứ gì trên canvas (khung nền ảnh), trước tiên bạn phải định
nghĩa canvas trong tệp HTML. Bạn phải 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ủa bạn.
Cấu tạo chính của thẻ <canvas>
là:
<canvas id="myCanvas" width="200" height="200"></canvas>
|
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");
|
Sau khi bạn xác định phần tử canvas và xác định rõ ngữ cảnh của nó, bạn đã
sẵn sàng bắt đầu vẽ.
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.
Trong Hình 2, ba đường kẻ được vẽ tương ứng bằng màu xanh dương, xanh lá
cây, và màu đỏ tía.
Hình 2. Canvas có các đường kẻ theo
ba màu khác nhau
Các đường kẻ trong Hình 2 do đoạn mã trong Liệt kê 1
tạo ra. Đườ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 bạn 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.
Thực hiện và làm thay đổi mã trong Liệt kê 1 để có được hiểu biết nhiều hơn
về cách vẽ các đường kẻ.
Liệt kê 1. Tạo ba đường kẻ có màu khác nhau trên canvas
<!DOCTYPE HTML>
<html>
<head>
<title>Line Example</title>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style>
<script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
// blue line with round ends
context.beginPath();
context.moveTo(50, 50);
context.lineTo(300,50);
context.lineWidth = 10;
context.strokeStyle = "#0000FF";
context.lineCap = "round";
context.stroke();
// green line with square ends
context.beginPath();
context.moveTo(50, 100);
context.lineTo(300,100);
context.lineWidth = 20;
context.strokeStyle = "#00FF00";
context.lineCap = "square";
context.stroke();
// purple line with butt ends
context.beginPath();
context.moveTo(50, 150);
context.lineTo(300, 150);
context.lineWidth = 30;
context.strokeStyle = "#FF00FF";
context.lineCap = "butt";
context.stroke();
};
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="200">
</canvas>
</body>
</html>
|
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.
Hình 3 cho thấy ba vùng hình chữ nhật do đoạn mã trong Liệt kê 2 tạo ra.
Hình 3. Canvas 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. Đó là cùng giữa hình chữ nhật được hình thành bởi
phương thức fillRect()
. 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.
Liệt kê 2. Mã canvas hình chữ nhật
<!DOCTYPE HTML>
<html>
<head>
<title>Rectangle Example</title>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #000000;
background-color: #ffff00;
}
</style>
<script type="text/javascript">
function drawShape(){
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.fillRect(25,25,50,50);
context.clearRect(35,35,30,30);
context.strokeRect(100,100,50,50);
}
</script>
</head>
<body onload="drawShape();">
<canvas id="myCanvas" width="200" height="200"></canvas>
</body>
</html>
|
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
, như được hiển thị dưới đây:
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
, như được hiển thị dưới đây:
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);
|
Bạn 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.
Hình 4 hiển thị — từ trái sang phải — một
cung, một đường cong bậc hai, một đường cong Bezier, một hình bán nguyệt,
và một hình tròn.
Hình 4. Cung, các đường cong, và các
hình tròn
Hình 4 được tạo bằng cách sử dụng mã trong Liệt kê 3.
Liệt kê 3. Mã của cung, đường cong, và hình tròn
<!DOCTYPE HTML>
<html>
<head>
<title>Arcs, Curves, Circles, & Semicircles</title>
<style>
body {
margin: 0px;
padding: 0px;
}
#myCanvas {
border: 1px solid #9C9898;
}
</style>
<script>
function drawArc(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var centerX = 100;
var centerY = 160;
var radius = 75;
var startingAngle = 1.1 * Math.PI;
var endingAngle = 1.9 * Math.PI;
var counterclockwise = false;
context.arc(centerX, centerY, radius, startingAngle,
endingAngle, counterclockwise);
context.lineWidth = 10;
context.strokeStyle = "black";
context.stroke();
};
function drawQuadratic(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.moveTo(200, 150);
var controlX = 288;
var controlY = 0;
var endX = 388;
var endY = 150;
context.quadraticCurveTo(controlX, controlY, endX, endY);
context.lineWidth = 10;
context.strokeStyle = "black";
context.stroke();
};
function drawBezier(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.moveTo(350, 350);
var controlX1 = 440;
var controlY1 = 10;
var controlX2 = 550;
var controlY2 = 10;
var endX = 500;
var endY = 150;
context.bezierCurveTo(controlX1, controlY1, controlX2,
controlY2, endX, endY);
context.lineWidth = 10;
context.strokeStyle = "black";
context.stroke();
};
function drawCircle(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var centerX = 450;
var centerY = 375;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = "#800000";
context.fill();
context.lineWidth = 5;
context.strokeStyle = "black";
context.stroke();
};
function drawSemicircle(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
var centerX = 100;
var centerY = 375;
var radius = 70;
var lineWidth = 5;
context.beginPath();
context.arc(centerX, centerY, radius, 0, Math.PI, false);
context.closePath();
context.lineWidth = lineWidth;
context.fillStyle = "#900000";
context.fill();
context.strokeStyle = "black";
context.stroke();
};
window.onload = function (){
drawArc();
drawQuadratic();
drawBezier();
drawCircle();
drawSemicircle()
}
</script>
</head>
<body>
<canvas id="myCanvas" width="600" height="500">
</canvas>
</body>
</html>
|
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.
Hình 5 là một ví dụ về những gì có thể được đưa ra khi sử dụng các phương
thức translate()
,
scale()
, và
rotate()
.
Hình 5. Sử dụng các phép biến
đổi
Liệt kê 4 cung cấp đoạn mã đã tạo ảnh trong Hình 5.
Liệt kê 4. Mã để tạo các phép biến đổi
<!DOCTYPE HTML>
<html>
<head>
<Title>Transformations Example</title>
<script>
window.onload = function() {
var canvas=document.getElementById("myCanvas");
var context=canvas.getContext("2d");
var rectWidth = 250;
var rectHeight = 75;
// translate context to center of canvas
context.translate(canvas.width/2,canvas.height/2);
// half the y component
context.scale(1,0.5);
// rotate 45 degrees clockwise
context.rotate(-Math.PI/4);
context.fillStyle="blue";
context.fillRect(-rectWidth/2,-rectHeight/2,
rectWidth,rectHeight);
// flip context horizontally
context.scale(-1,1);
context.font="30pt Calibri";
context.textAlign="center";
context.fillStyle="#ffffff";
context.fillText("Mirror Image",3,10);
}
</script>
</head>
<body>
<canvas id="myCanvas" width="400" height="400"></canvas>
</body>
</html>
|
Các 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.
Bạn 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
Hình 6 có bốn gradien: một gradien tuyến tính, một gradien văn bản, một
gradien tuyến tính theo đường chéo, và một gradien xuyên tâm.
Hình 6. Ví dụ về gradien
Hình 6 đã được tạo bằng cách sử dụng mã trong Liệt kê 5.
Liệt kê 5. Mã mẫu của gradien
<!doctype>
<html>
<head>
<title>Gradient Example</title>
<script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
//Let's try the gradient on a rectangle
// Create a linear gradient
var fillColor = context.createLinearGradient(50,50, 150,50);
// Set gradient colors
fillColor.addColorStop(0.15,"red");
fillColor.addColorStop(0.35,"black");
fillColor.addColorStop(0.65,"green");
fillColor.addColorStop(0.87,"yellow");
// Assign gradient object to fillstyle
context.fillStyle= fillColor;
// Draw rectangle
context.fillRect(50,50,100,100);
// With text
var fillColorText = context.createLinearGradient(300,50,600,50);
fillColorText.addColorStop(0.2,"red");
fillColorText.addColorStop(0.4,"black");
fillColorText.addColorStop(0.6,"green");
fillColorText.addColorStop(0.8,"yellow");
context.fillStyle= fillColorText;
context.font="40px verdana";
context.textBaseline="top";
context.fillText("With text too!", 300,50)
// Gradient on a diagonal
var fillColordiagonal = context.createLinearGradient(50,200, 100,450);
// Gradient colors
fillColordiagonal.addColorStop(0.2,"red");
fillColordiagonal.addColorStop(0.4,"black");
fillColordiagonal.addColorStop(0.6,"green");
fillColordiagonal.addColorStop(0.75,"yellow");
// Assign gradient object to fillstyle
context.fillStyle= fillColordiagonal;
// Draw rectangle
context.fillRect(50,225, 100,250);
// Draw radial gradient
fillColorRadial = context.createRadialGradient(450,300,0, 450,300,200);
fillColorRadial.addColorStop(0, "red");
fillColorRadial.addColorStop(0.2, "black");
fillColorRadial.addColorStop(0.4, "green");
fillColorRadial.addColorStop(0.7, "yellow");
context.fillStyle = fillColorRadial;
context.rect(300,200,500,400);
context.fill();
}
</script>
</head>
<body>
<div>
<p><canvas id="myCanvas" width="600" height="400"></canvas></p>
</div>
</body>
</html>
|
Cắt ảnh
Bạn có thể thay đổi các ảnh bằng cách cắt các vùng đã chọn bên ngoài chúng.
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)
.
Hình 7 cho thấy hình ảnh mà bạn sẽ cắt ra.
Hình 7. Cắt một ảnh
Khi sử dụng ảnh được hiển thị trong Hình 7, một tập các ảnh được đặt trên
canvas (khung nền ảnh) này. Một ảnh là một canvas đã định kích thước và
được sử dụng làm khung nền. Một ảnh khác được tạo ra nhỏ hơn và chèn vào
phía dưới bên phải của khung nền đó. Một ảnh thứ ba là ảnh cắt ra phần đầu
của Napoleon mà bạn đặt ở góc trên bên trái của khung nền này. Ảnh đã cắt
xong được hiển thị trong Hình 8.
Hình 8. Ảnh đã cắt xong
Hình 8 được tạo bằng cách sử dụng đoạn mã trong Liệt kê 6. Trước khi thực
hiện mã này, hãy chắc chắn tải tệp ảnh
Napolean.png được dùng trong ví dụ này.
Liệt kê 6. Đoạn mã để cắt ảnh ví dụ
<!doctype>
<html>
<head>
<title>Crop Example</title>
<script type="text/javascript">
window.onload = function() {
var canvas=document.getElementById("cropNapolean");
var context=canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function() {
// draw image to cover the entire canvas
context.drawImage(imageObj,0,0, 600, 400);
// draw small image in bottom right corner
var sourceX = 0;
var sourceY = 0;
var sourceWidth = 1200;
var sourceHeight = 801;
var destX = 300;
var destY = 200;
var destWidth = sourceWidth - 900;
var destHeight = sourceHeight - 600;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth,
sourceHeight, destX, destY, destWidth, destHeight);
//draw Napolean's head only
var sourceNapoleanX = 460;
var sourceNapoleanY = 25;
var sourceNapoleanWidth = 250;
var sourceNapoleanHeight = 175;
var destNapoleanX = 0;
var destNapoleanY = 0;
var destNapoleanWidth = sourceNapoleanWidth - 150 ;
var destNapoleanHeight = sourceNapoleanHeight - 100;
context.drawImage(imageObj, sourceNapoleanX, sourceNapoleanY,
sourceNapoleanWidth, sourceNapoleanHeight,
destNapoleanX, destNapoleanY,
destNapoleanWidth, destNapoleanHeight);
}
imageObj.src = "Napoleon.png";
}
</script>
</head>
<body>
<div>
<p><canvas id="cropNapolean" width="600" height="400"></canvas></p>
</div>
</body>
</html>
|
Hình ảnh động và nhiều
canvas
Khi làm việc với hình ảnh động, câu hỏi về các lớp luôn phát sinh. 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, bạn 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, bạn phải vẽ lại nó.
Để tạo một hình ảnh động:
- Hãy xóa canvas của các hình bất kỳ đã được vẽ trước đó.
- 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ẽ.
- Thực hiện các bước để hiển thị các khung hình.
- 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.
Hình 9 cho thấy một khung hình của hình ảnh động nhiều canvas của người
bơi. Nước ở trên một canvas, và người bơi ở trên một canvas khác.
Hình 9. Hình ảnh động khi sử dụng
các hình ảnh trên nhiều canvas
Bạn tạo người bơi bằng cách sử dụng đoạn mã trong Liệt kê 7. 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.
Liệt kê 7. Ví dụ về hình ảnh động
<!DOCTYPE HTML>
<html>
<head>
<title>Animation & Multiple Canvas Example</title>
<script>
// Water canvas
function drawWater() {
var canvasWater = document.getElementById("myWaterCanvas");
var contextWater = canvasWater.getContext("2d");
contextWater.globalAlpha = .50 ;
// Create a linear gradient fill
var linearGrad = contextWater.createLinearGradient(0,0,400,400);
linearGrad.addColorStop(0, '#0000ff'); // sets the first color
linearGrad.addColorStop(.25, '#0099ff'); // sets the second color
linearGrad.addColorStop(.50, '#00ccff'); // sets the third color
linearGrad.addColorStop(.75, '#00ffff'); // sets the fourth color
contextWater.fillStyle = linearGrad;
contextWater.fillRect(0,0,400,400);
}
// Swimmer canvas
setInterval(drawSwimmer, 30);
var positionX = 0;
var positionY = 0;
function drawSwimmer(){
var canvasSwimmer = document.getElementById("mySwimmerCanvas");
var contextSwimmer = canvasSwimmer.getContext("2d");
contextSwimmer.clearRect(0,0,400,400);
if (positionX < 30)
{
positionX += 1;
positionY += 1;
}
else
{
positionX = 0;
positionY = 0;
}
contextSwimmer.save();
// draw circle for head
var centerX = 200;
var centerY = 50;
var radius = 20;
contextSwimmer.beginPath();
contextSwimmer.arc(centerX, centerY+positionY,
radius, 0, 2 * Math.PI, false);
contextSwimmer.fillStyle = "#000000";
contextSwimmer.fill();
contextSwimmer.lineWidth = 5;
// torso
contextSwimmer.beginPath();
contextSwimmer.moveTo(200,70+positionY);
contextSwimmer.lineTo(200,175);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// image right arm
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(175-positionX,140-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// image left arm
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(225+positionX,140-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// image right leg
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 175);
contextSwimmer.lineTo(190-positionX,250-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// image left leg
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 175);
contextSwimmer.lineTo(210+positionX,250-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
contextSwimmer.restore();
};
</script>
</head>
<body onload="drawWater();">
<canvas id="myWaterCanvas" width="400" height="400" style="z-index: 2;
position:absolute;left:0px;top:0px;">
</canvas>
<canvas id="mySwimmerCanvas" width="400" height="400" style="z-index: 1;
position:absolute;left:0px;top:0px;">
</canvas>
</body>
</html>
|
Kết luận
Canvas HTML5 là điểm chính để xây dựng các RIA dựa trên trình duyệt. Nó
cung cấp một môi trường vẽ thiết thực được JavaScript và trí tưởng tượng
của bạn thúc đẩy. Nó không thực sự khó học, và có nhiều công cụ hỗ trợ
trên trang web cho nhu cầu rèn luyện và học tập của bạn, bao gồm các cẩm
nang, các blog, các bài viết trực tuyến, các hướng dẫn video và
không-video, và các ứng dụng mẫu.
Khả năng để thay đổi văn bản và hình ảnh trực quan và để mô phỏng chuyển
động làm cho Canvas trở thành một công cụ vô cùng có giá trị. Cho dù bạn
tiếp cận nó từ quan điểm của một nhà thiết kế hay nhà phát triển, việc sử
dụng Canvas để xây dựng các ứng dụng trò chơi chạy trên các thiết bị di
động, hoặc chỉ muốn nâng cao việc sử dụng toàn bộ tài sản thực của màn
hình, thì Canvas vẫn là một thành phần quan trọng của trải nghiệm HTML5.