canvas
初始化canvas
<canvas id="c" width="500" height="500"></canvas>
<script>
var c = document.querySelector("#c") // 獲得畫(huà)布組件
var ctx = c.getContext("2d") // 獲得繪制上下文(筆觸)
</script>
以下屬性默認(rèn)為 ctx 對(duì)象(筆觸)的屬性
如:ctx.fillStyle='#fff'
樣式和陰影
- 筆觸屬性:
- fillStyle='#fff' 設(shè)置或返回用于填充繪畫(huà)的顏色 漸變或模式
- strokeStyle='#fff' 設(shè)置或返回用于筆觸的顏色 漸變或模式
- shadowColor='#fff' 設(shè)置或返回用于陰影的顏色
- shadowBlur=20 設(shè)置或返回用于陰影的模糊級(jí)別
- shadowOffsetX=20 設(shè)置或返回陰影距形狀的水平偏移
- shadowOffsetY=20 設(shè)置或返回陰影距形狀的垂直偏移
- 方法(舉例)
/* 創(chuàng)建線性漸變 */
let lgra=ctx.createLinearGradient(x1,y1,x2,y2) // 漸變開(kāi)始點(diǎn)x坐標(biāo),漸變開(kāi)始點(diǎn)y坐標(biāo),漸變結(jié)束點(diǎn)x坐標(biāo),漸變結(jié)束點(diǎn)y坐標(biāo)
lgra.addColorStop(0,"black") // 規(guī)定漸變對(duì)象中的在0位置時(shí)的顏色
lgra.addColorStop(0.5,"red") // 規(guī)定漸變對(duì)象中的在0.5(一半)位置時(shí)的顏色
lgra.addColorStop(1,"white") // 規(guī)定漸變對(duì)象中的在1(終點(diǎn))位置時(shí)的顏色
ctx.fillStyle=lgra // 設(shè)置樣式為lgra
ctx.fillRect(20,20,150,100) // 填充一個(gè)矩形
/* 創(chuàng)建放射狀/環(huán)形的漸變 */
var rgra=ctx.createRadialGradient(x0,y0,r0,x1,y1,r1) // 漸變開(kāi)始圓心x坐標(biāo),漸變開(kāi)始圓心y坐標(biāo),漸變開(kāi)始圓的半徑,漸變結(jié)束圓心x坐標(biāo),漸變結(jié)束圓心y坐標(biāo),漸變結(jié)束圓的半徑
rgra.addColorStop(0,"red") // 規(guī)定漸變對(duì)象中的在0位置時(shí)的顏色
rgra.addColorStop(1,"white") // 規(guī)定漸變對(duì)象中的在1(終點(diǎn))位置時(shí)的顏色
ctx.fillStyle=rgra // 設(shè)置樣式為rgra
ctx.fillRect(10,10,150,100) // 填充一個(gè)矩形
/* 在指定的方向上重復(fù)指定的元素 */
let pat=ctx.createPattern(img,"repeat") // img假設(shè)為一個(gè)圖片dom,repeat repeat-x repeat-y no-repeat
ctx.rect(0,0,150,100) // 創(chuàng)建一個(gè)矩形
ctx.fillStyle=pat // 設(shè)置樣式為pat
ctx.fill() // 填充矩形
線條樣式
- lineCap="round" 設(shè)置或返回線條的結(jié)束端點(diǎn)樣式
- butt(默認(rèn),平直),round(圓形線帽),square(正方形線帽)
- lineJoin="round" 設(shè)置或返回兩條線相交時(shí),所創(chuàng)建的拐角類(lèi)型
- miter(默認(rèn),創(chuàng)建尖角),bevel(創(chuàng)建斜角),round(創(chuàng)建圓角)
- lineWidth=10 設(shè)置或返回當(dāng)前的線條寬度
- miterLimit=5 設(shè)置或返回最大斜接長(zhǎng)度
- 只有當(dāng)lineJoin屬性為"miter"時(shí),miterLimit才有效
- 如果斜接長(zhǎng)度超過(guò)miterLimit的值,邊角會(huì)以lineJoin的"bevel"類(lèi)型來(lái)顯示
矩形
- rect(x,y,w,h) 定義矩形,(20,20,100,100)
- x(矩形左上角的x坐標(biāo)),y(矩形左上角的y坐標(biāo)),w(矩形的寬度,以像素計(jì)),h(矩形的高度,以像素計(jì))
- fillRect(x,y,w,h) 繪制'被填充'的矩形,默認(rèn)填充為黑色,參數(shù)同上
- strokeRect(x,y,w,h) 繪制矩形(無(wú)填充),參數(shù)同上
- clearRect(x,y,w,h) 清除指定矩形內(nèi)的像素
路徑
- fill() 填充定義的路徑
- stroke() 繪制定義的路徑
- beginPath() 起始一條路徑,或重置當(dāng)前路徑
- moveTo(x,y) 把路徑移動(dòng)到畫(huà)布中的指定點(diǎn),不創(chuàng)建線條
- lineTo(x,y) 添加一個(gè)新點(diǎn),然后在畫(huà)布中創(chuàng)建從該點(diǎn)到最后指定點(diǎn)的線條
- closePath() 創(chuàng)建從當(dāng)前點(diǎn)回到起始點(diǎn)的路徑
- clip() 從原始畫(huà)布剪切任意形狀和尺寸的區(qū)域,只有被剪切區(qū)域內(nèi)的內(nèi)容是可見(jiàn)的
- quadraticCurveTo(cx,cy,x,y) 定義二次貝塞爾曲線
- cx(控制點(diǎn)的x坐標(biāo)),cy(控制點(diǎn)的y坐標(biāo)),x(結(jié)束點(diǎn)的x坐標(biāo)),y(結(jié)束點(diǎn)的y坐標(biāo))
/* 繪制二次貝塞爾曲線 */
ctx.moveTo(20,20) // 開(kāi)始點(diǎn)
ctx.quadraticCurveTo(20,100,200,20) // 定義曲線
ctx.stroke() // 繪制
- bezierCurveTo(cx1,cy1,cx2,cy2,x,y) 創(chuàng)建三次方貝塞爾曲線
- cx1(控制點(diǎn)1的x坐標(biāo)),cy1(控制點(diǎn)1的y坐標(biāo)),cx2(控制點(diǎn)2的x坐標(biāo)),cy2(控制點(diǎn)2的y坐標(biāo)),x(結(jié)束點(diǎn)的x坐標(biāo)),y(結(jié)束點(diǎn)的y坐標(biāo))
- arc(x,y,r,sa,ea,c); 創(chuàng)建弧 圓
- x(圓心x坐標(biāo)),y(圓心y坐標(biāo)),r(半徑),sa(起始點(diǎn)弧度),ea(結(jié)束點(diǎn)弧度),c(順時(shí)針還是逆時(shí)針?lè)较騮rue逆時(shí)針false順時(shí)針)
/* 繪制一個(gè)圓 */
ctx.arc(100,75,50,0,2*Math.PI) // 定義一個(gè)圓
ctx.stroke() // 繪制
- arcTo(x1,y1,x2,y2,r); 創(chuàng)建兩切線之間的弧 曲線
- x1(頂點(diǎn)x坐標(biāo)),y1(頂點(diǎn)y坐標(biāo)),x2(切點(diǎn)2x坐標(biāo)),y2(切點(diǎn)2y坐標(biāo)),r(半徑)
/* 繪制兩切線之間的弧 */
ctx.moveTo(20,20) // 定義開(kāi)始點(diǎn)
ctx.lineTo(100,20) // 定義線段1,確定切點(diǎn)1
ctx.arcTo(150,20,150,70,50) // 定義弧(頂點(diǎn) 切點(diǎn)2 半徑)
ctx.lineTo(150,120) // 定義線段2
ctx.stroke() // 繪制
- isPointInPath(x,y) 如果指定的點(diǎn)位于當(dāng)前路徑中,則返回true,否則返回false
/* 判斷點(diǎn)是否在矩形中 */
ctx.rect(20,20,150,100)
if(ctx.isPointInPath(20,50)){
ctx.stroke()
}
轉(zhuǎn)換
- scale(x,y) 縮放當(dāng)前繪圖至更大或更小
/* 繪制矩形,放大到2倍,再次繪制矩形 */
ctx.strokeRect(5,5,25,15) // 畫(huà)一個(gè)矩形
ctx.scale(2,2) // 放大畫(huà)布
ctx.strokeRect(5,5,25,15) // 再畫(huà)一個(gè)矩形
ctx.scale(-1,1) // 設(shè)置負(fù)數(shù)可以得到畫(huà)布的鏡像
- rotate(a) 旋轉(zhuǎn)當(dāng)前繪圖,a(旋轉(zhuǎn)弧度)
- translate(x,y) 平移當(dāng)前畫(huà)布,x(x軸平移量),y(y軸平移量)
/* 平移矩形 */
ctx.fillRect(10,10,100,50) // 填充一個(gè)矩形
ctx.translate(10,10) // 平移畫(huà)布
ctx.fillRect(10,10,100,50) // 重新填充一個(gè)矩形
- transform(scaleX,skewX,skewY,scaleY,translateX,translateY) 變形當(dāng)前畫(huà)布
- scaleX(水平縮放),skewX(水平傾斜,x軸正方向逆時(shí)針度數(shù)的正弦值),skewY(垂直傾斜),scaleY(垂直縮放),translateX(水平移動(dòng)),translateY(垂直移動(dòng))
/* 變形矩形 */
ctx.transform(1,0.5,-0.5,1,30,10)
ctx.fillStyle="red"
ctx.fillRect(0,0,250,100)
- setTransform(scaleX,skewX,skewY,scaleY,translateX,translateY) 重置當(dāng)前畫(huà)布.然后執(zhí)行transform()
文本
- font="font-style font-variant font-weight font-size/line-height font-family *[caption icon menu message-box small-caption status-bar]" 設(shè)置或返回字體屬性
- 參數(shù)解釋
- font-style(字體樣式,normal正常 italic斜體 *oblique斜體)
- font-variant(字體變體,normal *small-caps大寫(xiě)轉(zhuǎn)小寫(xiě))
- font-weight(字體粗細(xì),normal bold加粗 100~900 *bolder加粗 *lighter正常)
- font-size/line-height(規(guī)定字號(hào)和行高,像素)
- font-family(字體樣式)
- caption(使用標(biāo)題控件的字體,比如按鈕 下拉列表等)
- icon(使用用于標(biāo)記圖標(biāo)的字體)
- menu(使用用于菜單中的字體,下拉列表和菜單列表)
- message-box(使用用于對(duì)話框中的字體)
- small-caption(使用用于標(biāo)記小型控件的字體)
- status-bar(使用用于窗口狀態(tài)欄中的字體)
/* 寫(xiě)文字 */
ctx.font="40px Arial"
ctx.fillText("Hello World",10,50)
- textAlign="start|end|center|left|right"; 設(shè)置或返回文本對(duì)齊方式
- start(默認(rèn) 指定位置開(kāi)始),end(指定位置結(jié)束),center(文本中心放置在指定位置),left(文本左對(duì)齊),right(文本右對(duì)齊)
- textBaseline="alphabetic|top|hanging|middle|ideographic|bottom"; 設(shè)置或返回當(dāng)前文本基線
- alphabetic(默認(rèn) 普通字母基線),top(em框頂端),hanging(懸掛基線),middle(em框正中),ideographic(表意基線),bottom(em框底端)
- fillText(text,x,y,maxWidth); 繪制"被填充的"文本
- text(輸出的文本),x(繪制文本的x坐標(biāo)),y(繪制文本的y坐標(biāo)),*maxWidth(最大文本寬度 以像素計(jì))
- strokeText(text,x,y,maxWidth); 繪制文本(無(wú)填充)
- measureText(text) 返回包含指定文本寬度的對(duì)象 text(要測(cè)量的文本)
/* 輸出文本的寬度 */
ctx.font="30px Arial"
var txt="Hello World"
ctx.fillText("width:" + ctx.measureText(txt).width,10,50)
ctx.fillText(txt,10,100)
圖像
- drawImage(img,[sx,sy,swidth,sheight],x,y,[width,height]) 向畫(huà)布上繪制圖像 畫(huà)布或視頻
- img(規(guī)定要使用的圖像 畫(huà)布或視頻DOM),x(要放置圖像的x坐標(biāo)位置),y(要放置圖像的y坐標(biāo)位置)
- sx(剪切的x坐標(biāo)位置),sy(剪切的y坐標(biāo)位置),swidth(被剪切圖像的寬度),sheight(被剪切圖像的高度),width(繪制圖像的寬度(伸展或縮小圖像)),height(繪制圖像的高度)
- createImageData(width,height |imageDate) 創(chuàng)建空白的ImageData對(duì)象
- width(ImageDate對(duì)象的寬,以像素計(jì)),height(ImageDate對(duì)象的高,以像素計(jì)),imageDate(創(chuàng)建與另一個(gè)ImageData對(duì)象尺寸相同的新ImageData對(duì)象,不會(huì)復(fù)制圖像數(shù)據(jù))
/* 創(chuàng)建100*100像素的ImageData對(duì)象 */
var imgData=ctx.createImageData(100,100)
for (var i=0;i<imgData.data.length;i+=4){
imgData.data[i+0]=255 // R
imgData.data[i+1]=0 // G
imgData.data[i+2]=0 // B
imgData.data[i+3]=255 // A (0-255 0表示透明 255表示完全可見(jiàn))
} // i=0 時(shí),把ImageData對(duì)象中的第一個(gè)像素變?yōu)榧t色
ctx.putImageData(imgData,10,10)
- getImageData(x,y,width,height) 返回ImageData對(duì)象 復(fù)制畫(huà)布上指定的矩形像素?cái)?shù)據(jù)
- x(開(kāi)始復(fù)制左上角x坐標(biāo)),y(左上角y坐標(biāo)),width(要復(fù)制矩形區(qū)域?qū)挾?,height(要復(fù)制矩形區(qū)域高度)
/* 復(fù)制畫(huà)布上的一個(gè)矩形 */
ctx.fillStyle="green"
ctx.fillRect(10,10,50,50)
function copy(){
var imgData=ctx.getImageData(10,10,50,50)
ctx.putImageData(imgData,10,70)
}
- putImageData(imgData,x,y,[dirtyX,dirtyY,dirtyWidth,dirtyHeight]) 把圖像數(shù)據(jù)(ImageData對(duì)象)放在畫(huà)布上
- imgData(ImageData對(duì)象),x(左上角的x坐標(biāo) 以像素計(jì)),y(左上角的y坐標(biāo) 以像素計(jì))
- dirtyX(控制ImageData對(duì)象x屬性),dirtyY(ImageData對(duì)象y屬性),dirtyWidth(ImageData對(duì)象width屬性),dirtyHeight(ImageData對(duì)象height屬性)
- imageData.width 返回ImageData對(duì)象的寬度
- imageData.height 返回ImageData對(duì)象的高度
- imageData.data 返回一個(gè)數(shù)組,包含ImageData對(duì)象的color/alpha數(shù)據(jù)
合成
- globalAlpha=number; 設(shè)置或返回當(dāng)前繪圖的alpha(透明值),number(0 全透明~1 不透明 之間)
- globalCompositeOperation="source-over"; 設(shè)置或返回新圖像如何繪制到已有的圖像上
- 可用的取值:
- source-over 默認(rèn) 新圖像顯示在原圖像上方
- source-atop 顯示在原圖像上方 位于原圖像外的部分不可見(jiàn)
- source-in 顯示在原圖像上方 只有原圖像內(nèi)的部分會(huì)顯示 原圖像是透明的
- source-out 只會(huì)顯示原圖像之外部分 原圖像是透明的
- destination-over 新圖像顯示在原圖像下方
- destination-atop 新圖像之外的原圖像部分不會(huì)被顯示
- destination-in 新圖像內(nèi)的原圖像部分會(huì)顯示 新圖像是透明的
- destination-out 新圖像外的原圖像部分會(huì)顯示 新圖像是透明的
- lighter 顯示原圖像和新圖像 重合部分顏色混合
- copy 顯示新圖像 忽略原圖像
- xor 使用異或操作對(duì)新圖像與原圖像進(jìn)行組合 重合區(qū)域不顯示
其他
canvas 為 canvas標(biāo)簽的DOM對(duì)象
- save() 保存當(dāng)前的畫(huà)布狀態(tài)
- restore() 回滾到之前保存的畫(huà)布狀態(tài)
- canvas.getContext(contextID) 返回一個(gè)用于在畫(huà)布上繪圖的環(huán)境 getContext("2d")
- canvas.toDataURL(type,encoderOptions) 將canvas導(dǎo)出為base64格式的圖片
- type(圖片格式 默認(rèn)image/png,image/jpeg,image/webp)
- encoderOptions(在指定圖片格式為image/jpeg或image/webp的情況下,可以從0到1的區(qū)間內(nèi)選擇圖片的質(zhì)量 如果超出取值范圍 將會(huì)使用默認(rèn)值0.92)
- canvas.createEvent(type) 創(chuàng)建事件對(duì)象
canvas應(yīng)用例子
canvas壓縮圖片
function compressImg(img){
//創(chuàng)建畫(huà)板
let canvas=document.createElement('canvas')
let ctx=canvas.getContext('2d')
//獲取圖片參數(shù)
let initSize=img.src.length
let width=img.width
let height=img.height
// 如果圖片大于200萬(wàn)像素威蕉,計(jì)算壓縮比并將大小壓至400萬(wàn)以下
let ratio=(width*height)/2000000
if (ratio>1) {
ratio=Math.sqrt(ratio)
width/=ratio
height/=ratio
}else{
ratio=1
}
canvas.width=width
canvas.height=height
// 鋪底色
ctx.fillStyle='#fff'
ctx.drawImage(img,0,0,width,height)
// 進(jìn)行最小壓縮
let ndata = canvas.toDataURL('image/jpeg')
return ndata;
}