九色国产,午夜在线视频,新黄色网址,九九色综合,天天做夜夜做久久做狠狠,天天躁夜夜躁狠狠躁2021a,久久不卡一区二区三区

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

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

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

發(fā)布時(shí)間:2012-02-27 作者:小想 來源:未知 我要評(píng)論

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

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

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

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

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

什么是Canvas?

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

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

Canvas的坐標(biāo)


在畫布上繪圖的一個(gè)先決條件是要熟悉網(wǎng)格或是坐標(biāo)空間,寬度和高度的空間區(qū)域測(cè)量是以像素為單位給出的。畫布是基于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給出了一個(gè)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元素自身有兩個(gè)屬性:width和height,除此之外,canvas還擁有所有主要的HTML5屬性,比如說class、id和name等。id屬性被用在上面所示的代碼中,JavaScript使用這里創(chuàng)建的canvas的id來表示要在上面繪畫的畫布。JavaScript使用document.getElementById()方法來確定正確的畫布,如下面代碼所示:

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

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

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

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

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


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

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

你會(huì)用到的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)明一個(gè)繪制過程要遵循的新起點(diǎn)。在繪制第一條線段時(shí),beginPath()方法的調(diào)用不是必須的。

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

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

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

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

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

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

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

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

通過執(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();

// 有著對(duì)接端點(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>

繪制矩形

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

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

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

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

圖3. 畫有矩形的畫布

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

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

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

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

要使用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)、一個(gè)控制點(diǎn)以及一個(gè)結(jié)束點(diǎn)來定義??刂泣c(diǎn)確定了線的曲度。

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

貝塞爾曲線

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

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

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

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

圖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()方法都會(huì)修改當(dāng)前的矩陣。translate(x, y)方法把畫布上的項(xiàng)目移動(dòng)到網(wǎng)格上的不同點(diǎn)上,在translate(x, y)方法中,(x,y)坐標(biāo)指明了圖像在x方向和y方向上應(yīng)該移動(dòng)的像素?cái)?shù)。

如果你使用drawImage()方法來在(15,25)這一位置繪制一個(gè)圖像的話,你可以使用(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)建一個(gè)在x方向加大50%,而在y方向只相當(dāng)于當(dāng)前尺寸75%的圖像。rotate(angle)方法返回一個(gè)基于指定角度的對(duì)象。

圖5是一個(gè)可以使用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);

// 順時(shí)針旋轉(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)沿著一條由兩個(gè)點(diǎn)(x0,y0)和(x1,y1)來標(biāo)識(shí)的直線產(chǎn)生一個(gè)漸變,這兩個(gè)點(diǎn)分別是漸變的起點(diǎn)和終點(diǎn)。該方法返回一個(gè)對(duì)象。

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

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

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

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

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

//在一個(gè)矩形中嘗試做漸變

// 創(chuàng)建一個(gè)線性漸變 
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");

// 把漸變對(duì)象賦值給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)

// 對(duì)角線上的漸變
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");

// 把漸變對(duì)象賦值給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()有三種選擇,你可以使用三個(gè)、五個(gè)或者是九個(gè)參數(shù)。

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

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

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

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

圖7. 剪裁圖像

通過利用圖7中給出的圖像,可以把一組圖像放置在畫布上。一個(gè)圖像有畫布大小,被用作背景,另一個(gè)被創(chuàng)建的圖像較小一些,被插入到畫布的右下角上,第三個(gè)圖像是一個(gè)切出來的拿破侖的頭像,被放置在畫布的左上角上。裁剪后的圖像的最后情況如圖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() {
// 繪制圖像覆蓋整個(gè)畫布
context.drawImage(imageObj,0,0, 600, 400);

// 在右下角繪制一個(gè)小圖像
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>

動(dòng)畫和多重畫布


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

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

要?jiǎng)?chuàng)建一個(gè)動(dòng)畫的話:

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

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

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

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

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

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

圖9. 用到多重畫布的圖像的動(dòng)畫

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

清單7. 動(dòng)畫例子

< !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)建一個(gè)線性漸變的填充
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();

// 繪制一個(gè)圓作為頭部
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ū)動(dòng)力的實(shí)用的繪圖環(huán)境。學(xué)習(xí)它真的不是很難,并且網(wǎng)絡(luò)上有許多培訓(xùn)和學(xué)習(xí)所需的支持工具,其中包括了速查表、博客、在線文章、視頻和非視頻教程,以及示例應(yīng)用程序等。

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

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
HTML5常用的標(biāo)簽
canvas
基于Canvas的熱力圖繪制方法
HTML5
HTML5 canvas drawImage() 方法 縮放
網(wǎng)頁(yè)|HTML5 也可以畫一畫(canvas)
更多類似文章 >>
生活服務(wù)
熱點(diǎn)新聞
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服