什么是canvas
HTML5 <canvas> 元素用于圖形的繪制秤朗,通過腳本 (通常是JavaScript)來完成.
<canvas> 標簽只是圖形容器煤蹭,您必須使用腳本來繪制圖形。
創(chuàng)建一個canvas
一個畫布在網(wǎng)頁中是一個矩形框取视,通過 <canvas> 元素來繪制.
注意: 默認情況下 <canvas> 元素沒有邊框和內(nèi)容硝皂。你也可以添加。
使用如下代碼作谭,你就在頁面中創(chuàng)建出來一個寬200px稽物、高100px的canvas,如果沒有指定寬高折欠,canvas的默認寬高為300px * 150px,通常我們需要給canvas一個id以便在腳本中引用贝或。
<canvas id="myCanvas" width="200" height="100"></canvas>
我們也可以動態(tài)創(chuàng)建canvas,使用一下代碼锐秦,我們在頁面中創(chuàng)建出了一個id為layer的canvas咪奖,指定了其寬高。
var canvas = document.createElement('canvas');
canvas.id = "layer";
canvas.width = 200;
canvas.height = 100;
document.body.appendChild(canvas);
canvas操作
我們可以使用canvas繪制線條酱床、矩形羊赵、圓形、文本扇谣、圖像昧捷,可以對圖形、文本進行顏色填充以及漸變填充罐寨。詳細內(nèi)容可查看基礎(chǔ)教程靡挥,其中我們用到的比較多的應該是繪制圖像,繪制圖像會在下面專門講解衩茸。
canvas屬性中的寬高和css中寬高的區(qū)別
我們先看一個例子
我們使用屬性中的寬高創(chuàng)建一個canvas芹血,其寬高為300px,我們在其中畫一條線楞慈,從(0幔烛,0)點到(300,300)點囊蓝。我們可以看出該圖顯示正常不會被拉伸饿悬。
<canvas id="layer" width="300" height="300">瀏覽器不支持Canvas,請升級或改用其它瀏覽器!</canvas>
<script type="text/javascript">
var canvas = document.getElementById("layer"),
ctx = canvas.getContext('2d');
ctx.moveTo(0,0);
ctx.lineTo(300,300);
ctx.stroke();
</script>
接著我們給canvas設(shè)置一下style中寬高
#layer {
width: 150px;
height: 300px;
}
效果如下聚霜,使用style時圖像會被拉伸(變形)
這是什么原因狡恬?珠叔??我們需要搞清楚兩個概念:
1.畫布的寬和高(ps新建畫布的寬和高)弟劲;
2.畫布所在畫板的寬和高(例如ps打開后的窗口)祷安;
默認的畫板、畫布的寬和高是屬性中設(shè)置的寬高(例子中即為300*300)兔乞。但在畫布上設(shè)置style屬性的話汇鞭,相當于把畫板的寬和高改變了,而畫布的寬和高還是默認值庸追,所以 畫布會出現(xiàn)拉伸的情況霍骄,此例中設(shè)置的畫板的寬150和高300,相當于將畫布的寬度縮小一倍淡溯,所以實際上畫出來的是黑色的那條读整。 直接設(shè)置寬和高相當于是同時修改了畫板和畫布的寬和高(兩者一致),所以在畫布上畫的圖形不會出現(xiàn)拉伸(如紅色那條線)咱娶。
canvas繪制圖像
繪制圖像主要使用的是drawImage
方法
drawImage() 方法在畫布上繪制圖像米间、畫布或視頻。
drawImage() 方法也能夠繪制圖像的某些部分豺总,以及/或者增加或減少圖像的尺寸车伞。
語法:
1.在畫布上定義圖像:
context.drawImage(img,x,y);
2.在畫布上定位圖像择懂,并規(guī)定圖像的寬度和高度:
context.drawImage(img,x,y,width,height);
3.剪切圖像喻喳,并在畫布上定位被剪切的部分:
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
參數(shù)值:
參數(shù) | 描述 |
---|---|
img | 規(guī)定要使用的圖像、畫布或視頻困曙。 |
sx | 可選表伦。開始剪切的 x 坐標位置。 |
sy | 可選慷丽。開始剪切的 y 坐標位置蹦哼。 |
swidth | 可選。被剪切圖像的寬度要糊。 |
sheight | 可選纲熏。被剪切圖像的高度。 |
x | 在畫布上放置圖像的 x 坐標位置锄俄。 |
y | 在畫布上放置圖像的 y 坐標位置局劲。 |
width | 可選。要使用的圖像的寬度奶赠。(伸展或縮小圖像) |
height | 可選鱼填。要使用的圖像的高度。(伸展或縮小圖像) |
以上基礎(chǔ)內(nèi)容查看w3c教程
繪制圖像中的填坑
1.繪制圖像時毅戈,canvas中沒有圖像
var drawimg = document.getElementById("drawimg");
var image=document.getElementById("image");
var context = drawimg.getContext("2d");
context.drawImage(image,10,10);
原因是圖片是異步加載苹丸,在之前的代碼中愤惰,執(zhí)行js代碼的時候圖片有可能還沒有加載成功,就調(diào)用了drawImage()方法赘理,所以圖片就無法顯示宦言。所以在使用drawImage()方法時,務必保證所繪圖像已經(jīng)加載好了商模。通常我們會將其放在圖片加載onload回調(diào)函數(shù)中確保這一點蜡励。
image.onload=function(){
context.drawImage(devBgImg,imgX,imgY,imgWidth,imgHeight);
};
//例子
var img = new Image();
img.src ='devmonitor/res/main.jpg';
img.onload=function(){
ctx.drawImage(img,0,0,img.width,img.height,imgX,imgY,
canvas.width*imgScale,canvas.height*imgScale);
};
canvas像素操作
語法
context.getImageData(x,y,width,height);
參數(shù) | 描述 |
---|---|
x | 開始復制的左上角位置的 x 坐標。 |
y | 開始復制的左上角位置的 y 坐標阻桅。 |
width | 將要復制的矩形區(qū)域的寬度 |
height | 將要復制的矩形區(qū)域的高度 |
getImageData() 方法返回 ImageData 對象凉倚,該對象拷貝了畫布指定矩形的像素數(shù)據(jù)。
ImageData對象中存儲著canvas對象真實的像素數(shù)據(jù)嫂沉,它包含以下幾個只讀屬性:
width
無符號長整型(unsigned long)稽寒,使用像素描述 ImageData 的實際寬度。
height
無符號長整型(unsigned long)趟章,使用像素描述 ImageData 的實際高度杏糙。
data
Uint8ClampedArray類型的一維數(shù)組,包含著RGBA格式的整型數(shù)據(jù)蚓土,范圍在0至255之間(包括255)宏侍。
imageData.data;
一維數(shù)組,存儲了從canvas中獲取的每個像素的RGBA值蜀漆。該數(shù)組為每個像素點保存了四個值——紅谅河、綠、藍和alpha透明度确丢。
imageData.data并不是一個真正的數(shù)組绷耍,而是一個類數(shù)組的對象-------Uint8ClampedArray,data是個一維數(shù)組鲜侥!data的元素始終依次是red,green,blue,alpha,red,green,blue褂始。。描函。一直重復到最后一個崎苗。所以,data的length始終是像素個數(shù)*4.而在循環(huán)data的時候舀寓,也是以4為步長胆数。
綜合例子我們可以對canvas中像素進行操作
翻轉(zhuǎn)顏色
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
ctx.drawImage(img,0,0);
var imgData=ctx.getImageData(0,0,c.width,c.height);
// 反轉(zhuǎn)顏色(步長為4)
for (var i=0;i<imgData.data.length;i+=4)
{
imgData.data[i]=255-imgData.data[i];
imgData.data[i+1]=255-imgData.data[i+1];
imgData.data[i+2]=255-imgData.data[i+2];
imgData.data[i+3]=255;
}
ctx.putImageData(imgData,0,0);
灰度處理
例子中僅僅是用紅綠和藍的平均值。你也可以用加權(quán)平均基公,例如x = 0.299r + 0.587g + 0.114b這個公式幅慌。
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("tulip");
ctx.drawImage(img,0,0);
var imgData=ctx.getImageData(0,0,c.width,c.height);
// 反轉(zhuǎn)顏色(步長為4)
for (var i=0;i<imgData.data.length;i+=4)
{
var avg = (data[i] + data[i +1] + data[i +2]) / 3;
data[i] = avg; // red
data[i + 1] = avg; // green
data[i + 2] = avg; // blue
}
ctx.putImageData(imgData,0,0);
顏色選擇器:
//創(chuàng)建image對象
var img = new Image();
img.src = 'haorooms.jpg';
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//img加載完成后畫到canvas上
img.onload = function() {
ctx.drawImage(img, 0, 0);
img.style.display = 'none';
};
//獲取顏色RGBA值的函數(shù)
function pick(event) {
//layerX和layerY屬性表示Canvas內(nèi)部坐標系中的坐標
var x = event.layerX;
var y = event.layerY;
var pixel = ctx.getImageData(x, y, 1, 1);
var data = pixel.data;
console.log(data);
//獲取到RGBA值的字符串
var rgba = 'rgba(' + data[0] + ',' + data[1] +
',' + data[2] + ',' + (data[3] / 255) + ')';
//自定義操作例如將字符串顯示在某dom上或者return返回值等
//
}
//為canvas綁定mousemove事件
canvas.addEventListener('mousemove', pick);
這篇文章中有對像素操作的多個應用介紹
canvas和圖片相互轉(zhuǎn)換
//此處image應確保加載完成
function convertImageToCanvas(image) {
var canvas = document.createElement("canvas");
canvas.width = image.width;
canvas.height = image.height;
canvas.getContext("2d").drawImage(image, 0, 0);
return canvas;
}
// Converts canvas to an image
function convertCanvasToImage(canvas) {
var image = new Image();
image.src = canvas.toDataURL("image/png");
return image;
}