<meta charset="utf-8">
一. 基本用法
在HTML中添加<canvas>元素,必須設(shè)置width跟height屬性
<canvas id="drawing" width="200" height="200">A drawing of something</canvas>
如果瀏覽器不支持canvas元素,就會顯示標(biāo)簽中間的內(nèi)容
要在畫布上繪圖,需要取得繪圖上下文,調(diào)用getContext('2d')就可以取得canvas的2d上下文
let drawing = document.getElementById("drawing")
let context = drawing.getContext("2d")
使用toDataURL方法可以導(dǎo)出canvas上繪制的圖像,接受一個參數(shù),圖像的MIME類型格式
let imgURL = drawing.toDataURL("image/png") // 將imgURL賦值給一個img元素的src屬性就可以顯示了
常用的屬性控制
- lineWidth:設(shè)置線條的寬度,可以是任意整數(shù)
- lineCap:設(shè)置線條末端的形狀,butt(平頭)、round(圓頭)、square(方頭)
- lineJoin:設(shè)置線條相交的方式,round(圓交)、斜交(bevel)、miter(斜接)
二.繪制矩形
矩形是唯一一種可以直接在上下文中繪制的形狀
與矩形有關(guān)的方法包括fillRect()、strokeRect()和clearRect(),這三個方法接受4個參數(shù)(x, y, width, height)
fillRect()繪制的矩形會填充指定的顏色,顏色通過fillStyle屬性指定
context.fillStyle = 'red'
context.fillRect(10, 10, 50, 50)
strokeRect()繪制的矩形會使用指定的顏色描邊,描邊顏色通過strokeStyle屬性指定
context.strokeStyle = '#ff0000'
context.strokeRect(30, 30, 50, 50)
clearRect()方法用于清除畫布上的矩形區(qū)域
context.fillStyle = 'green'
context.fillRect(10, 10, 50, 50)
context.fillStyle = 'red'
context.fillRect(30, 30, 50, 50)
context.clearRect(40, 40, 10, 10)

三.繪制路徑
要繪制路徑,首選必須調(diào)用beginPath()方法,表示開始繪制新路徑,繪制路徑主要有以下方法
- arc(x, y, radius, startAngle, endAndle, counterclockwise):以(x, y)為圓心繪制一條弧線,半徑為radius,起始和結(jié)束角度分別為startAngle和endAngle,最后一個參數(shù)表示順時針還是逆時針,false表示順時針
- arcTo(x1, y1, x2, y2, radius):從上一點開始繪制一條弧線,到(x2, y2)為止,并且穿過(x1, y1)
- bezierCurveTo(c1x, c1y, c2x, c2y, x, y):從上一點開始繪制一條曲線,到(x, y)為止,并且以(c1x, c1y)和(c2x, c2y)為控制點
- lineTo(x, y):從上一點開始繪制一條直線,到(x, y)為止
- moveTo(x, y):將繪圖游標(biāo)移動到(x, y),不畫線
- quadraticCurveTo(cx, cy, x, y):從上一點開始繪制一條二次曲線,到(x, y)為止,并且以(cx, cy)為控制點
- rect(x, y, width, height):從點(x, y)開始繪制矩形,寬為width,高為height,這個方法繪制的是矩形路徑,而不是strokeRect()和fillRect()繪制的獨立矩形

調(diào)用closePath()可以將路徑的起點與終點連接。路徑完成后,可以使用fill()填充,或者使用stroke()描邊。最后還可以調(diào)用clip(),在路徑上創(chuàng)建一個剪切區(qū)域
四.繪制文本
繪制文本主要有兩個方法,fillText()和strokeText(),這個兩個方法接受4個參數(shù):要繪制的文本字符串、x坐標(biāo)、y坐標(biāo)和可選的最大像素寬度。這兩個方法都以下列3個屬性為基礎(chǔ)
- font:表示文本樣式、大小及字體,用css中指定字體的格式來指定,例如"bold 10px Arial"
- textAlign:表示文本的對齊方式??赡苤涤?start"、"end"、"left"、"right"和"center"。
- textBaseline:表示文本的基線??赡苤涤?top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom"

上下文提供了輔助確定文本大小的方法measureText(),這個方法接受一個參數(shù),即要繪制的文本,返回一個TextMetrics對象,這個對象有一個width屬性,表示文本的寬度
五.變換
為上下文應(yīng)用變換,會導(dǎo)致使用不同的變換矩陣應(yīng)用處理,從而產(chǎn)生不同的結(jié)果,可以通過如下方法來修改變換矩陣
- rotate(angle):圍繞原點旋轉(zhuǎn)圖像angle弧度
- scale(scaleX, scaleY):縮放圖像,默認值都是1.0
- translate(x, y):將原點移動到(x, y)
有兩個方法可以追蹤上下文的狀態(tài)變化。save()方法將當(dāng)前上下文的所有狀態(tài)存入一個棧結(jié)構(gòu),restore()方法在保存狀態(tài)的棧結(jié)構(gòu)中向前返回一級

六.繪制圖像
如果想把一副圖像繪制到畫布上,可以使用drawImage()方法,調(diào)用這個方法時,可以使用三種不同的參數(shù)組合,最簡單的方式是傳入一個<img>元素,以及繪制該圖像的起點x和y坐標(biāo)
let image = document.images[0] // 獲取文檔中的第一幅圖像
context.drawImage(image, 10, 10) // 將圖像繪制到畫布上,起點為(10, 10),大小與原始大小一樣
可以多傳入兩個參數(shù),表示目標(biāo)寬度和高度
context.drawImage(image, 10, 10, 100, 100) // 繪制的圖像大小為100x100像素
還可以把圖像中的某個區(qū)域繪制到上下文中,需要傳入9個參數(shù):要繪制的圖像、源圖像的x坐標(biāo)、源圖像的y坐標(biāo)、源圖像的寬度、源圖像的高度、目標(biāo)圖像的x坐標(biāo)、目標(biāo)圖像的y坐標(biāo)、目標(biāo)圖像的寬度、目標(biāo)圖像的高度
context.drawImage(image, 50, 50, 80, 80, 10, 10, 50, 50)

除了給drawImage()方法傳入<img>元素外,還可以傳入另一個<canvas>元素作為其第一個參數(shù)。結(jié)合drawImage()和其他方法,可以對圖像進行各種基本操作,操作的結(jié)果可以通過toDataURL()方法獲得,toDataURL()是canvas的方法而不是上下文的方法
七.陰影
上下文會根據(jù)以下幾個屬性,自動為形狀或路徑繪制陰影,需要在繪制路徑之前設(shè)置
- shadowColor:陰影顏色,默認為黑色
- shadowOffsetX:形狀或路徑x軸方向的陰影偏移量,默認為0
- shadowOffsetY:形狀或路徑y(tǒng)軸方向的陰影偏移量,默認為0
- shadowBlur:模糊的像素數(shù),默認0,即不模糊

八.漸變
漸變有CanvasGradient實例表示,要創(chuàng)建一個新的線性漸變,可以調(diào)用createLinearGradient()方法,接受4個參數(shù):startX、startY、endX、endY。創(chuàng)建漸變后,使用addColorStop()方法來指定色標(biāo),接受兩個參數(shù):色標(biāo)位置和css顏色值。色標(biāo)位置是一個0(開始的顏色)到1(結(jié)束的顏色)之間的數(shù)字
let gradient = context.createLinearGradient(30, 30, 70, 70)
gradient.addColorStop(0, 'white')
gradient.addColorStop(1, 'black')
表示從一個畫布上的點(30, 30)到點(70, 70)的漸變。起點的色標(biāo)是白色,終點的色標(biāo)是黑色。然后可以把fillStyle或者strokeStyle設(shè)置為這個對象,從而使用漸變來繪制形狀或描邊

要創(chuàng)建徑向漸變,可以使用createRadialGradient()方法,接受6個參數(shù),對應(yīng)著兩個圓的圓心和半徑

九.模式
模式其實就是重復(fù)的圖像,可以用來填充或描邊圖像,使用createPattern()方法并傳入兩個參數(shù):一個<img>元素和一個表示如何重復(fù)圖像的字符串。其中第二個參數(shù)的值與css的background-repeat屬性值相同,包括“repeat”、“repeat-x”、“repeat-y”和“no-repeat”
模式與漸變一樣,都是從畫布的原點(0, 0)開始的,將填充樣式設(shè)置為模式對象,只表示在某個特定的區(qū)域內(nèi)顯示重復(fù)的圖像,而不是要從某個位置開始繪制重復(fù)圖像

十.使用圖像數(shù)據(jù)
上下文可以通過getImageData(x, y, width, height)取得原始圖像數(shù)據(jù)
let imageData = context.getImageData(10, 5, 50, 50) // 取得左上角坐標(biāo)為(10, 5),大小為50x50像素的區(qū)域的圖像數(shù)據(jù)
這里返回的對象是ImageData的實例,每個ImageData對象都有三個屬性:width、height和data。其中data是一個數(shù)組,保存著圖像中每一個像素的數(shù)據(jù)。
在data數(shù)組中,每一個像素用4個元素來保存,分別表示紅、綠、藍和透明度。因此第一個像素的數(shù)據(jù)保存在數(shù)組的第0到第3個元素中,數(shù)組中的每個元素的值都介于0到255之間(包括0和255)
putImageData()方法可以將imageData表示的圖像繪制到畫布上

十一.合成
globalAlpha:用于指定所有繪制的透明度,是一個介于0到1之間的值,默認值為1
如果所有的后續(xù)操作都要基于相同的透明度,可以先把globalAlpha設(shè)置為適當(dāng)?shù)闹?,然后繪制

globalCompositionOperation:表示后繪制的圖形怎樣與先繪制的圖形結(jié)合,可能的值如下
- source-over(默認值):后繪制的圖形位于先繪制的圖形上方
- source-in:后繪制的圖形與先繪制的圖形重疊部分可見,其他部分透明
- source-out:后繪制的圖形與先繪制的圖形不重疊部分可見,先繪制的圖形透明
- source-atop:后繪制的圖形與先繪制的圖形重疊部分可見,先繪制圖形不受影響
- destination-over:后繪制的圖形位于先繪制的圖形下方
- destination-in:后繪制的圖形位于先繪制的圖形下方,兩者不重疊的部分透明
- destination-out:后繪制的圖形擦除與先繪制的圖形重疊的部分
- destination-atop:后繪制的圖形位于先繪制的圖形下方,先繪制的圖形不重疊部分透明
context.fillStyle = 'blue'
context.fillRect(20, 20, 50, 50)
context.globalCompositionOperation = '***' // 需要在中間設(shè)置
context.fillStyle = 'red'
context.fillRect(45, 45, 50, 50)
