## Canvas
**二、canvas**
HTML5`<canvas>`元素用于圖形的繪制,通過(guò)腳本 (通常是JavaScript)來(lái)完成。
`<canvas> `標(biāo)簽只是圖形容器,您必須使用腳本來(lái)繪制圖形。
要使用Canvas API,首先需要新建一個(gè)`<canvas>`網(wǎng)頁(yè)元素
```
<canvas id="canvas" width="400" height="200">
您的瀏覽器不支持canvas!
</canvas>
```
width 和 height 屬性定義的畫布的大小。
接著,我們可以通過(guò)標(biāo)簽選擇獲取到<canvas>元素:
```
var canvas = document.getElementById('canvas');
```
然后,創(chuàng)建context對(duì)象:
```
if(canvas.getContext){
var ctx = canvas.getContext('2d');
}
```
調(diào)用getContext()方法時(shí),傳遞一個(gè)“2d”參數(shù),會(huì)獲得一個(gè)CanvasRenderingContext2D對(duì)象,使用該對(duì)象可以在畫布上繪制二維圖形。我們也可將CanvasRenderingContext2D簡(jiǎn)稱為“上下文對(duì)象”。
**2.1 canvas的繪圖用法**
canvas畫布提供了一個(gè)用來(lái)作圖的平面空間,該空間的每個(gè)點(diǎn)都有自己的坐標(biāo),x表示橫坐標(biāo),y表示豎坐標(biāo)。原點(diǎn)(0, 0)位于圖像左上角,x軸的正向是原點(diǎn)向右,y軸的正向是原點(diǎn)向下。
**(1)繪制矩形**
- rect(x,y,width,height)方法用來(lái)繪制矩形。
- fillRect(x, y, width, height)方法用來(lái)繪制矩形,它的四個(gè)參數(shù)分別為矩形左上角頂點(diǎn)的x坐標(biāo)、y坐標(biāo),以及矩形的寬和高。fillStyle屬性用來(lái)設(shè)置矩形的填充色。
- strokeRect(x, y, width, height)方法同樣是繪制矩形,但只畫線不填充,也可以說(shuō)是畫空心矩形。strokeStyle屬性用來(lái)設(shè)置矩形的繪制色。
- clearRect(x, y, width, height)方法用來(lái)清除某個(gè)矩形區(qū)域的內(nèi)容。
**(2)繪制圓形和扇形**
- arc(x, y, radius, startAngle, endAngle, anticlockwise)方法用來(lái)繪制圓形和扇形。
arc方法的x和y參數(shù)是圓心坐標(biāo),radius是半徑,startAngle和endAngle則是扇形的起始角度和終止角度(以弧度表示),anticlockwise表示做圖時(shí)應(yīng)該逆時(shí)針畫(true)還是順時(shí)針畫(false)。
- arcTo(x1,y1,x2,y2,r)方法在畫布上創(chuàng)建介于兩個(gè)切線之間的弧/曲線。
參數(shù):x1 弧的起點(diǎn)的 x 坐標(biāo),y1 弧的起點(diǎn)的 y 坐標(biāo),x2 弧的終點(diǎn)的 x 坐標(biāo),y2 弧的終點(diǎn)的 y 坐標(biāo),r 弧的半徑。
**(3)繪制文本**
- fillText(string, x, y) 用來(lái)繪制文本,它的三個(gè)參數(shù)分別為文本內(nèi)容、起點(diǎn)的x坐標(biāo)、y坐標(biāo)。使用之前,需用font設(shè)置字體、大小、樣式(寫法類似與CSS的font屬性)。
strokeText(string,x,y)方法,用來(lái)添加空心字。
```
// 設(shè)置字體
ctx.font = "Bold 20px Arial";
// 設(shè)置對(duì)齊方式,start、end、right、center
ctx.textAlign = "left";
// 設(shè)置填充顏色
ctx.fillStyle = "#008600";
//設(shè)置垂直對(duì)齊方式,top、hanging、middle、alphabetic、ideographic、bottom
ctx.textBaseline = top;
```
我們還可以計(jì)算字體寬度(px):
```
var name = 'aaa';
ctx.measureText(name);
```
measureText() 方法返回包含一個(gè)對(duì)象,該對(duì)象包含以像素計(jì)的指定字體寬度。
```
ctx.measureText(name).width
```
**(4)繪制路徑**
`beginPath()`方法表示開(kāi)始繪制路徑,`moveTo(x, y)`方法設(shè)置線段的起點(diǎn),`lineTo(x, y)`方法設(shè)置線段的終點(diǎn),`stroke()`方法用來(lái)給透明的線段著色。
```
ctx.beginPath(); // 開(kāi)始路徑繪制
ctx.moveTo(20, 20); // 設(shè)置路徑起點(diǎn),坐標(biāo)為(20,20)
ctx.lineTo(200, 20); // 繪制一條到(200,20)的直線
ctx.lineWidth = 1.0; // 設(shè)置線寬
ctx.strokeStyle = '#CC0000'; // 設(shè)置線的顏色
ctx.stroke(); // 進(jìn)行線的著色,這時(shí)整條線才變得可見(jiàn)
moveTo()和lineTo()方法可以多次使用。
```
注意:如果使用closePath()方法,會(huì)自動(dòng)繪制一條當(dāng)前點(diǎn)到起點(diǎn)的直線,形成一個(gè)封閉圖形。
fill()和stroke()分別填充當(dāng)前繪圖(路徑)和繪制已定義的路徑。
**isPointInPath()**
```
isPointInPath(x,y);
```
如果指定的點(diǎn)位于當(dāng)前路徑中,isPointInPath() 方法返回 true,否則返回 false。
**clip()**
clip()方法從原始畫布中剪切任意形狀和尺寸。
注意:一旦剪切了某個(gè)區(qū)域,則所有之后的繪圖都會(huì)被限制在被剪切的區(qū)域內(nèi)(不能訪問(wèn)畫布上的其他區(qū)域)。您也可以在使用 clip() 方法前通過(guò)使用 save() 方法對(duì)當(dāng)前畫布區(qū)域進(jìn)行保存,并在以后的任意時(shí)間對(duì)其進(jìn)行恢復(fù)(通過(guò) restore() 方法)。
closePath()方法創(chuàng)建當(dāng)前點(diǎn)回到起始點(diǎn)的路徑。
**其他樣式屬性:**
- lineCap 設(shè)置或返回線條的結(jié)束端點(diǎn)樣式,可能值: butt|round|square(平直邊緣|圓形線帽|正方形線帽)
- lineJoin 設(shè)置或返回兩條線相交時(shí),所創(chuàng)建的拐角類型,可能值:bevel|round|miter(斜角|圓角|尖角(默認(rèn)值))
- lineWidth 設(shè)置或返回當(dāng)前的線條寬度。
- miterLimit 正數(shù),設(shè)置或返回最大斜接長(zhǎng)度。如果斜接長(zhǎng)度超過(guò) miterLimit 的值,邊角會(huì)以 lineJoin 的 "bevel" 類型來(lái)顯示。
- fillStyle 設(shè)置填充色
- strokeStyle 設(shè)置繪制線色
顏色格式:
```
//可直接用顏色名稱
'red' 'green'
//十六進(jìn)制顏色
'#d9d9d9'
//rgb
rgb(0,0,0)
//rgba
rgba(0,0,0,1)
```
**(5)設(shè)置漸變色**
**線性漸變**
createLinearGradient方法用來(lái)設(shè)置漸變色。
```
var gradient = ctx.createLinearGradient(0, 0, 0, 160);
gradient.addColorStop(0, "#BABABA");
gradient.addColorStop(1, "#636363");
```
createLinearGradient()方法的參數(shù)是(x1, y1, x2, y2),其中x1和y1是起點(diǎn)坐標(biāo),x2和y2是終點(diǎn)坐標(biāo)。通過(guò)不同的坐標(biāo)值,可以生成從上至下、從左到右的漸變等等。
使用方法:
```
ctx.fillStyle = myGradient;
ctx.fillRect(10,10,200,100);
```
**環(huán)形漸變**
createRadialGradient()方法的參數(shù)是(x0,y0,r0,x1,y1,r1),其中x0 漸變的開(kāi)始圓的 x 坐標(biāo),y0 漸變的開(kāi)始圓的 y 坐標(biāo),r0 開(kāi)始圓的半徑,x1 漸變的結(jié)束圓的 x 坐標(biāo),y1 漸變的結(jié)束圓的 y 坐標(biāo),r1 結(jié)束圓的半徑。
```
var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,100);
```
**(6)設(shè)置陰影**
我們還可以設(shè)置陰影
```
ctx.shadowOffsetX = 10; // 設(shè)置水平位移
ctx.shadowOffsetY = 10; // 設(shè)置垂直位移
ctx.shadowBlur = 5; // 設(shè)置模糊度
ctx.shadowColor = "rgba(0,0,0,0.5)"; // 設(shè)置陰影顏色
ctx.fillStyle = "#CC0000";
ctx.fillRect(10,10,200,100);
```
**(7)合成**
`globalAlpha` 屬性設(shè)置或返回繪圖的當(dāng)前透明值(alpha 或 transparency)。
`globalAlpha` 屬性值必須是介于 0.0(完全透明) 與 1.0(不透明) 之間的數(shù)字。
ctx.globalAlpha = number
`globalCompositeOperation`屬性設(shè)置或返回如何將一個(gè)源(新的)圖像繪制到目標(biāo)(已有的)的圖像上。
源圖像 = 您打算放置到畫布上的繪圖。
目標(biāo)圖像 = 您已經(jīng)放置在畫布上的繪圖。
```
source-over 默認(rèn)。在目標(biāo)圖像上顯示源圖像。
source-atop 在目標(biāo)圖像頂部顯示源圖像。源圖像位于目標(biāo)圖像之外的部分是不可見(jiàn)的。
source-in 在目標(biāo)圖像中顯示源圖像。只有目標(biāo)圖像之內(nèi)的源圖像部分會(huì)顯示,目標(biāo)圖像是透明的。
source-out 在目標(biāo)圖像之外顯示源圖像。只有目標(biāo)圖像之外的源圖像部分會(huì)顯示,目標(biāo)圖像是透明的。
destination-over 在源圖像上顯示目標(biāo)圖像。
destination-atop 在源圖像頂部顯示目標(biāo)圖像。目標(biāo)圖像位于源圖像之外的部分是不可見(jiàn)的。
destination-in 在源圖像中顯示目標(biāo)圖像。只有源圖像之內(nèi)的目標(biāo)圖像部分會(huì)被顯示,源圖像是透明的。
destination-out 在源圖像之外顯示目標(biāo)圖像。只有源圖像之外的目標(biāo)圖像部分會(huì)被顯示,源圖像是透明的。
lighter 顯示源圖像 + 目標(biāo)圖像。
copy 顯示源圖像。忽略目標(biāo)圖像。
xor 使用異或操作對(duì)源圖像與目標(biāo)圖像進(jìn)行組合。
```
**2.2 繪制圖像**
Canvas API 允許將圖像文件插入畫布。
我們可以使用Image對(duì)象來(lái)加載圖片,然后繪制:
```
var image = new Image();
image.onload = function(){
ctx.drawImage(image,0,0);
};
image.src='new.jpg';
```
**drawImage方法**
```
drawImage(img,x,y)
drawImage(img,x,y,width,height)
drawImage(img,sx,sy,switch,sheight,x,y,width,height)
```
參數(shù):
img 規(guī)定要使用的圖像、畫布或視頻;sx 可選,開(kāi)始剪切的 x 坐標(biāo)位置;sy 可選,開(kāi)始剪切的 y 坐標(biāo)位置;swidth 可選,被剪切圖像的寬度;sheight 可選,被剪切圖像的高度;x 表示在畫布上放置圖像的 x 坐標(biāo)位置;y 在畫布上放置圖像的 y 坐標(biāo)位置;width 可選,表示要使用的圖像的寬度(伸展或縮小圖像);height 可選,表示要使用的圖像的高度(伸展或縮小圖像)。
**圖像平鋪**
```
createPattern(image,type)
```
參數(shù):
type: no-repeat:不平鋪 ;repeat-x:橫方向平鋪;repeat-y:縱方向平鋪;repeat:全方向平鋪
**2.3 像素處理**
通過(guò)`getImageData`方法和`putImageData`方法,可以處理每個(gè)像素,進(jìn)而操作圖像內(nèi)容。
`getImageData()`方法可以用來(lái)讀取Canvas的內(nèi)容,返回一個(gè)對(duì)象,包含了每個(gè)像素的信息。
```
var imageData = ctx.getImageData(x,y,w,h)
```
參數(shù):x是canvas的X軸坐標(biāo),y是canvas的Y軸坐標(biāo),w是寬度,h是高度。
getImageData()方法返回一個(gè)像素顏色數(shù)組(該數(shù)組的長(zhǎng)度等于圖像的像素寬度*圖像的像素高度*4,每個(gè)值的范圍是0-255,可讀寫),imageData的屬性data就是指向它,順序是所取像素范圍的從左到右,從上到下,數(shù)組的元素是(所有圖形,包括圖片,和繪制的圖形)每個(gè)像素的rgba :
```
[r1,g1,b1,a1,r2,g2,b2,a2...]
```
`putImageData()`方法可將數(shù)組內(nèi)容重新繪制到Canvas上。
```
putImageData(imgData,x,y,dirtyX,dirtyY,dirtyWidth,dirtyHeight);
```
參數(shù):imgData 規(guī)定要放回畫布的 ImageData 對(duì)象;x 是ImageData 對(duì)象左上角的 x 坐標(biāo),以像素計(jì);y 是ImageData 對(duì)象左上角的 y 坐標(biāo),以像素計(jì);dirtyX 可選,水平值(x),以像素計(jì),在畫布上放置圖像的位置;dirtyY 可選,垂直值(y),以像素計(jì),在畫布上放置圖像的位置;dirtyWidth 可選,在畫布上繪制圖像所使用的寬度;dirtyHeight 可選,在畫布上繪制圖像所使用的高度。
當(dāng)然,我們也可以創(chuàng)建一個(gè)空白的ImageData對(duì)象。
```
var imgData=context.createImageData(width,height);
```
也可創(chuàng)建與指定的另一個(gè)ImageData對(duì)象尺寸相同的新ImageData對(duì)象(其不會(huì)復(fù)制圖像數(shù)據(jù)):
```
var imgData=context.createImageData(imageData);
```
ImageData對(duì)象有data屬性,它包含 color/alpha 信息的數(shù)組。
**2.4 保存與恢復(fù)**
save()方法用于保存上下文環(huán)境,restore()方法用于恢復(fù)到上一次保存的上下文環(huán)境。
**2.5 保存圖像**
我們可以使用toDataURL()方法將Canvas數(shù)據(jù)重新轉(zhuǎn)化成圖像文件形式:
```
canvas.toDataURL('image/png')
```
上面的代碼將Canvas數(shù)據(jù),轉(zhuǎn)化成PNG data URI。
**2.6 轉(zhuǎn)換**
**(1)scale()**
scale() 方法縮放當(dāng)前繪圖至更大或更小。
```
scale(scalewidth,scaleheight)
```
參數(shù):scalewidth 縮放當(dāng)前繪圖的寬度;scaleheight 縮放當(dāng)前繪圖的高度。
注意:如果您對(duì)繪圖進(jìn)行縮放,所有之后的繪圖也會(huì)被縮放。定位也會(huì)被縮放。如果您 scale(2,2),那么繪圖將定位于距離畫布左上角兩倍遠(yuǎn)的位置。
**(2)rotate()**
rotate() 方法旋轉(zhuǎn)當(dāng)前的繪圖。
```
rotate(angle)
```
參數(shù):angle 旋轉(zhuǎn)角度,以弧度計(jì)。
注意:旋轉(zhuǎn)只會(huì)影響到旋轉(zhuǎn)完成后的繪圖。
**(3)translate()**
translate() 方法重新映射畫布上的 (0,0) 位置。
```
translate(x,y)
```
參數(shù):x 添加到水平坐標(biāo)(x)上的值;y 添加到垂直坐標(biāo)(y)上的值。
**(4)transform()**
```
transform(a,b,c,d,e,f)
```
參數(shù):a 水平縮放繪圖,b 水平傾斜繪圖,c 垂直傾斜繪圖,d 垂直縮放繪圖,e 水平移動(dòng)繪圖,f 垂直移動(dòng)繪圖。
**(5)setTransform()**
setTransform() 方法把當(dāng)前的變換矩陣重置為單位矩陣,然后以相同的參數(shù)運(yùn)行 transform()。
```
setTransform(a,b,c,d,e,f)
```
參數(shù):a 水平縮放繪圖,b 水平傾斜繪圖,c 垂直傾斜繪圖,d 垂直縮放繪圖,e 水平移動(dòng)繪圖,f 垂直移動(dòng)繪圖。
注意:該變換只會(huì)影響 setTransform() 方法調(diào)用之后的繪圖。
**2.7 動(dòng)畫**
我們可以使用`setInterval()`和`setTimeout()`來(lái)產(chǎn)生動(dòng)畫效果。
還可以使用`requestAnimationFrame()`來(lái)制作動(dòng)畫。
requestAnimationFrame()函數(shù)是全局函數(shù)。
考慮兼容,如下:
```
var requestAnimFrame = function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(a) {window.setTimeout(a, 1e3 / 60, (new Date).getTime())};
}();
```
使用方法:
```
function step(){
requestAnimationFrame(step);
}
```
requestAnimationFrame()方法會(huì)返回一個(gè)requestID,是一個(gè)長(zhǎng)整型非零值,作為一個(gè)唯一的標(biāo)識(shí)符,可將該值作為參數(shù)傳遞給window.cancelAnimationFrame()來(lái)取消這個(gè)函數(shù)。
```
cancelAnimationFrame(requestID);
```
兼容性代碼:
```
var cancelAnimFrame = function() {
return window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || function(id) { clearTimeout(id); };
}();
```
- 前言
- JavaScript簡(jiǎn)介
- 基本概念
- 語(yǔ)法
- 數(shù)據(jù)類型
- 運(yùn)算符
- 表達(dá)式
- 語(yǔ)句
- 對(duì)象
- 數(shù)組
- 函數(shù)
- 引用類型(對(duì)象)
- Object對(duì)象
- Array對(duì)象
- Date對(duì)象
- RegExp對(duì)象
- 基本包裝類型(Boolean、Number、String)
- 單體內(nèi)置對(duì)象(Global、Math)
- console對(duì)象
- DOM
- DOM-屬性和CSS
- BOM
- Event 事件
- 正則表達(dá)式
- JSON
- AJAX
- 表單和富文本編輯器
- 表單
- 富文本編輯器
- canvas
- 離線應(yīng)用
- 客戶端存儲(chǔ)(Cookie、Storage、IndexedDB)
- HTML5 API
- Video/Audio
- Geolocation API
- requestAnimationFrame
- File API
- FullScreen API
- IndexedDB
- 檢測(cè)設(shè)備方向
- Blob
- vibrate
- Luminosity API
- WebRTC
- Page Visibility API
- Performance API
- Web Speech
- Notification
- 面向?qū)ο蟮某绦蛟O(shè)計(jì)
- 概述
- this關(guān)鍵字
- 原型鏈
- 作用域
- 常用API合集
- SVG
- 錯(cuò)誤處理機(jī)制
- JavaScript開(kāi)發(fā)技巧合集
- 編程風(fēng)格
- 垃圾回收機(jī)制
