canvas簡(jiǎn)介
canvas標(biāo)簽是HTML5標(biāo)準(zhǔn)最受歡迎的一個(gè)標(biāo)簽浓利,它的作用就相當(dāng)于一塊畫布挤庇,可以通過JS腳本在canvas上面進(jìn)行繪畫,而且還可以對(duì)畫面的內(nèi)容進(jìn)行修改贷掖,通過不斷修改可以實(shí)現(xiàn)動(dòng)畫的效果嫡秕,再跟事件結(jié)合后就可以制作游戲了!
canvas標(biāo)簽及其所對(duì)應(yīng)的JS對(duì)象HTMLCanvasElement本身非常簡(jiǎn)單苹威,它們主要包含width昆咽、height兩個(gè)屬性和一個(gè)getContext方法。雖然HTML5中新增了setContext等方法牙甫,但是各大瀏覽器支持得并不好掷酗。
canvas本身并沒有太多得操作,它主要是通過getContext方法獲取的環(huán)境對(duì)象進(jìn)行操作窟哺。canvas和它所包含的context對(duì)象的關(guān)系就好像canvas是一塊畫布泻轰,而context是各種筆,拿到筆且轨,然后才可以繪圖浮声。
canvas的用法
首先獲取canvas對(duì)象虚婿,然后使用這個(gè)對(duì)象獲取相應(yīng)的環(huán)境,最后使用獲取的環(huán)境繪圖泳挥。
代碼示例:
<body>
<canvas id="c2d" width="300" height="300">瀏覽器不支持canvas</canvas>
<canvas id="c3d" width="150" height="150">瀏覽器不支持canvas</canvas>
<script>
// 獲取canvas對(duì)象
const canvas2d = document.querySelector('#c2d');
// 使用這個(gè)對(duì)象獲取相應(yīng)的環(huán)境
const ctx2d = canvas2d.getContext('2d');'
// 繪制圖形...
const canvas3d = document.querySelector('#c3d');
const ctx3d = canvas3d.getContext('webgl');
</script>
</body>
從示例中然痊,我們可以看出利用getContext()方法獲取繪圖環(huán)境,目前只支持2d('2d')和3d('webgl')環(huán)境羡洁。
繪制矩形
繪制矩形是canvas中最簡(jiǎn)單的功能,跟繪制矩形相關(guān)的方法一共包括如下三個(gè):
- strokeRect(x,y,width,height):繪制矩形邊框
- fillRect(x,y,width,height):繪制矩形并填充
-
clearRect(x,y,width,height): 清除矩形區(qū)域內(nèi)容爽丹,實(shí)際上是使用底色填充矩形區(qū)域筑煮。
這三個(gè)方法的參數(shù)中,x,y表示矩形左上角的坐標(biāo)粤蝎,width和height表示矩形的寬和高真仲,坐標(biāo)原點(diǎn)默認(rèn)為canvas的左上角,canvas中矩形的結(jié)構(gòu)如下:
canvas矩形結(jié)構(gòu)圖
代碼示例:
<canvas id="c2d" width="300" height="300">瀏覽器不支持canvas</canvas>
<script>
const canvas2d = document.querySelector('#c2d');
const ctx2d = canvas2d.getContext('2d');
// 繪制矩形
ctx2d.fillRect(30,50,100,50);
ctx2d.strokeRect(100,30,100,50);
ctx2d.clearRect(101,51,28,28);
</script>
繪制路徑
使用路徑一共可以分為4步:創(chuàng)建路徑初澎、繪制路徑秸应、關(guān)閉路徑和操作路徑,其中繪制路徑最復(fù)雜也是最重要的內(nèi)容碑宴。先介紹其他三種操作软啼,最后詳細(xì)講解繪制路徑。
創(chuàng)建/關(guān)閉路徑
創(chuàng)建路徑
路徑的創(chuàng)建一共有兩種方法延柠,一種是調(diào)用CanvasRenderingContext2D的beginPath方法祸挪,另一種是新建Path2D對(duì)象。
調(diào)用CanvasRenderingContext2D的beginPath方法后就可以直接使用CanvasRenderingContext2D來繪制路徑贞间,而使用Path2D新建時(shí)會(huì)返回新建的路徑贿条,然后在新建出來的路徑上進(jìn)行操作,例如下面的例子:
<canvas id="c2d">瀏覽器不支持canvas</canvas>
<script>
const c2d = document.querySelector('#c2d');
const ctx2d = c2d.getContext('2d');
// 使用beginPath方法創(chuàng)建
ctx2d.beginPath();
// 這里可以使用ctx2d繪制路徑
// ......
// 使用Path2D新建路徑
const newPath = new Path2D();
// 這里實(shí)際newPath來繪制路徑
//......
</script>
關(guān)閉路徑
關(guān)閉路徑使用的是closePath方法增热,其主要作用是將路徑閉合起來整以,也就是從畫筆的終點(diǎn)到路徑的起點(diǎn)繪制一條直線,如果路徑已經(jīng)閉合峻仇,那么也可以不調(diào)用該方法公黑。
操作路徑
對(duì)路徑的操作只有兩種:填充和描邊,它們所對(duì)應(yīng)的方法分別是stroke和fill摄咆。如果是使beginPath創(chuàng)建的路徑帆调,那么直接調(diào)用就可以了,如果是新建的Path2D路徑豆同,那么需要將創(chuàng)建出來的路徑傳入?yún)?shù)中番刊,例如下面的例子:
<canvas id="c2d">瀏覽器不支持canvas</canvas>
<script>
const c2d = document.querySelector('#c2d');
const ctx2d = c2d.getContext('2d');
// 使用beginPath方法創(chuàng)建
ctx2d.beginPath();
// 這里可以使用ctx2d繪制路徑
// ......
ctx2d.closePath();
ctx2d.fill();
// 使用Path2D新建路徑
const newPath = new Path2D();
// 這里實(shí)際newPath來繪制路徑
//......
newPath.closePath();
ctx2d.stroke(newPath);
</script>
繪制路徑
所有平面上的圖形都是由直線和曲線組成的(點(diǎn)其實(shí)是半徑很小的實(shí)心圓),因此路徑的繪制主要分為直線和曲線兩種類型影锈。但是芹务,CanvasRenderingContext2D繪制路徑時(shí)除了這兩種類型外還有一個(gè)輔助操作的方法蝉绷。
輔助操作
輔助方法:moveTo(x,y),兩個(gè)參數(shù)表示移動(dòng)到的目標(biāo)點(diǎn)的坐標(biāo)值
繪制直線
方法:lineTo(x,y),它可以從畫筆當(dāng)前點(diǎn)到參數(shù)中傳入的坐標(biāo)點(diǎn)畫一條直線,一般會(huì)與moveTo方法配合使用枣抱。
樣式的設(shè)置
屬性:lineWidth:指定線條的寬度
屬性:lineDashOffset: 指定虛線的偏移量
方法:setLineDash():設(shè)置虛線的樣式熔吗,參數(shù)為一個(gè)數(shù)組,數(shù)組的元素用來表示實(shí)線與空白所占用的寬度佳晶,虛線會(huì)按數(shù)組中的值進(jìn)行循環(huán)桅狠。
示例(畫一個(gè)正方形和兩條虛線):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="canvas" width="500" width="500"></canvas>
<script>
const canvas = document.querySelector('#canvas');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.moveTo(10,10);
ctx.lineTo(10,100);
ctx.lineTo(100,100);
ctx.lineTo(100,10);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.setLineDash([5,10]);
ctx.moveTo(10,120);
ctx.lineTo(120,120);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.setLineDash([5,10]);
ctx.lineDashOffset = 2;
ctx.moveTo(10,130);
ctx.lineTo(130,130);
ctx.closePath();
ctx.stroke();
}
</script>
</body>
</html>
繪制曲線
繪制圓弧
方法:arc(x,y,radius,startAngle,endAngle,anticlockwise)
參數(shù)說明:x,y為圓心,radius為半徑轿秧,startAngle和endAngle分別是起始角度和結(jié)束角度中跌,anticlockwise表示是否逆時(shí)針繪制,默認(rèn)為順時(shí)針菇篡。
方法:arcTo(x1,y1,x2,y2,radius)
參數(shù)說明:通過兩條切線和半徑來指定一段圓弧漩符,畫筆當(dāng)前點(diǎn)和(x1,y1), (x1,y1)和(x2,y2)構(gòu)成兩條切線,參數(shù)radius為半徑驱还。兩條切線和一個(gè)半徑可以將一個(gè)圓分成兩段圓弧嗜暴,acrTo方法繪制的是較短的那段。如果畫筆的起始點(diǎn)不是圓弧的切點(diǎn)议蟆,那么acrTo方法還會(huì)將起點(diǎn)和切點(diǎn)使用直線連接起來闷沥。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas width="500" height="500" id='c2d'></canvas>
<script>
const canvas = document.getElementById('c2d');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(100,100,100,0, 2*Math.PI,false);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.lineTo(250,30);
ctx.lineWidth = 0.5;
ctx.arcTo(200,30,250,50,20);
ctx.closePath();
ctx.stroke();
</script>
</body>
</html>
繪制貝塞爾曲線
方法:quadraticCurveTo(cp1x,xp1y,x,y)
方法:bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
這兩個(gè)方法分別用于繪制一個(gè)控制點(diǎn)和兩個(gè)控制點(diǎn)的貝塞爾曲線,畫筆當(dāng)前點(diǎn)為曲線的起點(diǎn)咐容,(x,y)為曲線的終點(diǎn)狐赡,(cpx1,cp1y)和(cp2x,cp2y)都是控制點(diǎn),理解了貝塞爾曲線疟丙,這兩個(gè)方法就很容易理解:深入理解貝塞爾曲線
實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d">瀏覽器不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(30,50);
ctx.quadraticCurveTo(40,80,100,50);
ctx.moveTo(130,60);
ctx.bezierCurveTo(160,30,200,100,260,50);
ctx.stroke();
}
</script>
</body>
</html>
組合與剪切
組合與剪切主要是對(duì)應(yīng)多個(gè)圖形來說的颖侄,組合指的是多個(gè)圖形重疊時(shí)的組合方式,剪切是指使用路徑來指定繪圖的區(qū)域享郊,類似于Photoshop中的蒙版的效果览祖。
組合
圖形的組合是通過globalCompositeOperation屬性來操作的,該屬性可以取下面的值:
- source-over: 后繪制的圖形覆蓋原圖炊琉,該值為默認(rèn)值
- source-in: 保留后繪制圖形和原圖形重疊的部分展蒂,使用后繪制圖形的樣式,其他區(qū)域透明苔咪,也就是保留相交的部分
- source-out: 保留后繪制圖形不和原圖形重疊的部分锰悼,其他區(qū)域透明
- source-atop: 保留后繪制圖形和原圖形重疊的部分,使用后繪制圖形的樣式团赏,原圖中的非重疊部分不變
- destination-over: 后繪制圖形被原圖覆蓋箕般,也就是重疊部分顯示原圖
- destination-in: 保留后繪制圖形和原圖形重疊的部分,使用原圖的樣式舔清,其他區(qū)域透明
- destination-out: 保留原圖不和后繪制圖形重疊的部分丝里,其他區(qū)域透明
- destination-atop: 保留后繪制圖形和原圖形重疊的部分曲初,使用原圖的樣式,后繪制圖形中的非重疊部分不變
- lighter: 后繪制圖形和原圖重疊的部分進(jìn)行疊加
- copy: 顯示后繪制圖形杯聚,不顯示原圖
- xor: 后繪制圖形和原圖重疊的部分進(jìn)行異或操作
- multiply: 將后繪制圖形和原圖的像素相乘臼婆,圖形變暗
- screen: 將后繪制圖形和原圖的像素分別反向后相乘再反向,圖形變亮
- overlay: 組合使用multiply和screen,使亮的部分更亮幌绍,暗的部分更暗
- darken: 取兩個(gè)圖形中較暗的像素值颁褂,例如,#aa0011與#cc3300計(jì)算后為#aa0000
- ighten: 取兩個(gè)圖形中較亮的像素值傀广,例如颁独,#aa0011與#cc3300計(jì)算后為#aa3311
- color-dodge: 使用原圖像素除以后繪制圖形的反向像素值
- color-burn: 使用原圖反向像素除以后繪制圖形的像素,然后再反向
- hard-light: 組合使用multiply和screen主儡,它與overlay的區(qū)別是將原圖和后繪制圖形進(jìn)行交換
- soft-light: 類似于hard-light奖唯,但比hard-light柔和
- difference: 使用后繪制圖形的像素值減去原圖的像素值
- exclusion: difference操作后降低對(duì)比度
- hue: 使用后繪制圖形的色調(diào)和原圖的亮度惨缆、色度
- saturation: 使用后繪制圖形的色度和原圖的亮度糜值、色調(diào)
- color: 使用后繪制圖形的色度、色調(diào)和原圖的亮度
- luminosity:使用后繪制圖形的亮度和原圖的色度坯墨、色調(diào)
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.fillRect(30,60,60,40);
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = 'blue';
ctx.fillRect(70,40,60,40);
}
</script>
</body>
剪切
剪切的作用其實(shí)是指定新的繪圖區(qū)域寂汇,如果將圖像繪制到剪切區(qū)域外面就顯示不出來了,但是剪切操作不會(huì)影響剪切之前的圖形捣染。剪切使用的是clip方法骄瓣,如下:
- clip([fillRule="nonzero"])
- clip(path[,fillRule="nonzero"])
fillRule:用來指定用你什么算法來判斷一個(gè)點(diǎn)是否在被剪切的區(qū)域內(nèi),可取“nonzero”或“evenodd”
當(dāng)路徑是使用beginPath創(chuàng)建時(shí)耍攘,使用第一種方式直接調(diào)用clip榕栏,當(dāng)路徑是使用Path2D創(chuàng)建時(shí),需要使用第二種方式將創(chuàng)建的路徑作為參數(shù)傳入蕾各。
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
ctx.fillRect(110,15,30,45);
ctx.beginPath();
ctx.arc(60,60,45,0,2*Math.PI);
ctx.stroke();
ctx.clip();
ctx.fillRect(0,0,60,60);
}
</script>
</body>
首先畫一個(gè)以(110,15)為左上頂點(diǎn)扒磁,寬為30、高為45的矩形式曲,接著剪切了一個(gè)(60妨托,60)為圓形、45為半徑的圓吝羞,然后又畫了一個(gè)以(0兰伤,0)為左上角,寬和高都是60的矩形钧排。這時(shí)第一個(gè)矩形可以正常顯示敦腔,但是第二個(gè)矩形只有剪切區(qū)域中的部分(也就是和剪切區(qū)域相交的部分)才可以顯示出來。
坐標(biāo)檢測(cè)
坐標(biāo)檢測(cè)就是檢測(cè)指定的點(diǎn)是否在所畫的路徑中恨溜,可以用于動(dòng)畫和游戲的碰撞檢測(cè)中会烙。坐標(biāo)檢測(cè)使用的是isPointInPath方法负懦,方法如下:
- isPointInPath(x,y[,fillRule="nonzero"])
- isPointInPath(path,x,y[,fillRule="nonzero"])
參數(shù)中,fillRule也用于指定算法柏腻,一般不需要修改纸厉;x和y為要檢測(cè)點(diǎn)的坐標(biāo);path為使用Path2D新建出來的路徑五嫂,如果是beginPath新建的路徑颗品,就可以直接調(diào)用。
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<div></div>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
const newPath = new Path2D();
newPath.rect(30,30,40,60);
const div = document.querySelector('div');
const spanValue = `<span>30,40 is in Path: ${ctx.isPointInPath(newPath,30,40)}</span>`;
const spanValue1 = `<span>20,40 is in Path: ${ctx.isPointInPath(newPath,20,40)}</span>`;
div.innerHTML = spanValue + '<br>' + spanValue1;
}
</script>
</body>
顏色和樣式是通過strokeStyle和fillStyle兩個(gè)屬性修改的沃缘,它們的默認(rèn)值都是black躯枢,strokeStyle表示畫線(描邊)用的樣式,fillStyle表示填充用的樣式槐臀,它們可以被賦予三種類型的值:純色锄蹂、漸變和模式。
純色
純色有以下三種賦值方法:
- 直接賦予顏色值水慨,包括賦予十六進(jìn)制和顏色的單詞得糜,例如#323232、red等
- 使用rgb函數(shù)賦值晰洒,rgb函數(shù)有三個(gè)十進(jìn)制(0~255)的參數(shù)朝抖,分別表示紅、綠谍珊、藍(lán)的值
- 使用rgba函數(shù)賦值治宣,rgba函數(shù)在rgb函數(shù)的基礎(chǔ)上添加了透明度(alpha),它用第四個(gè)參數(shù)表示透明度砌滞。透明度的取值范圍為【0侮邀,1】,其中贝润,0表示完全透明绊茧,1表示完全不透明。
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
ctx.fillStyle = "blue";
ctx.beginPath();
ctx.rect(0,0,20,20);
ctx.fill();
ctx.fillStyle = "rgb(249,27,27)";
ctx.beginPath();
ctx.rect(20,20,20,20);
ctx.fill();
ctx.fillStyle = "rgb(249,27,27, 0.5)";
ctx.beginPath();
ctx.rect(40,40,20,20);
ctx.fill();
}
</script>
</body>
漸變
漸變的顏色是通過CanvasGradient對(duì)象來表示的题暖,它可以使用下面兩個(gè)方法來創(chuàng)建:
- createLinearGradient(x0,y0,x1,y1): 創(chuàng)建線性漸變
- createRadialGradient(x0,y0,x1,y1,r1): 創(chuàng)建徑向漸變按傅,也就是散漸變
CanvasGradient對(duì)象包含一個(gè)addColorStop方法,用來添加漸變的顏色控制點(diǎn)胧卤,語法如下:
addColorStop(offset,color)
offset用于設(shè)置控制點(diǎn)唯绍,取值范圍【0,1】枝誊;color用于設(shè)置控制點(diǎn)的顏色况芒。
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
let lineGradient = ctx.createLinearGradient(20,20,100,150);
lineGradient.addColorStop(0, 'red');
lineGradient.addColorStop(0.5, 'rgba(255,255,0,0.7)');
lineGradient.addColorStop(1, '#ff6d00');
ctx.fillStyle = lineGradient;
ctx.beginPath();
ctx.arc(50,50,30,0,2*Math.PI);
ctx.fill();
let radiaGradient = ctx.createRadialGradient(130,50,10,130,50,30);
radiaGradient.addColorStop(0,'rgba(255,204,205,0.3)');
radiaGradient.addColorStop(0.5,'#ffff00');
radiaGradient.addColorStop(1,'#ff6d00');
ctx.fillStyle = radiaGradient;
ctx.fillRect(100,20,60,60);
}
</script>
</body>
模式
模式使用CanvasPattern對(duì)象來表示的,它使用createPattern方法來創(chuàng)建叶撒,語法如下:
createPattern(image,repetition);
參數(shù)中绝骚,image為CanvasImageSource類型耐版,它可以是html中的img節(jié)點(diǎn)、video節(jié)點(diǎn)压汪、canvas節(jié)點(diǎn)或者CanvasRenderingContext2D對(duì)象粪牲。repetion為重復(fù)方式,它可以取下面4個(gè)值:
- repeat: 水平和豎直兩個(gè)方向重復(fù)
- repeat-x: 水平重復(fù)
- repeat-y: 豎直重復(fù)
- no-repeat: 不重復(fù)
模式的用法就好像使用圖片作為畫筆繪圖止剖,其中repetition屬性跟css中的background-repeat屬性類似腺阳。
示例:
<body>
<canvas id='c2d'>瀏覽器不支持canvas</canvas>
<script>
const canvas = document.getElementById('c2d');
if (canvas.getContext) {
let ctx = canvas.getContext('2d');
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
img.onload = function () {
var pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(0, 0, 400, 400);
};
}
</script>
</body>
插入文本
在繪圖的過程中經(jīng)常需要插入一些文本內(nèi)容,在CanvasRenderingContext2D中可以使用下面的方法來插入:
- fillText(text,x,y[,maxWidth]):實(shí)心文本
- strokeText(text,x,y[,maxWidth]):空心wenb
相關(guān)屬性: - font: 字體
- textAlign:排列方式,可選值[start, end, left, right, center]
- direction: 文本方向
- textBaseline: 文本的基線穿香,漢字用不到亭引,值為top,hanging,middle,alphabetic,ideographic,bottom.
實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d">瀏覽器不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.font='28px 行楷';
ctx.fillText('愛我中華', 10, 50);
ctx.font = '38px 宋體';
ctx.strokeText('中國加油', 10, 100);
}
</script>
</body>
</html>
插入圖片
在CanvasRenderingContext2D中可以插入圖片,使用drawImage方法皮获,有以下三種調(diào)用方式:
- drawImage(image, x, y)
指定圖片繪制位置的左上角 - drawImage(image,x,y,width,height)
指定繪制后的寬和高焙蚓,這個(gè)方法可能會(huì)產(chǎn)生變形 - drawImage(image,sx,sy,sWidth,sHeight,dx,dy,dWidth,dHeight)
可以截取原圖的一部分繪制到當(dāng)前canvas中,并且可以進(jìn)行縮放洒宝,它的后8個(gè)參數(shù)中的前4個(gè)表示在原圖中要截取得位置购公,sx,sy為截取的左上角的位置,sWidth和sHeight為截取的寬度和高度待德,后4個(gè)參數(shù)表示在當(dāng)前canvas中繪制的位置君丁,dx枫夺,dy為繪制的左上角将宪,dWidth和dHeight為繪制的寬度和高度。
參數(shù)中橡庞,image為CanvasImageSource類型较坛,可以是html中的img節(jié)點(diǎn)、video節(jié)點(diǎn)扒最、canvas節(jié)點(diǎn)或者Canvas'RenderingContext2D對(duì)象丑勤。
實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d" width="800" height="800">瀏覽器不支持canvas</canvas>
<img id="pic" src="./img/Pic2.png" hidden="true">
<script>
window.onload = function () {
const canvas = document.querySelector('#c2d');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
const pic = document.getElementById('pic');
ctx.drawImage(pic, 0, 0, 100, 100);
ctx.drawImage(pic, 50, 50, 100, 100);
ctx.drawImage(pic, 100, 100, 100, 100);
}
}
</script>
</body>
</html>
環(huán)境的保存和恢復(fù)
在繪圖的過程中經(jīng)常需要對(duì)環(huán)境進(jìn)行設(shè)置,例如填充樣式吧趣、描邊法竞,在操作完之后,往往需要恢復(fù)到原來的環(huán)境强挫,CanvasRenderingContext2D中可以使用save和restore方法快速操作岔霸。
環(huán)境的保存和恢復(fù)還可以進(jìn)行多層嵌套。多次使用save方法可以創(chuàng)建多個(gè)保存點(diǎn)俯渤,每次調(diào)用restore方法都會(huì)按save相反的順序獲取所保存的環(huán)境呆细。
實(shí)例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d" width="600" height="600">瀏覽器不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.save();
ctx.fillStyle = 'red';
ctx.fillRect(0,0,100,100);
ctx.restore();
ctx.fillRect(100,100,100,100);
}
</script>
</body>
</html>
移動(dòng)坐標(biāo)原點(diǎn)
方法:translate(x,y):x八匠,y代表移動(dòng)后x絮爷,y坐標(biāo)
旋轉(zhuǎn)坐標(biāo)系
方法:rotate(angle)趴酣, 旋轉(zhuǎn)角度,整數(shù)為逆時(shí)針坑夯,負(fù)數(shù)為順時(shí)針岖寞。
實(shí)例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d" width="500" height="500">不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.fillRect(0,0,10,30);
ctx.translate(10,30);
ctx.fillRect(0,0,10,30);
ctx.translate(10,30);
ctx.rotate(-Math.PI * 1/2);
ctx.fillStyle='red';
ctx.fillRect(0,0,10,30);
}
</script>
</body>
</html>
縮放
方法: scale(x, y)
坐標(biāo)系除了可以移動(dòng)和旋轉(zhuǎn)外還可以進(jìn)行縮放,縮放使用的是scale方法柜蜈,它有兩個(gè)參數(shù)慎璧,分別標(biāo)識(shí)橫軸和縱軸縮放的比例, 1為原始大小,大于1為放大跨释,小于1為縮小胸私。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d" height="600" width="600">瀏覽器不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.fillText('愛我中華', 10, 50);
ctx.scale(2,2);
ctx.translate(50,50);
ctx.fillText('愛我中華', 10, 50);
}
</script>
</body>
</html>
同樣是填充一個(gè)文本,由于第二次填充文字時(shí)鳖谈,x軸和y軸都同比增加了2倍岁疼,所以文字的大小也相應(yīng)的增加。
陰影
屬性值:
- shadowOffsetX: 陰影的水平偏移距離
- shadowOffsetY: 陰影的豎直偏移距離
- shadowBlur: 陰影的模糊效果缆娃,數(shù)字越大越模糊
- shadowColor: 陰影顏色
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<canvas id="c2d">瀏覽器不支持canvas</canvas>
<script>
const canvas = document.querySelector('#c2d');
if(canvas.getContext) {
const ctx = canvas.getContext('2d');
// 設(shè)置陰影效果
ctx.shadowOffsetX = -7;
ctx.shadowOffsetY = 5;
ctx.shadowBlur = 3;
ctx.shadowColor = 'rgba(255,255,0,0.7)';
ctx.fillStyle = 'red';
ctx.fillRect(15,30,130,40);
}
</script>
</body>
</html>