(譯者注:由於yeeyan編輯器對文章中的標簽做解析的原因,我在每個標簽的<符號之後都加入了一個空格,比如說,左尖括號<+head+右尖括號>,我會寫成< head>,以便其能夠在文章中正確顯示,不便之處敬請諒解。)
使用Html5來編寫代碼的人,有著設計者和開發者雙重身份的強悍組合,其職責是構造出高效的富互聯網應用(rich Internet application,RIA),特別是豐富的用戶界面。就高效這個字眼來說,我的意思是指系統級的和系統性的創造力增強,這種增強以數字化的方式促進了站點所有者、所有者的代理機構和站點用戶之間的對話。
RIA是用戶獲得滿意體驗的來源之處和媒介,因此,它是任何成功的以網絡為中心的風險投資的重要組成部分。以網絡為中心的活動,就性質來說,或多或少都是協作式的。公司要在包括了市場營銷和管理的各個層面都取得成功的話,數字化協作的制勝方法是至關重要的。很多時候的很多情況都取決於效率,網站要依靠效率來滿足其訪問者的品質期望。
正如你已經見到的那樣,Html5是為這一具有跨平台能力、融合了通信、使用統一語言、提供無處不在的計算,以及基於開放系統的協作式“一網化世界(one web world)”量身定做的。這一文章系列的前面三部分內容重點關注語義、正確的編碼方法、輸入在極為重要的轉化過程中的作用,以及站點管理最佳做法等,所有這些的目的都是在為以一種有組織和符合邏輯的方式來創建RIA奠定基礎。每篇文章中都共有的一個主題是,對於實現網站所有者的機構目標來說,制造並管理豐富的用戶體驗是至關重要的。
什麼是Canvas?
Html5 Canvas(畫布)是一個非常有用的繪圖和動畫元素,Canvas使用JavaScript來直接在頁面上繪制圖形。這是一個由你來定義和控制的長方形區域,該區域允許動態、可腳本渲染的2D圖形和位圖圖像。
在制作用來增強UI、示意圖、相冊、圖表、圖形、動畫和嵌入式繪圖應用的那些非常棒的視覺材料方面,Html5堪稱完美。Canvas元素有一些用來繪制路徑、矩形、圓形和字符的方法。
Canvas的坐標
在畫布上繪圖的一個先決條件是要熟悉網格或是坐標空間,寬度和高度的空間區域測量是以像素為單位給出的。畫布是基於x和y坐標的使用來構建的,畫布的x=0, y=0坐標位於左上角。
畫布的矩形區域的默認屬性是300像素的寬度和150像素的高度,但你可以通過指定寬度和高度來確定畫布元素的確切大小。圖1中的示意圖說明了x和y坐標的實現方式。
圖1. Canvas的坐標
圖1給出了一個100像素X100像素的畫布區:
1. 左上角是x=0,y=0。
2. x的值水平增加,y的值垂直增加。
3. 右下角是x=100,y=100。
4. 中間的點是x=50,y=50。
開始第一步
要在畫布上放置任何東西的話,你首先必須在Html文件中定義畫布。你必須創建訪問< canvas>標簽的JavaScript代碼,並通過與Html5 Canvas API通信來繪制你的圖像。
< canvas>標簽的基本結構如下:
< canvas id="myCanvas" width="200" height="200">< /canvas>
canvas元素自身有兩個屬性:width和height,除此之外,canvas還擁有所有主要的Html5屬性,比如說class、id和name等。id屬性被用在上面所示的代碼中,Javascript使用這裡創建的canvas的id來表示要在上面繪畫的畫布。JavaScript使用document.getElementById()方法來確定正確的畫布,如下面代碼所示:
var canvas = document.getElementById("myCanvas");
每個畫布都必須要有一個context(上下文)的定義,如下面代碼所示。就目前的情況來說,官方規范只承認一個2D環境:
var context = canvas.getContext("2d");
在標識畫布並指明了它的上下文之後,你就做好了開始繪畫的准備了。
繪圖工具、效果和轉換
在Html5 Canvas的這一討論過程中,我們對各種繪圖工具、效果和轉換都查看一番。繪圖工具包括:
1. 線條
2. 矩形
3. 圓弧
4. 貝塞爾曲線和二次曲線
5. 圓和半圓
你會用到的Canvas效果包括:
1. 填充和描邊
2. 線性和徑向的漸變
要討論的轉換包括:
1. 縮放
2. 旋轉
3. 平移
繪制線段
要在畫布上繪制線段的話,你可以使用moveTo()、lineTo()和stroke()方法,此外,你要使用beginPath()方法來重置當前路徑:
1. context.beginPath();
2. Context.moveTo(x,y);
3. Context.lineTo(x,y);
4. Context.stroke(x,y);
beginPath()方法開始一條新的路徑,在使用不同的子路徑繪制一條新的線段之前,你必須要使用beginPath()來標明一個繪制過程要遵循的新起點。在繪制第一條線段時,beginPath()方法的調用不是必須的。
moveTo()方法指明新的子路徑從哪裡開始,lineTo()方法創建子路徑。你可以使用lineWidth和strokeStyle來改變線段的外觀,lineWidth元素改變線段的粗細,strokeStyle改變顏色。
在圖2中,三條線段分別用藍色、綠色和紫色畫了出來。
圖2. 畫有三條不同顏色的線段的畫布
圖2中的線段由清單1中的代碼來創建,藍色的線段有著圓弧形的端點,該線段是由首個context.beginPath()這一開始新路徑的建立的方法來創建的,其後緊跟著:
1. context.moveTo(50, 50),該方法把線路的起點置於(x=50, y=50)
2. context.lineTo(300,50),該方法標識線段的終點
3. context.lineWidth = 10,該屬性是線段的寬度
4. context.strokeStyle = "#0000FF",該屬性是線段的顏色
5. context.lineCap = "round",該屬性把端點設成是圓弧狀的
6. context.stroke(),該方法真正在畫布上繪制該線段
所有線段的長度都是50像素,盡管它們看上去不一樣長——這是由線段的線帽(line cap)造成的視覺錯覺。可用的線帽有三種:
1. Context.round (blue)
2. Context.square (green)
3. Context.butt (purple)——默認值
對接(butt)線帽是默認值,當你使用圓形(round)或是方形(square)的線帽風格時,線段的長度會增加,加上一段相當於線段寬度的長度。例如,一個長度為200像素,寬度為10像素,有著圓形或是方形線帽風格的線段,其最終的線段長度是210像素,因為每個線帽都都往線段的每一端加上了5個像素的長度。而一個長度為200像素,寬度為20像素,有著圓形或是方形的線帽風格的線段的最終長度是220像素,因為每個線帽都往線段每一端加上了10像素的長度。
通過執行和修改清單1中的代碼來更好地理解線段的繪制方式。
清單1. 在畫布上創建三條不同顏色的線段
< !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");
// 有著圓形端點的藍色線段
context.beginPath();
context.moveTo(50, 50);
context.lineTo(300,50);
context.lineWidth = 10;
context.strokeStyle = "#0000FF";
context.lineCap = "round";
context.stroke();
// 有著方形端點的綠色線段
context.beginPath();
context.moveTo(50, 100);
context.lineTo(300,100);
context.lineWidth = 20;
context.strokeStyle = "#00FF00";
context.lineCap = "square";
context.stroke();
// 有著對接端點的紫色線段
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>
繪制矩形
有三個方法可用來在畫布上給出一個矩形的區域:
1. fillRect(x,y,width,height),該方法繪制一個有填充的矩形
2. strokeRect(x,y,width,height),該方法繪制一個矩形的外邊框
3. clearRect(x,y,width,height),該方法清空指定的區域,使之變得完全透明
對於這三個方法中的每個來說,x和y表示的都是畫布上相對於矩形(x=0, y=0)的左上角的位置,width和height分別是矩形的寬度和高度。
圖3顯示了由清單2中的代碼創建的三個矩形。
圖3. 畫有矩形的畫布
fillRect()方法創建了一個以缺省的黑色為填充色的矩形;clearRect()方法在第一個矩形的中心部分清除出一個矩形區域,該區域位於由fillRect()方法產生的矩形的中央位置;strokeRect創建了一個只有可見的黑色邊框的矩形。
清單2. 矩形畫布的代碼
< !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>
繪制圓弧、曲線、圓和半圓
圓和半圓都是使用arc()方法來繪制,arc()方法用到了六個參數:
context.arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);
centerX和centerY參數是圓的中心坐標,radius就是數學上的半徑:從圓心到圓周線的一條直線。弧形是作為所定義的圓的一部分來創建的,startAngle和endAngle參數分別是圓弧的起點和終點,以弧度為單位。anticlockwise參數是一個布爾(Boolean)值,當其值為true時,弧形按逆時針方向來繪制,當其值為false時,弧形按順時針方向來繪制。
要使用arc()方法來繪制圓的話,把起始角度定義成0,把結束角度定義成2*PI,如下所示:
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
要使用arc()方法來繪制半圓的話,把結束角度定義成startingAngle + PI,如下所示:
context.arc(centerX, centerY, radius, startingAngle, startingAngle + Math.PI, false);
二次曲線
quadraticCurveTo()方法被用來創建一條二次曲線,如下所示。二次曲線通過上下文中的點、一個控制點以及一個結束點來定義。控制點確定了線的曲度。
context.moveTo(x, y);
context.quadraticCurveTo(controlX, controlY, endX, endY);
貝塞爾曲線
正和二次曲線一樣,貝塞爾曲線也有一個起點和一個終點,但和二次曲線不同的是,它有兩個控制點:
context.moveTo(x, y);
context.bezIErCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
你可使用bezIErCurveTo()方法來創建貝塞爾曲線,因為貝塞爾曲線是由兩個控制點而不僅是由一個控制點來定義的,所有你可以創造出更加復雜的曲度來。
圖4的顯示——從左到右——為一條圓弧、一條二次曲線、一條貝塞爾曲線、一個半圓和一個圓。
圖4. 圓弧、曲線和圓
圖4的內容是用清單3中的代碼來創建的。
清單3. 圓弧、曲線和圓的代碼
< !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>
轉換:平移、縮放和旋轉
translate()、scale()和rotate()方法都會修改當前的矩陣。translate(x, y)方法把畫布上的項目移動到網格上的不同點上,在translate(x, y)方法中,(x,y)坐標指明了圖像在x方向和y方向上應該移動的像素數。
如果你使用drawImage()方法來在(15,25)這一位置繪制一個圖像的話,你可以使用(20,30)作為參數的來調用translate(),該調用把圖像放在(15+20, 25+30) = (35, 55)這一位置上。
scale(x,y)方法改變圖像的大小,x參數指明水平方向的比例系數,y參數指明垂直方向的比例系數。例如,scale(1.5, .75)將創建一個在x方向加大50%,而在y方向只相當於當前尺寸75%的圖像。rotate(angle)方法返回一個基於指定角度的對象。
圖5是一個可以使用translate()、scale()和rotate()進行渲染的圖像例子。
圖5. 使用轉換
清單4提供的代碼創建了圖5中的圖像。
清單4. 創建轉換的代碼
< !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;
// 把context平移到畫布的中心
context.translate(canvas.width/2,canvas.height/2);
// y方向的組成減半
context.scale(1,0.5);
// 順時針旋轉45度
context.rotate(-Math.PI/4);
context.fillStyle="blue";
context.fillRect(-rectWidth/2,-rectHeight/2,
rectWidth,rectHeight);
// 水平方向翻轉context
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>
漸變
漸變(gradIEnt)是指從一種顏色向另一種顏色變化的填充,在顏色相交的地方做融合。在Canvas中你可以創建兩種類型的漸變:線性的和徑向的。
createLinearGradient()方法被用來創建線性的漸變。createLinearGradIEnt(x0,y0,x1,y1)沿著一條由兩個點(x0,y0)和(x1,y1)來標識的直線產生一個漸變,這兩個點分別是漸變的起點和終點。該方法返回一個對象。
顏色的漸變可以有多種顏色,addcolorStop(offset, color) 方法為被標明為在給定的偏移量上漸變的顏色指明了顏色過渡點。addColorStop()方法讓你在0和1之間指定一個偏移量,以這一偏移量為依據來開始過渡到下一種顏色。值0是漸變的一端的偏移量,1是另一端的偏移量。在顏色的漸變定義好了之後,漸變對象就可以被賦值給fillStyle()。你也可以使用fillText()方法來繪制出帶有漸變的文字來。
徑向漸變——createradialGradIEnt(x0,y0,r0,x1,y1,r1)——使用六個參數以一種圓形或是圓錐形的模式來組合兩種或多種顏色。
1. (x0,y0): 圓錐的第一個圓的中心
2. r0:第一個圓的半徑
3. (x1,y1):圓錐的第二個圓的中心
4. r1:第二個圓的半徑
圖6包含了四種漸變:一個線性漸變、一個文本漸變、一個對角線上的漸變和一個徑向漸變。
圖6. 漸變的例子
圖6的內容是使用清單5中的代碼創建出來的。
清單5. 漸變的例子代碼
< !doctype>
< Html>
< head>
< title>GradIEnt Example< /title>
< script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
//在一個矩形中嘗試做漸變
// 創建一個線性漸變
var fillColor = context.createLinearGradIEnt(50,50, 150,50);
// 設置漸變的顏色
fillColor.addColorStop(0.15,"red");
fillColor.addColorStop(0.35,"black");
fillColor.addColorStop(0.65,"green");
fillColor.addColorStop(0.87,"yellow");
// 把漸變對象賦值給fillstyle
context.fillStyle= fillColor;
// 繪制矩形
context.fillRect(50,50,100,100);
// 使用文本
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)
// 對角線上的漸變
var fillColordiagonal = context.createLinearGradIEnt(50,200, 100,450);
// 漸變顏色
fillColordiagonal.addColorStop(0.2,"red");
fillColordiagonal.addColorStop(0.4,"black");
fillColordiagonal.addColorStop(0.6,"green");
fillColordiagonal.addColorStop(0.75,"yellow");
// 把漸變對象賦值給fillstyle
context.fillStyle= fillColordiagonal;
// 繪制矩形
context.fillRect(50,225, 100,250);
// 繪制徑向漸變
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>
圖像剪裁
你可以通過裁剪出選定的區域來改變圖像。在畫布上裁剪是一項重載drawImage()方法的功能,drawImage()有三種選擇,你可以使用三個、五個或者是九個參數。
三個參數的配置——drawImage(image, dx, dy)——在目標坐標(dx,dy)上繪制圖形。坐標構成了圖像的左上角。
五個參數的配置——drawImage(image, dx, dy, dw, dh)——提供了目標的寬度和高度,圖像會被縮放以適應目標寬度和高度。
九個參數的配置——drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)——用到一個圖像,以圖像來源的(sx,sy)坐標為開始剪出一個寬度和高度為(sw,sh)的矩形區域,並把它縮放使之適應目標寬度和高度(dw,dh),然後把它放置在畫布的(dx,dy)位置上。
圖7顯示了你將要對其做剪裁的圖像。
圖7. 剪裁圖像
通過利用圖7中給出的圖像,可以把一組圖像放置在畫布上。一個圖像有畫布大小,被用作背景,另一個被創建的圖像較小一些,被插入到畫布的右下角上,第三個圖像是一個切出來的拿破侖的頭像,被放置在畫布的左上角上。裁剪後的圖像的最後情況如圖8所示。
圖8. 最終裁剪出來的圖像
圖8中的內容是使用清單6中的代碼創建出來的。在執行這一代碼之前,確保已下載了這一例子中用到的Napolean.png圖像。
清單6. 用來裁剪例子圖像的代碼
< !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() {
// 繪制圖像覆蓋整個畫布
context.drawImage(imageObj,0,0, 600, 400);
// 在右下角繪制一個小圖像
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);
//只繪制拿破侖的頭部
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>
動畫和多重畫布
要處理動畫方面的內容的話,分層問題總是不可避免的。分層允許組件被隔開開來,這使得編碼和調試變得更容易且更高效。Canvas API並未有分層的處理,但你可以創建多重的畫布。
動畫必須是隨著時間的推移來做控制的,因此,要創建一個動畫的話,你需要處理動畫的每一幀內容。Canvas API在動畫方面有一個主要的限制是:在某個形狀被放置到畫布上之後,它就一直保持它的樣子不變了,要移動該形狀的話,你必須要重新繪制它。
要創建一個動畫的話:
1. 清除掉之前在畫布上繪制的任何圖像。
2. 保存畫布的狀態,確保在每次繪制一個幀的時候都是使用最初的狀態。
3. 執行渲染幀的步驟。
4. 如果你已經保存了狀態的話,在繪制新的幀之前恢復該狀態。
你可以以兩種方式來控制動畫:使用setInterval或者setTimeout方法,每個方法都可以用來在超過某個設定時間段時調用一個函數。setInterval函數重復地執行所提供的代碼,setTimeout函數只在所提供的時間過去之後執行一次。
圖9展示了游泳者的多重畫布動畫的一幀,水畫在一幅畫布上,游泳的人則畫在另一幅畫布上。
圖9. 用到多重畫布的圖像的動畫
清單7中的代碼被用來創建游泳者,代碼使用一個線性漸變來創建水的效果。水有四種藍色色調,這提供了一種合理的水的假象。游泳者的動作通過使用positionX和positionY的值來創建,這兩個值改變圖像所擺放的樣子。游泳者的頭使用arc()方法來創建,游泳者的腿和雙臂則是通過繪制線段然後改變他們的lineTo()位置來創建,軀干則是通過修改moveTo()的位置來發生變化。因為這是一個動畫,因此你需要執行這一段代碼來看一下游泳者是如何運動的。
清單7. 動畫例子
< !DOCTYPE Html>
< Html>
< head>
< title>Animation & Multiple Canvas Example< /title>
< script>
// 水的畫布
function drawWater() {
var canvasWater = document.getElementById("myWaterCanvas");
var contextWater = canvasWater.getContext("2d");
contextWater.globalAlpha = .50 ;
// 創建一個線性漸變的填充
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);
}
// 游泳者的畫布
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();
// 繪制一個圓作為頭部
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;
// 軀干部分
contextSwimmer.beginPath();
contextSwimmer.moveTo(200,70+positionY);
contextSwimmer.lineTo(200,175);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// 畫右邊的手臂
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(175-positionX,140-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// 畫左邊的手臂
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(225+positionX,140-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// 畫右邊的腿
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 175);
contextSwimmer.lineTo(190-positionX,250-positionY);
contextSwimmer.lineWidth = 10;
contextSwimmer.strokeStyle = "#000000";
contextSwimmer.lineCap = "round";
contextSwimmer.stroke();
// 畫左邊的腿
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>
結論
Html5的畫布是基於浏覽器的RIA的結構核心,其提供了一種以JavaScript和你的想像力為驅動力的實用的繪圖環境。學習它真的不是很難,並且網絡上有許多培訓和學習所需的支持工具,其中包括了速查表、博客、在線文章、視頻和非視頻教程,以及示例應用程序等。
可視化地修改文本和圖像以及模擬運動的能力使得Canvas變成了一個極其有價值的工具,無論你是從設計者還是開發者的角度來熟悉它,無論你是使用Canvas來構建運行在移動設備上的游戲應用,還是僅僅想增強屏幕這一整體資源的利用情況,Canvas都是Html5體驗的重要組成部分。