線條樣式
- 繪制直線,第五章知識簡單回顧
lineWidth 設置或返回當前的線條寬度,單位為像素
-
lineCap 設置或返回線條的結束端點樣式
- butt 默認。向線條的每個末端添加平直的邊緣。
- round 向線條的每個末端添加圓形線帽。
- square 向線條的每個末端添加正方形線帽。
- "round" 和 "square" 會使線條略微變長。
cxt.lineCap = "round";
-
lineJoin 設置或返回兩條線相交時,所創建的拐角類型
- miter 默認。創建尖角。
- bevel 創建斜角。
- round 創建圓角。
cxt.lineJoin = "bevel";
-
miterLimit 設置或返回最大斜接長度。
斜接長度指的是在兩條線交匯處內角和外角之間的距離。該屬性定義了斜連線長度和線條寬度的最大比率
- 只有當 lineJoin 屬性為 "miter" 時,miterLimit 才有效。
- 邊角的角度越小,斜接長度就會越大。為了避免斜接長度過長,我們可以使用 miterLimit 屬性。
- 如果斜接長度超過 miterLimit 的值,邊角會以 lineJoin 的 "bevel" 類型來顯示
cxt.lineJoin = "miter"; cxt.miterLimit=2;
矩形
- rect(x,y,w,h) 創建矩形。
- fillRect(x,y,w,h) 繪制"被填充"的矩形。
- strokeRect(x,y,w,h) 繪制矩形(無填充)。
- clearRect(x,y,w,h) 在給定的矩形內清除指定的像素。
cxt.fillRect(100,100,100,100)
cxt.clearRect(110,110,80,80);
路徑方法
- fill() 填充當前繪圖(路徑)
- stroke() 繪制已定義的路徑
- moveTo() 把路徑移動到畫布中的指定點,不創建線條
- lineTo() 添加一個新點,然后在畫布中創建從該點到最后指定點的線條
- 開啟和關閉路徑
- beginPath() 起始一條路徑,或重置當前路徑
- closePath() 創建從當前點回到起始點的路徑
繪制圓弧
arc() 創建弧/曲線(用于創建圓形或部分圓)
-
arcTo(x1,y1,x2,y2,r) 創建兩切線之間的弧/曲線,點1坐標,點2坐標,半徑
ctx.beginPath(); ctx.moveTo(200,300); ctx.arcTo(200,100,400,100,100) ctx.lineTo(400,100); ctx.stroke();
//封裝繪制圓角矩形的函數 function roundRect(x,y,w,h,r){ ctx.beginPath() ctx.moveTo(x,y+r) ctx.arcTo(x,y,x+w,y,r) ctx.arcTo(x+w,y,x+w,y+h,r) ctx.arcTo(x+w,y+h,x,y+h,r) ctx.arcTo(x,y+h,x,y,r) ctx.closePath() ctx.stroke() }
quadraticCurveTo(cx,cy,x,y) 創建二次貝塞爾曲線
二次貝塞爾曲線需要兩個點。第一個點是用于二次貝塞爾計算中的控制點,第二個點是曲線的結束點。曲線的開始點是當前路徑中最后一個點。如果路徑不存在,那么請使用 beginPath() 和 moveTo() 方法來定義開始點。
bezierCurveTo(c1x,c1y,c2x,c2y,x,y) 創建三次方貝塞爾曲線
提示:三次貝塞爾曲線需要三個點。前兩個點是用于三次貝塞爾計算中的控制點,第三個點是曲線的結束點。曲線的開始點是當前路徑中最后一個點。如果路徑不存在,那么請使用 beginPath() 和 moveTo() 方法來定義開始點。
clip() 從原始畫布剪切任意形狀和尺寸的區域
isPointInPath() 如果指定的點位于當前路徑中,則返回 true,否則返回 false
// 二次方貝塞爾曲線
ctx.beginPath()
ctx.moveTo(50,50)
ctx.quadraticCurveTo(150,200,300,50);
ctx.stroke()
//為了更好的理解繪制原理,這里我們將控制線也繪制出來
ctx.beginPath()
ctx.strokeStyle = "blue"
ctx.lineWidth=1
ctx.moveTo(50,50)
ctx.lineTo(150,200)
ctx.lineTo(300,50)
ctx.stroke()
//三次方貝塞爾曲線
ctx.beginPath()
ctx.lineWidth=3
ctx.fillStyle = "orange"
ctx.strokeStyle = "green"
ctx.moveTo(350,50)
ctx.bezierCurveTo(400,150,600,200,700,50);
ctx.stroke()
//為了更好的理解繪制原理,這里我們將控制線也繪制出來
ctx.beginPath()
ctx.strokeStyle = "blue"
ctx.lineWidth=1
ctx.moveTo(350,50)
ctx.lineTo(400,150)
ctx.moveTo(600,200)
ctx.lineTo(700,50)
ctx.stroke()
顏色、樣式和陰影
- fillStyle 設置或返回用于填充繪畫的顏色、漸變或模式
- strokeStyle 設置或返回用于筆觸的顏色、漸變或模式
- 陰影
- shadowColor 設置或返回用于陰影的顏色
- shadowBlur 設置或返回用于陰影的模糊級別
- shadowOffsetX 設置或返回陰影距形狀的水平距離
- shadowOffsetY 設置或返回陰影距形狀的垂直距離
- 漸變
- createLinearGradient(x0,y0,x1,y1) 創建線性漸變(用在畫布內容上)
- createRadialGradient(x0,y0,r0,x1,y1,r1) 創建放射狀/環形的漸變(用在畫布內容上)
- addColorStop() 規定漸變對象中的顏色和停止位置
- createPattern(image,"repeat|repeat-x|repeat-y|no-repeat")在指定的方向上重復指定的元素
- createPattern() 方法在指定的方向內重復指定的元素。
- 元素可以是圖片、視頻,或者其他 canvas 元素。
- 被重復的元素可用于繪制/填充矩形、圓形或線條等等
CanvasPattern對象開始平鋪圖像的參考起點并不是我們當前繪制圖形的左上角,而是整個canvas畫布的左上角,確切地說,即canvas的起點坐標(0,0)。
注意:如果createPattern()方法的image參數值不是當前頁面一個已經存在的Image對象或Canvas對象,那么我們需要等待瀏覽器將圖片加載完畢后才能調用createPattern()方法及后續操作,否則將無法正確顯示對應的圖形。
// ctx.shadowColor = 'rgb(75, 71, 230)';
// ctx.shadowOffsetX = 5;
// ctx.shadowOffsetY = 5;
// ctx.shadowBlur = 10;
//
// ctx.fillRect(100,100,100,100);
//
// // var gradient = ctx.createLinearGradient(300,100,400,100);
// var gradient = ctx.createRadialGradient(350,150,10,350,150,100);
// gradient.addColorStop(0,'rgb(52, 213, 55)');
// gradient.addColorStop(0.25,'rgb(213, 96, 52)');
// gradient.addColorStop(0.5,'rgb(52, 203, 213)');
// gradient.addColorStop(0.75,'rgb(104, 52, 213)');
// gradient.addColorStop(1,'rgb(210, 213, 52)');
// ctx.fillStyle = gradient;
// ctx.fillRect(300,100,100,100);
var img = new Image();
img.src = './xj2.png';
img.onload = function () {
// 創建CanvasPattern對象,指定上述圖片進行水平的重復平鋪
var pattern = ctx.createPattern(img,"repeat");
ctx.fillStyle= pattern;
ctx.fillRect(0,0,500,800);
}
文本
- 屬性
- font 設置或返回文本內容的當前字體屬性
- textAlign 設置或返回文本內容的當前對齊方式
- start 默認。文本在指定的位置開始。
- end 文本在指定的位置結束。
- center 文本的中心被放置在指定的位置。
- left 文本左對齊。
- right 文本右對齊。
- textBaseline 設置或返回在繪制文本時使用的當前文本基線
- top 文本基線是 em 方框的頂端。
- bottom 文本基線是 em 方框的底端。
- middle 文本基線是 em 方框的正中。
- alphabetic 默認。文本基線是普通的字母基線。
- ideographic 文本基線是表意基線。一般用于繪制中文或日文字符串。
- hanging 文本基線是懸掛基線。一般用于繪制印度語字符串
```
ctx.beginPath();
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
ctx.font = '50px 宋體';
ctx.fillText('我',100,100);
ctx.strokeText('我',200,200);
document.write(ctx.measureText(ctx).width);
```
- 方法
- fillText() 在畫布上繪制“被填充的”文本
- strokeText() 在畫布上繪制文本(無填充)
- measureText() 返回包含指定文本寬度的對象 語法:context.measureText(text).width;
measureText的返回值是一個對象,但里面只有一個屬性:width,本來文字的尺寸應該有width也有height,但canvas中的文字連行高都沒有,所以measureText也沒法得出高度。
measureText只是單純的測量文字,與是否把文字寫到canvas上無關。
轉換
- translate() 重新映射畫布上的 (0,0) 位置(即移動坐標原點)
- scale() 縮放當前繪圖至更大或更小
溫馨提示:如果對繪圖進行縮放,所有之后的繪圖也會被縮放。定位也會被縮放。如果您 scale(2,2),那么繪圖將定位于距離畫布左上角兩倍遠的位置。
- rotate() 旋轉當前繪圖
注意參數單位為弧度。如需將角度轉換為弧度,請使用 degrees*Math.PI/180 公式進行計算。
- transform() 替換繪圖的當前轉換矩陣
- setTransform() 將當前轉換重置為單位矩陣。然后運行 transform()
//縮放\平移\旋轉
ctx.translate(100,100);
ctx.scale(2,2);
ctx.rotate(15*Math.PI/180);
狀態的保存和恢復
- save() 保存當前環境的狀態
ctx.save();// 保存當前繪圖狀態
- restore() 返回之前保存過的路徑狀態和屬性
ctx.restore();
注意:可以多次保存,逐級恢復;最后保存的最先還原!restore總是還原離他最近的save點(已經還原的不能第2次還原到他)。
<script type="text/javascript">
var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
ctx.lineWidth = 5;
ctx.fillStyle = 'rgb(76, 207, 106)';
ctx.strokeStyle = 'rgb(23, 26, 139)';
var i = 0;
var j=100;
var step=-1;
function test() {
i++;
if(j==200){
step=-1
}else if(j==1){
step=1
}
j+=step;
ctx.save()
ctx.clearRect(0,0,c.width,c.height);
ctx.scale(j/100,j/100);
ctx.translate(c.width/2,c.height/2);
ctx.rotate(i*15*Math.PI/180);
ctx.translate(-50,-50);
ctx.strokeRect(0,0,100,100);
ctx.fillRect(0,0,100,100);
ctx.restore()
}
setInterval('test()',10);
</script>
合成
- globalAlpha 設置或返回繪圖的當前 alpha 或透明值
- globalCompositeOperation 設置或返回新圖像如何繪制到已有的圖像上
- source-over 默認。在目標圖像上顯示源圖像。
- source-atop 在目標圖像頂部顯示源圖像。源圖像位于目標圖像之外的部分是不可見的。
- source-in 在目標圖像中顯示源圖像。只有目標圖像內的源圖像部分會顯示,目標圖像是透明的。
- source-out 在目標圖像之外顯示源圖像。只會顯示目標圖像之外源圖像部分,目標圖像是透明的。
- destination-over 在源圖像上方顯示目標圖像。
- destination-atop 在源圖像頂部顯示目標圖像。源圖像之外的目標圖像部分不會被顯示。
- destination-in 在源圖像中顯示目標圖像。只有源圖像內的目標圖像部分會被顯示,源圖像是透明的。
- destination-out 在源圖像外顯示目標圖像。只有源圖像外的目標圖像部分會被顯示,源圖像是透明的。
- lighter 顯示源圖像 + 目標圖像。這個值與順序無關,如果源與目標重疊,就將兩者的顏色值想加。得到的顏色值的最大取值為 255,結果就為白色。
- copy 顯示源圖像。忽略目標圖像。這個值與順序無關,只繪制源,覆蓋掉目標。
- xor 使用異或操作對源圖像與目標圖像進行組合。這個值與順序無關,只繪制出不重疊的源與目標區域。所有重疊的部分都變成透明的
ctx.globalCompositeOperation = 'xor';
圖像繪制
-
drawImage(img,sx,sy,swidth,sheight,x,y,width,height) 向畫布上繪制圖像、畫布或視頻
- img 規定要使用的圖像、畫布或視頻。
- sx 可選。開始剪切的 x 坐標位置。
- sy 可選。開始剪切的 y 坐標位置。
- swidth 可選。被剪切圖像的寬度。
- sheight 可選。被剪切圖像的高度。
- x 在畫布上放置圖像的 x 坐標位置。
- y 在畫布上放置圖像的 y 坐標位置。
- width 可選。要使用的圖像的寬度。(伸展或縮小圖像)
- height 可選。要使用的圖像的高度。(伸展或縮小圖像)
- drawImage(image,x,y) : 在canvas中(x,y)處繪制圖片。
- drawImage(image,x,y,width,height) : 在canvas中(x,y)處繪制圖片,并將其縮放到指定的寬度和高度。
- drawImage(image,sourceX,sourceY,sourceWidth,sourceHeight,x,y,width,height) :
從圖片中切割出一個矩形區域(sourceX,sourceY,sourceWidth,sourceHeight),縮放到指定的寬度和高度,并在canvas中(x,y)繪制出來。
// 在圖片未被加載錢不能對其繪制 // window.onload=function () { // ctx.drawImage(img,0,0); // } img.onload = function () { ctx.drawImage(img,0,0,100,100,0,0,100,100); }
像素操作
- 屬性
- width 返回 ImageData 對象的寬度(可以理解為一行像素的個數)
- height 返回 ImageData 對象的高度(可以理解為一列像素的個數)
- data 返回一個對象,其包含指定的 ImageData 對象的圖像數據
- 該對象包含每一個像素的四個rgba值,注意每個值都在0-255之間
- 這個四個參數和CSS中講的rgba顏色表示法原理相同,四個參數分別表示紅、綠、藍以及透明度。
- 所不同的是這里的透明度取值也是0-255,255表示完全不透明,0表示完全透明
- 方法
getImageData(x,y,w,h) 返回 ImageData 對象,該對象為畫布上指定的矩形復制像素數據
-
putImageData(imgData,dx,dy,dirtyX,dirtyY,w,h) 把圖像數據(從指定的 ImageData 對象)放回畫布上
首先討論第一種最簡單的putImageData用法,即putImageData(imgData,dirtyX,dirtyY),在解釋其他參數
- imgData 規定要放回畫布的 ImageData 對象。
- dx/dy ImageData 對象左上角的 x/y坐標,以像素計。即準備繪制圖像的起點坐標.
[dirtyX,dirtyY,w,h]為一組可選參數,該參數確定了一個以dx和dy坐標原點的矩形,分別表示矩形的起點和寬高,該矩形把將要繪制的圖像限定在矩形區域內.
溫馨提示:如果用繪入外部圖片的辦法測試該屬性,在本地測試會出錯,這是由于javaScript的同源策略對context.getImageDate的影響,該策略是基于瀏覽器的安全,禁用會造成安全隱患。可以通過搭建一個本地站點,將文檔放到站點的方法測試。對于這一點在本課程中不做過多講解。
-
createImageData() 創建新的、空白的 ImageData 對象
- var imgData=context.createImageData(width,height);以指定的尺寸(以像素計)創建新的 ImageData 對象
- var imgData=context.createImageData(imageData)創建與指定的另一個 ImageData 對象尺寸相同的新 ImageData 對象(不會復制圖像數據)
<script type="text/javascript"> var c = document.getElementById('canvas'); var ctx = c.getContext('2d'); var img= new Image(); img.onload = function () { ctx.drawImage(img,0,0,300,200); } img.src = './tooopen_sy_172649745666.jpg' function putImg() { var imgData = ctx.getImageData(0,0,300,200); ctx.putImageData(imgData,310,0,50,0,100,100); } // 反色繪制 function fs() { ctx.clearRect(300,0,300,200); var imgData = ctx.getImageData(0,0,300,200); for (var i = 0; i < imgData.data.length; i+=4) { imgData.data[i+0] = 255-imgData.data[i+0]; imgData.data[i+1] = 255-imgData.data[i+1]; imgData.data[i+2] = 255-imgData.data[i+2]; // imgData.data[i+3] = 255 - imgData.data[i+3]; } ctx.putImageData(imgData,310,0); } // 濾鏡 function lj() { ctx.clearRect(300,0,300,200); var imgData = ctx.getImageData(0,0,300,200); for (var i = 0; i < imgData.data.length; i+=4) { imgData.data[i] = 0; } ctx.putImageData(imgData,310,0); }
```
canvas畫布內容導出為圖像
- toDataURL()這個方法能把畫布里的圖案轉變成base64編碼格式的png,然后返回 Data URL數據。
溫馨提示:以前多數瀏覽器不支持canvas中的內容直接右鍵保存為圖片格式。但現在大多數瀏覽器都是支持的。
面向畫布(Canvas)的JavaScript庫
- EaselJS 是一個封裝了 HTML5 畫布(Canvas) 元素的 JavaScript 庫。
- jCanvaScript面向HTML5畫布(canvas)的Javascript類庫,它提供了許多方法用于簡化處理HTML5畫布(canvas)元素的內容,只要支持canvas和javascript的瀏覽器都可以使用它,包括iPhone、iPad和android等平臺。
- Processing.js是一個開放的編程語言,在不使用Flash或Java小程序的前提下,可以實現程序圖像、動畫和互動的應用。Processing.js是輕量,易于了解掌握的理想工具,可用于可視化的數據,創建用戶界面和開發基于Web的游戲。
- FABRIC.JS是一款簡單而強大的JavaScript Canvas 庫,提供了互動的對象模型,同時還包含 Canvas-to-SVG 解析器。
- oCanvas是一個JavaScript框架,用于簡化HTML5 Canvas標簽的使用,可以利用對象來代替像素。 oCanvas 可以幫助你很容易的在 HTML5 的 Canvas 標簽上創建對象,并且創建這些對象的動畫。
- jCanvas 就是一個 jQuery 的繪圖插件,它封裝了一些繪制圖形的方法,只需編寫幾行代碼即可生成圖形。
- RGraph是一個使用HTML5 Canvas標簽實現的圖表制作Library。利用該Library生成的Chart具有可交互性,當鼠標點擊或移過時會顯示相應的信息,可以動態加載Chart或對特殊點進行縮放。
- Two.js 是面向現代 Web 瀏覽器的一個二維繪圖 API。Two.js 可以用于多個場合:SVG,Canvas 和 WebGL,旨在使平面形狀和動畫的創建更方便,更簡潔。
- ......