pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

HTML5基礎(chǔ),第4部分:點(diǎn)睛之筆Canvas

(譯者注:由于yeeyan編輯器對文章中的標(biāo)簽做解析的原因,我在每個標(biāo)簽的<符號之后都加入了一個空格,比如說,左尖括號<+head+右尖括號>,我會寫成< head>,以便其能夠在文章中正確顯示,不便之處敬請諒解。)

使用HTML5來編寫代碼的人,有著設(shè)計(jì)者和開發(fā)者雙重身份的強(qiáng)悍組合,其職責(zé)是構(gòu)造出高效的富互聯(lián)網(wǎng)應(yīng)用(rich Internet application,RIA),特別是豐富的用戶界面。就高效這個字眼來說,我的意思是指系統(tǒng)級的和系統(tǒng)性的創(chuàng)造力增強(qiáng),這種增強(qiáng)以數(shù)字化的方式促進(jìn)了站點(diǎn)所有者、所有者的代理機(jī)構(gòu)和站點(diǎn)用戶之間的對話。

RIA是用戶獲得滿意體驗(yàn)的來源之處和媒介,因此,它是任何成功的以網(wǎng)絡(luò)為中心的風(fēng)險投資的重要組成部分。以網(wǎng)絡(luò)為中心的活動,就性質(zhì)來說,或多或少都是協(xié)作式的。公司要在包括了市場營銷和管理的各個層面都取得成功的話,數(shù)字化協(xié)作的制勝方法是至關(guān)重要的。很多時候的很多情況都取決于效率,網(wǎng)站要依靠效率來滿足其訪問者的品質(zhì)期望。

正如你已經(jīng)見到的那樣,HTML5是為這一具有跨平臺能力、融合了通信、使用統(tǒng)一語言、提供無處不在的計(jì)算,以及基于開放系統(tǒng)的協(xié)作式“一網(wǎng)化世界(one web world)”量身定做的。這一文章系列的前面三部分內(nèi)容重點(diǎn)關(guān)注語義、正確的編碼方法、輸入在極為重要的轉(zhuǎn)化過程中的作用,以及站點(diǎn)管理最佳做法等,所有這些的目的都是在為以一種有組織和符合邏輯的方式來創(chuàng)建RIA奠定基礎(chǔ)。每篇文章中都共有的一個主題是,對于實(shí)現(xiàn)網(wǎng)站所有者的機(jī)構(gòu)目標(biāo)來說,制造并管理豐富的用戶體驗(yàn)是至關(guān)重要的。

什么是Canvas?

HTML5 Canvas(畫布)是一個非常有用的繪圖和動畫元素,Canvas使用JavaScript來直接在頁面上繪制圖形。這是一個由你來定義和控制的長方形區(qū)域,該區(qū)域允許動態(tài)、可腳本渲染的2D圖形和位圖圖像。

在制作用來增強(qiáng)UI、示意圖、相冊、圖表、圖形、動畫和嵌入式繪圖應(yīng)用的那些非常棒的視覺材料方面,HTML5堪稱完美。Canvas元素有一些用來繪制路徑、矩形、圓形和字符的方法。

Canvas的坐標(biāo)


在畫布上繪圖的一個先決條件是要熟悉網(wǎng)格或是坐標(biāo)空間,寬度和高度的空間區(qū)域測量是以像素為單位給出的。畫布是基于x和y坐標(biāo)的使用來構(gòu)建的,畫布的x=0, y=0坐標(biāo)位于左上角。

畫布的矩形區(qū)域的默認(rèn)屬性是300像素的寬度和150像素的高度,但你可以通過指定寬度和高度來確定畫布元素的確切大小。圖1中的示意圖說明了x和y坐標(biāo)的實(shí)現(xiàn)方式。

圖1. Canvas的坐標(biāo)

圖1給出了一個100像素X100像素的畫布區(qū):

1. 左上角是x=0,y=0。

2. x的值水平增加,y的值垂直增加。

3. 右下角是x=100,y=100。

4. 中間的點(diǎn)是x=50,y=50。

開始第一步


要在畫布上放置任何東西的話,你首先必須在HTML文件中定義畫布。你必須創(chuàng)建訪問< canvas>標(biāo)簽的JavaScript代碼,并通過與HTML5 Canvas API通信來繪制你的圖像。

< canvas>標(biāo)簽的基本結(jié)構(gòu)如下:

< canvas id="myCanvas" width="200" height="200">< /canvas>

canvas元素自身有兩個屬性:width和height,除此之外,canvas還擁有所有主要的HTML5屬性,比如說class、id和name等。id屬性被用在上面所示的代碼中,JavaScript使用這里創(chuàng)建的canvas的id來表示要在上面繪畫的畫布。JavaScript使用document.getElementById()方法來確定正確的畫布,如下面代碼所示:

var canvas = document.getElementById("myCanvas");

每個畫布都必須要有一個context(上下文)的定義,如下面代碼所示。就目前的情況來說,官方規(guī)范只承認(rèn)一個2D環(huán)境:

var context = canvas.getContext("2d");

在標(biāo)識畫布并指明了它的上下文之后,你就做好了開始繪畫的準(zhǔn)備了。

繪圖工具、效果和轉(zhuǎn)換


在HTML5 Canvas的這一討論過程中,我們對各種繪圖工具、效果和轉(zhuǎn)換都查看一番。繪圖工具包括:

1. 線條
2. 矩形
3. 圓弧
4. 貝塞爾曲線和二次曲線
5. 圓和半圓

你會用到的Canvas效果包括:

1. 填充和描邊
2. 線性和徑向的漸變

要討論的轉(zhuǎn)換包括:

1. 縮放
2. 旋轉(zhuǎn)
3. 平移

繪制線段

要在畫布上繪制線段的話,你可以使用moveTo()、lineTo()和stroke()方法,此外,你要使用beginPath()方法來重置當(dāng)前路徑:

1. context.beginPath();
2. Context.moveTo(x,y);
3. Context.lineTo(x,y);
4. Context.stroke(x,y);

beginPath()方法開始一條新的路徑,在使用不同的子路徑繪制一條新的線段之前,你必須要使用beginPath()來標(biāo)明一個繪制過程要遵循的新起點(diǎn)。在繪制第一條線段時,beginPath()方法的調(diào)用不是必須的。

moveTo()方法指明新的子路徑從哪里開始,lineTo()方法創(chuàng)建子路徑。你可以使用lineWidth和strokeStyle來改變線段的外觀,lineWidth元素改變線段的粗細(xì),strokeStyle改變顏色。

在圖2中,三條線段分別用藍(lán)色、綠色和紫色畫了出來。

圖2. 畫有三條不同顏色的線段的畫布

圖2中的線段由清單1中的代碼來創(chuàng)建,藍(lán)色的線段有著圓弧形的端點(diǎn),該線段是由首個context.beginPath()這一開始新路徑的建立的方法來創(chuàng)建的,其后緊跟著:

1. context.moveTo(50, 50),該方法把線路的起點(diǎn)置于(x=50, y=50)
2. context.lineTo(300,50),該方法標(biāo)識線段的終點(diǎn)
3. context.lineWidth = 10,該屬性是線段的寬度
4. context.strokeStyle = "#0000FF",該屬性是線段的顏色 
5. context.lineCap = "round",該屬性把端點(diǎn)設(shè)成是圓弧狀的
6. context.stroke(),該方法真正在畫布上繪制該線段

所有線段的長度都是50像素,盡管它們看上去不一樣長——這是由線段的線帽(line cap)造成的視覺錯覺。可用的線帽有三種:

1. Context.round (blue)
2. Context.square (green)
3. Context.butt (purple)——默認(rèn)值

對接(butt)線帽是默認(rèn)值,當(dāng)你使用圓形(round)或是方形(square)的線帽風(fēng)格時,線段的長度會增加,加上一段相當(dāng)于線段寬度的長度。例如,一個長度為200像素,寬度為10像素,有著圓形或是方形線帽風(fēng)格的線段,其最終的線段長度是210像素,因?yàn)槊總€線帽都都往線段的每一端加上了5個像素的長度。而一個長度為200像素,寬度為20像素,有著圓形或是方形的線帽風(fēng)格的線段的最終長度是220像素,因?yàn)槊總€線帽都往線段每一端加上了10像素的長度。

通過執(zhí)行和修改清單1中的代碼來更好地理解線段的繪制方式。

清單1. 在畫布上創(chuàng)建三條不同顏色的線段

< !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");

// 有著圓形端點(diǎn)的藍(lán)色線段
context.beginPath();
context.moveTo(50, 50);
context.lineTo(300,50);
context.lineWidth = 10;
context.strokeStyle = "#0000FF"; 
context.lineCap = "round";
context.stroke();

// 有著方形端點(diǎn)的綠色線段
context.beginPath();
context.moveTo(50, 100);
context.lineTo(300,100);
context.lineWidth = 20;
context.strokeStyle = "#00FF00"; 
context.lineCap = "square";
context.stroke();

// 有著對接端點(diǎn)的紫色線段
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>

繪制矩形

有三個方法可用來在畫布上給出一個矩形的區(qū)域:

1. fillRect(x,y,width,height),該方法繪制一個有填充的矩形
2. strokeRect(x,y,width,height),該方法繪制一個矩形的外邊框
3. clearRect(x,y,width,height),該方法清空指定的區(qū)域,使之變得完全透明

對于這三個方法中的每個來說,x和y表示的都是畫布上相對于矩形(x=0, y=0)的左上角的位置,width和height分別是矩形的寬度和高度。

圖3顯示了由清單2中的代碼創(chuàng)建的三個矩形。

圖3. 畫有矩形的畫布

fillRect()方法創(chuàng)建了一個以缺省的黑色為填充色的矩形;clearRect()方法在第一個矩形的中心部分清除出一個矩形區(qū)域,該區(qū)域位于由fillRect()方法產(chǎn)生的矩形的中央位置;strokeRect創(chuàng)建了一個只有可見的黑色邊框的矩形。

清單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()方法用到了六個參數(shù):

context.arc(centerX, centerY, radius, startingAngle, endingAngle, antiClockwise);

centerX和centerY參數(shù)是圓的中心坐標(biāo),radius就是數(shù)學(xué)上的半徑:從圓心到圓周線的一條直線。弧形是作為所定義的圓的一部分來創(chuàng)建的,startAngle和endAngle參數(shù)分別是圓弧的起點(diǎn)和終點(diǎn),以弧度為單位。anticlockwise參數(shù)是一個布爾(Boolean)值,當(dāng)其值為true時,弧形按逆時針方向來繪制,當(dāng)其值為false時,弧形按順時針方向來繪制。

要使用arc()方法來繪制圓的話,把起始角度定義成0,把結(jié)束角度定義成2*PI,如下所示:

context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);

要使用arc()方法來繪制半圓的話,把結(jié)束角度定義成startingAngle + PI,如下所示:

context.arc(centerX, centerY, radius, startingAngle, startingAngle + Math.PI, false);

二次曲線

quadraticCurveTo()方法被用來創(chuàng)建一條二次曲線,如下所示。二次曲線通過上下文中的點(diǎn)、一個控制點(diǎn)以及一個結(jié)束點(diǎn)來定義。控制點(diǎn)確定了線的曲度。

context.moveTo(x, y);
context.quadraticCurveTo(controlX, controlY, endX, endY);

貝塞爾曲線

正和二次曲線一樣,貝塞爾曲線也有一個起點(diǎn)和一個終點(diǎn),但和二次曲線不同的是,它有兩個控制點(diǎn):

context.moveTo(x, y);
context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);

你可使用bezierCurveTo()方法來創(chuàng)建貝塞爾曲線,因?yàn)樨惾麪柷€是由兩個控制點(diǎn)而不僅是由一個控制點(diǎn)來定義的,所有你可以創(chuàng)造出更加復(fù)雜的曲度來。

圖4的顯示——從左到右——為一條圓弧、一條二次曲線、一條貝塞爾曲線、一個半圓和一個圓。

圖4. 圓弧、曲線和圓

圖4的內(nèi)容是用清單3中的代碼來創(chuàng)建的。

清單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>

轉(zhuǎn)換:平移、縮放和旋轉(zhuǎn)

translate()、scale()和rotate()方法都會修改當(dāng)前的矩陣。translate(x, y)方法把畫布上的項(xiàng)目移動到網(wǎng)格上的不同點(diǎn)上,在translate(x, y)方法中,(x,y)坐標(biāo)指明了圖像在x方向和y方向上應(yīng)該移動的像素數(shù)。

如果你使用drawImage()方法來在(15,25)這一位置繪制一個圖像的話,你可以使用(20,30)作為參數(shù)的來調(diào)用translate(),該調(diào)用把圖像放在(15+20, 25+30) = (35, 55)這一位置上。

scale(x,y)方法改變圖像的大小,x參數(shù)指明水平方向的比例系數(shù),y參數(shù)指明垂直方向的比例系數(shù)。例如,scale(1.5, .75)將創(chuàng)建一個在x方向加大50%,而在y方向只相當(dāng)于當(dāng)前尺寸75%的圖像。rotate(angle)方法返回一個基于指定角度的對象。

圖5是一個可以使用translate()、scale()和rotate()進(jìn)行渲染的圖像例子。

圖5. 使用轉(zhuǎn)換

清單4提供的代碼創(chuàng)建了圖5中的圖像。

清單4. 創(chuàng)建轉(zhuǎn)換的代碼

< !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);

// 順時針旋轉(zhuǎn)45度
context.rotate(-Math.PI/4); 

context.fillStyle="blue";
context.fillRect(-rectWidth/2,-rectHeight/2,
rectWidth,rectHeight);

// 水平方向翻轉(zhuǎn)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中你可以創(chuàng)建兩種類型的漸變:線性的和徑向的。

createLinearGradient()方法被用來創(chuàng)建線性的漸變。createLinearGradient(x0,y0,x1,y1)沿著一條由兩個點(diǎn)(x0,y0)和(x1,y1)來標(biāo)識的直線產(chǎn)生一個漸變,這兩個點(diǎn)分別是漸變的起點(diǎn)和終點(diǎn)。該方法返回一個對象。

顏色的漸變可以有多種顏色,addcolorStop(offset, color) 方法為被標(biāo)明為在給定的偏移量上漸變的顏色指明了顏色過渡點(diǎn)。addColorStop()方法讓你在0和1之間指定一個偏移量,以這一偏移量為依據(jù)來開始過渡到下一種顏色。值0是漸變的一端的偏移量,1是另一端的偏移量。在顏色的漸變定義好了之后,漸變對象就可以被賦值給fillStyle()。你也可以使用fillText()方法來繪制出帶有漸變的文字來。

徑向漸變——createradialGradient(x0,y0,r0,x1,y1,r1)——使用六個參數(shù)以一種圓形或是圓錐形的模式來組合兩種或多種顏色。

1. (x0,y0): 圓錐的第一個圓的中心
2. r0:第一個圓的半徑 
3. (x1,y1):圓錐的第二個圓的中心
4. r1:第二個圓的半徑

圖6包含了四種漸變:一個線性漸變、一個文本漸變、一個對角線上的漸變和一個徑向漸變。

圖6. 漸變的例子

圖6的內(nèi)容是使用清單5中的代碼創(chuàng)建出來的。

清單5. 漸變的例子代碼

< !doctype>
< html>
< head>
< title>Gradient Example< /title>
< script>
window.onload = function() {
var canvas = document.getElementById("myCanvas");

var context = canvas.getContext("2d");

//在一個矩形中嘗試做漸變

// 創(chuàng)建一個線性漸變 
var fillColor = context.createLinearGradient(50,50, 150,50);

// 設(shè)置漸變的顏色
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>

圖像剪裁


你可以通過裁剪出選定的區(qū)域來改變圖像。在畫布上裁剪是一項(xiàng)重載drawImage()方法的功能,drawImage()有三種選擇,你可以使用三個、五個或者是九個參數(shù)。

三個參數(shù)的配置——drawImage(image, dx, dy)——在目標(biāo)坐標(biāo)(dx,dy)上繪制圖形。坐標(biāo)構(gòu)成了圖像的左上角。

五個參數(shù)的配置——drawImage(image, dx, dy, dw, dh)——提供了目標(biāo)的寬度和高度,圖像會被縮放以適應(yīng)目標(biāo)寬度和高度。

九個參數(shù)的配置——drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)——用到一個圖像,以圖像來源的(sx,sy)坐標(biāo)為開始剪出一個寬度和高度為(sw,sh)的矩形區(qū)域,并把它縮放使之適應(yīng)目標(biāo)寬度和高度(dw,dh),然后把它放置在畫布的(dx,dy)位置上。

圖7顯示了你將要對其做剪裁的圖像。

圖7. 剪裁圖像

通過利用圖7中給出的圖像,可以把一組圖像放置在畫布上。一個圖像有畫布大小,被用作背景,另一個被創(chuàng)建的圖像較小一些,被插入到畫布的右下角上,第三個圖像是一個切出來的拿破侖的頭像,被放置在畫布的左上角上。裁剪后的圖像的最后情況如圖8所示。

圖8. 最終裁剪出來的圖像

圖8中的內(nèi)容是使用清單6中的代碼創(chuàng)建出來的。在執(zhí)行這一代碼之前,確保已下載了這一例子中用到的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>

動畫和多重畫布


要處理動畫方面的內(nèi)容的話,分層問題總是不可避免的。分層允許組件被隔開開來,這使得編碼和調(diào)試變得更容易且更高效。Canvas API并未有分層的處理,但你可以創(chuàng)建多重的畫布。

動畫必須是隨著時間的推移來做控制的,因此,要創(chuàng)建一個動畫的話,你需要處理動畫的每一幀內(nèi)容。Canvas API在動畫方面有一個主要的限制是:在某個形狀被放置到畫布上之后,它就一直保持它的樣子不變了,要移動該形狀的話,你必須要重新繪制它。

要創(chuàng)建一個動畫的話:

1. 清除掉之前在畫布上繪制的任何圖像。

2. 保存畫布的狀態(tài),確保在每次繪制一個幀的時候都是使用最初的狀態(tài)。

3. 執(zhí)行渲染幀的步驟。

4. 如果你已經(jīng)保存了狀態(tài)的話,在繪制新的幀之前恢復(fù)該狀態(tài)。

你可以以兩種方式來控制動畫:使用setInterval或者setTimeout方法,每個方法都可以用來在超過某個設(shè)定時間段時調(diào)用一個函數(shù)。setInterval函數(shù)重復(fù)地執(zhí)行所提供的代碼,setTimeout函數(shù)只在所提供的時間過去之后執(zhí)行一次。

圖9展示了游泳者的多重畫布動畫的一幀,水畫在一幅畫布上,游泳的人則畫在另一幅畫布上。

圖9. 用到多重畫布的圖像的動畫

清單7中的代碼被用來創(chuàng)建游泳者,代碼使用一個線性漸變來創(chuàng)建水的效果。水有四種藍(lán)色色調(diào),這提供了一種合理的水的假象。游泳者的動作通過使用positionX和positionY的值來創(chuàng)建,這兩個值改變圖像所擺放的樣子。游泳者的頭使用arc()方法來創(chuàng)建,游泳者的腿和雙臂則是通過繪制線段然后改變他們的lineTo()位置來創(chuàng)建,軀干則是通過修改moveTo()的位置來發(fā)生變化。因?yàn)檫@是一個動畫,因此你需要執(zhí)行這一段代碼來看一下游泳者是如何運(yùn)動的。

清單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 ;

// 創(chuàng)建一個線性漸變的填充
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>

結(jié)論


HTML5的畫布是基于瀏覽器的RIA的結(jié)構(gòu)核心,其提供了一種以JavaScript和你的想像力為驅(qū)動力的實(shí)用的繪圖環(huán)境。學(xué)習(xí)它真的不是很難,并且網(wǎng)絡(luò)上有許多培訓(xùn)和學(xué)習(xí)所需的支持工具,其中包括了速查表、博客、在線文章、視頻和非視頻教程,以及示例應(yīng)用程序等。

可視化地修改文本和圖像以及模擬運(yùn)動的能力使得Canvas變成了一個極其有價值的工具,無論你是從設(shè)計(jì)者還是開發(fā)者的角度來熟悉它,無論你是使用Canvas來構(gòu)建運(yùn)行在移動設(shè)備上的游戲應(yīng)用,還是僅僅想增強(qiáng)屏幕這一整體資源的利用情況,Canvas都是HTML5體驗(yàn)的重要組成部分。

【網(wǎng)站聲明】本站除付費(fèi)源碼經(jīng)過測試外,其他素材未做測試,不保證完整性,網(wǎng)站上部分源碼僅限學(xué)習(xí)交流,請勿用于商業(yè)用途。如損害你的權(quán)益請聯(lián)系客服QQ:2655101040 給予處理,謝謝支持。

相關(guān)文檔推薦

這篇文章主要介紹了有關(guān)HTML5頁面在iPhoneX適配問題,需要的朋友可以參考下
本篇文章主要介紹了html5中canvas圖表實(shí)現(xiàn)柱狀圖的示例,本文使用canvas來實(shí)現(xiàn)一個圖表,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
Adobe公司出品的多媒體處理軟件產(chǎn)品線較多,涵蓋了音視頻編輯、圖像處理、平面設(shè)計(jì)、影視后期等領(lǐng)域。這篇文章主要介紹了Adobe Html5 Extension開發(fā)初體驗(yàn)圖文教程,非常不錯,需要的朋
這篇文章主要介紹了基于HTML5的WebGL經(jīng)典3D虛擬機(jī)房漫游動畫,需要的朋友可以參考下
這篇文章主要介紹了手機(jī)端用rem+scss做適配的詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
本篇文章主要介紹了canvas 實(shí)現(xiàn) github404動態(tài)效果的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
主站蜘蛛池模板: 电动垃圾车,垃圾清运车-江苏速利达机车有限公司 | 电动垃圾车,垃圾清运车-江苏速利达机车有限公司 | 订做不锈钢_不锈钢定做加工厂_不锈钢非标定制-重庆侨峰金属加工厂 | 合肥触摸一体机_触摸查询机厂家_合肥拼接屏-安徽迅博智能科技 | 外贮压-柜式-悬挂式-七氟丙烷-灭火器-灭火系统-药剂-价格-厂家-IG541-混合气体-贮压-非贮压-超细干粉-自动-灭火装置-气体灭火设备-探火管灭火厂家-东莞汇建消防科技有限公司 | 智成电子深圳tdk一级代理-提供TDK电容电感贴片蜂鸣器磁芯lambda电源代理经销,TDK代理商有哪些TDK一级代理商排名查询。-深圳tdk一级代理 | 车牌识别道闸_停车场收费系统_人脸识别考勤机_速通门闸机_充电桩厂家_中全清茂官网 | 许昌奥仕达自动化设备有限公司 | 网站seo优化_seo云优化_搜索引擎seo_启新网络服务中心 | pos机办理,智能/扫码/二维码/微信支付宝pos机-北京万汇通宝商贸有限公司 | 美能达分光测色仪_爱色丽分光测色仪-苏州方特电子科技有限公司 | 12cr1mov无缝钢管切割-15crmog无缝钢管切割-40cr无缝钢管切割-42crmo无缝钢管切割-Q345B无缝钢管切割-45#无缝钢管切割 - 聊城宽达钢管有限公司 | 玻璃钢板-玻璃钢防腐瓦-玻璃钢材料-广东壹诺 | 小型单室真空包装机,食品单室真空包装机-百科 | 低压载波电能表-单相导轨式电能表-华邦电力科技股份有限公司-智能物联网综合管理平台 | 证券新闻,热播美式保罗1984第二部_腾讯1080p-仁爱影院 | 27PR跨境电商导航 | 专注外贸跨境电商 | 进口便携式天平,外校_十万分之一分析天平,奥豪斯工业台秤,V2000防水秤-重庆珂偌德科技有限公司(www.crdkj.com) | 上海皓越真空设备有限公司官网-真空炉-真空热压烧结炉-sps放电等离子烧结炉 | 不锈钢监控杆_监控立杆厂家-廊坊耀星光电科技有限公司 | 手持气象站_便携式气象站_农业气象站_负氧离子监测站-山东万象环境 | 脱硫搅拌器厂家-淄博友胜不锈钢搅拌器厂家 | 上海橡胶接头_弹簧减震器_金属软接头厂家-上海淞江集团 | 定硫仪,量热仪,工业分析仪,马弗炉,煤炭化验设备厂家,煤质化验仪器,焦炭化验设备鹤壁大德煤质工业分析仪,氟氯测定仪 | 高压负荷开关-苏州雷尔沃电器有限公司 | 奇酷教育-Python培训|UI培训|WEB大前端培训|Unity3D培训|HTML5培训|人工智能培训|JAVA开发的教育品牌 | 岩棉切条机厂家_玻璃棉裁条机_水泥基保温板设备-廊坊鹏恒机械 | 软瓷_柔性面砖_软瓷砖_柔性石材_MCM软瓷厂家_湖北博悦佳软瓷 | 南京技嘉环保科技有限公司-杀菌除臭剂|污水|垃圾|厕所|橡胶厂|化工厂|铸造厂除臭剂 | 没斑啦-专业的祛斑美白嫩肤知识网站-去斑经验分享 | 涡轮流量计_LWGY智能气体液体电池供电计量表-金湖凯铭仪表有限公司 | 智能监控-安防监控-监控系统安装-弱电工程公司_成都万全电子 | 临朐空调移机_空调维修「空调回收」临朐二手空调 | 网站建设,北京网站建设,北京网站建设公司,网站系统开发,北京网站制作公司,响应式网站,做网站公司,海淀做网站,朝阳做网站,昌平做网站,建站公司 | 紫外可见光分光度计-紫外分光度计-分光光度仪-屹谱仪器制造(上海)有限公司 | 道康宁消泡剂-瓦克-大川进口消泡剂供应商 | 纯化水设备-纯水设备-超纯水设备-[大鹏水处理]纯水设备一站式服务商-东莞市大鹏水处理科技有限公司 | 高压微雾加湿器_工业加湿器_温室喷雾-昌润空气净化设备 | 航空障碍灯_高中低光强航空障碍灯_民航许可认证航空警示灯厂家-东莞市天翔航天科技有限公司 | 数码听觉统合训练系统-儿童感觉-早期言语评估与训练系统-北京鑫泰盛世科技发展有限公司 | 压砖机、液压制砖机、静压砖机、环保砖机生产厂家—杜甫机械 |