@(HTML5)[canvas與SVG]
[TOC]
十 、canvas
canvas的基本用法
canvas是HTML5中的新的標(biāo)簽,表示一個HTML畫布對象梧躺。
定義canvas元素
<canvas id="canvas" width="500" height="500">對不起奥吩,你的瀏覽器不支持canvas標(biāo)簽</canvas>
canvas只有兩個屬性(width與height)。默認(rèn)的width是300px构拳,高度是150px咆爽。注意:不要使用css樣式指定canvas的大小。
渲染上下文
canvas初始化是空白的置森,要在上面用腳本畫圖首先需要其渲染上下文斗埂,可以通過canvas對象的getContext
方法來獲取,同時得到的還有一些畫圖用的函數(shù)凫海。
這里來看看一個例子:
function draw() {
var canvas = document.getElementById("canvas");
if (canvas.getContext) {
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200,0,0)";
ctx.fillRect (10, 10, 55, 50);
ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
ctx.fillRect (30, 30, 55, 50);
}
}
canvas繪制圖形
我們先來看一下canvas的網(wǎng)格
在上面的例子中繪制了兩個正方形呛凶,拿其中的紅色正方形來講。運行代碼后行贪,會發(fā)現(xiàn)它離左上角有一定的距離漾稀。這個距離是由傳進(jìn)的參數(shù)來決定的,是(10,10)建瘫。這表示這個正方形的原點的坐標(biāo)崭捍。在canvas網(wǎng)格中,原點定在左上角的位置(坐標(biāo)(0,0))啰脚。所有canvas里所繪制的圖形的位置都是相對這個原點的殷蛇。看下圖,這個藍(lán)色的方塊的位置就是距離左邊x像素粒梦,距離上邊y像素亮航,即它的坐標(biāo)是(x,y)。實際上匀们,是(x-0,y-0)缴淋,由于canvas定原點坐標(biāo)為(0,0)所以便是(x,y)。
下面我們來看看繪制的具體的方法
繪制矩形
以下單個函數(shù)是繪制矩形:
fillRect(x,y,width,height) //填充一個矩形
strokeRect(x,y,width,height) //繪制一個矩形的邊框(但不填充矩形的內(nèi)部)
clearRect(x,y,width,height) //擦出了指定的矩形泄朴,并且用一個透明的顏色填充
繪制路徑
與繪制路徑有關(guān)的函數(shù):
beginPath() //丟棄任何當(dāng)前定義的路徑并且開始一條新的路徑宴猾。它把當(dāng)前的點設(shè)置為(0,0)。當(dāng)一個畫布的環(huán)境第一次創(chuàng)建時叼旋,beginPath()方法會被顯示地調(diào)用仇哆。
closePath() //創(chuàng)建從當(dāng)前點到開始點的路徑。
stroke() //方法繪制當(dāng)前路徑的邊框夫植。它意味著畫輪廓讹剔,但是線條的可視化取決于strokeStyle、lineWidth详民、lineJoin延欠、lineCap和miterLimit等屬性。
fill() //方法用于填充路徑沈跨,默認(rèn)是黑色由捎。fill()方法使用fillStyle屬性所指定的顏色、漸變和模式來填充當(dāng)前路徑饿凛。當(dāng)調(diào)用該方法時狞玛,開放的路徑會自動閉合。
moveTo()方法
moveTo(x,y) //用于定位繪畫的位置涧窒,即將點移動到參數(shù)x,y所指定的坐標(biāo)位置心肪。
canvas初始化或者調(diào)用了beginPath()方法時,繪畫開始的位置即原點(0,0)纠吴,使用moveTo()方法硬鞍,我們可以將起始位置移動到任何我們想要的地方。
lineTo()方法
lineTo(x,y) //接受終點的坐標(biāo)(x,y)作為參數(shù)戴已。起始坐標(biāo)取決于前一路徑的終點坐標(biāo)固该。當(dāng)然,起始坐標(biāo)也可以通過前面介紹的moveTo()方法來設(shè)置糖儡。
arc()方法
arc(x, y, radius, startAngle, endAngle, anticlockwise)
該方法接受6個參數(shù)伐坏。其中,x,y是圓心坐標(biāo)休玩;radius是圓的半徑著淆;startAngle和endAngle分別是起末弧度(以x軸為基準(zhǔn));anticlockwise為true表示逆時針拴疤,反之為順時針永部。
這邊有一點是需要注意的,就是arc方法里的角度是以弧度為計算單位的呐矾,不是度苔埋。這么說吧,通常我們說的180度蜒犯,就等價于PI组橄。兩者的計算公式是這樣的:radians=(Math.PI/180)*degrees.(其中,radians代表弧度罚随,degrees代表度)
貝塞爾與二次方曲線
貝塞爾曲線(Bézier curve)玉工,又稱貝茲曲線或貝濟埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線
二次貝塞爾曲線
quadraticCurveTo(cpx, cpy, x, y)
其中淘菩,cpx指控制點的x坐標(biāo)遵班;cpy指控制點的y坐標(biāo);x指結(jié)束點的x坐標(biāo)潮改;y指結(jié)束點的y坐標(biāo)狭郑。
看看下面的這個圖片:
由上面的參數(shù)可以看出,二次貝賽爾曲線需要兩個點:第一個點用于二次貝賽爾計算中的控制點汇在,第二個點是曲線的結(jié)束點翰萨。曲線的開始點是當(dāng)前路徑中最后一個點。如果路徑不存在糕殉,可使用beginPath()和moveTo()方法來定義亩鬼。
三次貝塞爾曲線
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
其中,cp1x為第一個控制點的x坐標(biāo)阿蝶;cp1y為第一個控制點的y坐標(biāo)辛孵;cp2x為第二個控制點的x坐標(biāo);cp2y為第二個控制點的y坐標(biāo)赡磅;x為結(jié)束點的x坐標(biāo)魄缚;y為結(jié)束點的y坐標(biāo)。
再來看一張圖片:
由上面可以看出焚廊,三次貝賽爾曲線需要三個點冶匹。前兩個點用于三次貝賽爾計算中的控制點,第三個點是曲線結(jié)束的控制點咆瘟。同上嚼隘,曲線的開始點是當(dāng)前路徑中最后一個點。如果路徑不存在袒餐,可使用beginPath()和moveTo()方法來定義飞蛹。
canvas運用樣式與顏色
色彩
fillStyle=color;
strokeStyle=color;
fillStyle用于設(shè)置填充的顏色谤狡,而strokeStyle用于設(shè)置圖像輪廓的顏色。color可以是表示css顏色值的字符串卧檐、漸變對象或者圖案對象墓懂。默認(rèn)情況下,線條顏色和填充顏色都是黑色的霉囚。
透明度
globalAlpha
globalAlpha = transparencyValue
這個屬性會影響canvas里所有
在設(shè)置透明度后繪制的圖形的透明度捕仔。它的取值區(qū)間是[0.0,1.0]。其中盈罐,0.0表示完全透明榜跌,1.0表示完全不透明。默認(rèn)值是1.0盅粪。
rgba
由于strokeStyle和fillStyle都接受符合css3規(guī)范的顏色值钓葫,所以還可以使用另一種設(shè)置透明度的方法,那就是rgba()方法票顾,它的靈活性更大瓤逼。
線型
lineWidth屬性
lineWidth用于設(shè)置當(dāng)前繪制的線的粗細(xì)。屬性值必須為正數(shù)库物。默認(rèn)值為1.0霸旗。
注意,這里的線寬是指給定路徑的中心到兩邊的粗細(xì)戚揭。換句話說就是:在路徑的兩邊各繪制線寬的一半诱告。
lineCap屬性
屬性lineGap設(shè)置或返回了線條末端
線帽的樣式。
它有三個可選值民晒,分別為:butt精居,這個值是默認(rèn)的,表示向線條的每個末端添加平直的邊緣潜必;round靴姿,表示向線條的每個末端添加圓形線帽;square磁滚,表示向線條的每個末端添加正方形的線帽佛吓。
lineJoin屬性
當(dāng)一個路徑包含了線段或曲線相交的交點時,lineJoin屬性說明如何繪制這些交點垂攘。只有當(dāng)繪制具有等寬線條的時候维雇,這一屬性的效果才能表現(xiàn)出來。
它的可選值有三個晒他,分別是:round吱型、bevel和miter。默認(rèn)值是miter陨仅。
下圖從上往下的三個小圓:
miterLimit屬性
miterLimit 屬性設(shè)置或返回最大斜接長度津滞。
斜接長度指的是在兩條線交匯處內(nèi)角和外角之間的距離铝侵。
注意:只有當(dāng) lineJoin 屬性為 “miter” 時,miterLimit 才有效触徐。
邊角的角度越小咪鲜,斜接長度就會越大。為了避免斜接長度過長锌介,我們可以使用 miterLimit 屬性。
如果斜接長度超過 miterLimit 的值猾警,邊角會以 lineJoin 的 “bevel” 類型來顯示(圖解 3):
語法:
miterLimit=number;
使用虛線
用 setLineDash
方法和lineDashOffset
屬性來制定虛線樣式. setLineDash 方法接受一個數(shù)組孔祸,來指定線段與間隙的交替;lineDashOffset 屬性設(shè)置起始偏移量.
setLineDash([5, 15])
一個跑馬燈的例子:
var ctx = document.getElementById('canvas').getContext('2d');
var offset = 0;
function draw() {
ctx.clearRect(0,0, canvas.width, canvas.height);
ctx.setLineDash([4, 2]);
ctx.lineDashOffset = -offset;
ctx.strokeRect(10,10, 100, 100);
}
function march() {
offset++;
if (offset > 16) {
offset = 0;
}
draw();
setTimeout(march, 20);
}
march();
漸變
線性漸變
createLinearGradient(xStart, yStart, xEnd, yEnd)
線性漸變有四個參數(shù)发皿,其中xStart,yStart為漸變起始點的坐標(biāo)崔慧;xEnd,yEnd為漸變結(jié)束點的坐標(biāo)。
徑向漸變
createRadialGradient(xStart, yStart, radiusStart, xEnd, yEnd, radiusEnd)
徑向漸變有六個參數(shù)穴墅,其中xStart,yStart為開始圓的圓心坐標(biāo)惶室;radiusStart為開始圓的半徑;xEnd, yEnd為結(jié)束圓的圓心坐標(biāo)玄货;radiusEnd為結(jié)束圓的半徑皇钞。
注意,以上兩個方法都沒有為漸變指定任何顏色松捉。使用返回對象的addColorStop()來設(shè)置顏色夹界。要使用一個漸變來勾勒線條或填充區(qū)域,只需要把CanvasGradient對象賦給strokeStyle屬性或fillStyle屬性即可隘世。
addColorStop
addColorStop(offset,color)
offset是一個范圍在0.0到1.0之間的浮點值可柿,表示漸變開始點和結(jié)束點直接的一部分。offset值為0對應(yīng)開始點丙者,offset值為1對應(yīng)結(jié)束點复斥。
使用createPattern創(chuàng)建重復(fù)圖片
語法:createPattern(image, type)
image是圖片,type是圖片的重復(fù)(repeat械媒,repeat-x目锭,repeat-y 和 no-repeat)
創(chuàng)建出一個 pattern 之后,賦給 fillStyle 或 strokeStyle 屬性即可纷捞。
例如:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
// 創(chuàng)建新 image 對象侣集,用作圖案
var img = new Image();
img.src = 'images/wallpaper.png';
img.onload = function(){
// 創(chuàng)建圖案
var ptrn = ctx.createPattern(img,'repeat');
ctx.fillStyle = ptrn;
ctx.fillRect(0,0,150,150);
}
}
canvas填充規(guī)則
當(dāng)我們用到 fill(或者 clip和isPointinPath )你可以選擇一個填充規(guī)則,該填充規(guī)則根據(jù)某處在路徑的外面或者里面來決定該處是否被填充兰绣,這對于自己與自己路徑相交或者路徑被嵌套的時候是有用的世分。
兩個可能值:nonzero(默認(rèn),一般沒用) evenodd
繪制文本
兩種繪制方式
fillText(text,x,y[,maxWidth])
在指定的(x,y)位置填充指定的文本缀辩,繪制的最大寬度是可選的.
strokeText(text, x, y [, maxWidth])
在指定的(x,y)位置繪制文本邊框臭埋,繪制的最大寬度是可選的.
有樣式的文本
font
當(dāng)前我們用來繪制文本的樣式. 這個字符串使用和 CSS font 屬性相同的語法. 默認(rèn)的字體是 10px sans-serif踪央。
textAlign
文本對齊選項. 可選的值包括:start, end, left, right or center. 默認(rèn)值是 start。
textBaseline
基線對齊選項. 可選的值包括:top, hanging, middle, alphabetic, ideographic, bottom瓢阴。默認(rèn)值是 alphabetic畅蹂。
direction
:ltr,rtl
文本測量
measureText()
方法
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var text = ctx.measureText("foo"); // TextMetrics object
text.width; // 16;
}
陰影
shadowOffsetX
shadowOffsetY
shadowBlur
shadowColor
canvas應(yīng)用圖像
可以使用的圖片源
- HTMLImageElemment:這些圖片是由Image()函數(shù)構(gòu)造出來的,或者任何的
<img>
元素 - HTMLVideoElement:用一個HTML的
<video>
元素作為你的圖片源荣恐,可以從視頻中抓取當(dāng)前幀作為一個圖像 - HTMLCanvasElement:可以使用另一個
<canvas>
元素作為你的圖片源液斜。 - ImageBitmap:這是一個高性能的位圖,可以低延遲地繪制叠穆,它可以從上述的所有源以及其它幾種源中生成少漆。
drawImage
drawImage方法有三種狀態(tài)`,下面為最簡單的一種硼被。
第一種
drawImage(img,x,y);
其中示损,img規(guī)定要使用的圖像、畫布或視頻嚷硫;x指在畫布上放置圖像的x坐標(biāo)位置检访;y指在畫布上放置的圖像的y坐標(biāo)位置。
注意:引用圖片可是使用js的new Image()來創(chuàng)建仔掸。這個方法的缺點是脆贵,腳本會因為等待圖片加載而暫停∑鹉海可以使用onload事件丹禀,等圖片加載完再執(zhí)行相應(yīng)的代碼。
例如:
var img = new Image(); // Create new Image object
img.onload = function(){
// 執(zhí)行drawImage語句
}
img.src = 'myImage.png'; // Set source path
第二種:縮放圖片
drawImage(img,x,y,width,height);
img,x,y三個參數(shù)和上面一致鞋怀,新增的兩個參數(shù)分別表示:width双泪,在canvas中圖片要顯示的寬度;height密似,在canvas中圖片要顯示的高度焙矛。
第三種:剪切圖片
drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
它一共有九個參數(shù),分別為:img残腌,源圖片對象村斟;sx,開始剪切的x坐標(biāo)位置抛猫;sy蟆盹,開始剪切的y坐標(biāo)位置;swidth闺金,要剪切的寬度逾滥;sheight,要剪切的高度败匹;x寨昙,剪切后在畫布顯示的x坐標(biāo)位置讥巡;y,剪切后舔哪,在畫布上顯示的y坐標(biāo)的位置欢顷;width,剪切后要顯示的圖片的寬度捉蚤;height抬驴,剪切后要顯示的圖片的高度。
變形 transform
translate(x,y)
rotate(angle)
scale(x,y)
狀態(tài)的保存與恢復(fù)
save()與restore()
save 和 restore 方法是用來保存和恢復(fù) canvas 狀態(tài)的缆巧,都沒有參數(shù)布持。Canvas 的狀態(tài)就是當(dāng)前畫面應(yīng)用的所有樣式和變形的一個快照。
執(zhí)行的步驟:
Canvas狀態(tài)存儲在棧中盅蝗,每當(dāng)save()
方法被調(diào)用后鳖链,當(dāng)前的狀態(tài)就被推送到棧中保存姆蘸。一個繪畫狀態(tài)包括:
當(dāng)前應(yīng)用的變形(即移動墩莫,旋轉(zhuǎn)和縮放,見下)
strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
當(dāng)前的裁切路徑(clipping path)逞敷,會在下一節(jié)介紹
每一次調(diào)用 restore 方法狂秦,上一個保存的狀態(tài)就從棧中彈出,所有設(shè)定都恢復(fù)推捐。
典型的例子就是canvas繪制時鐘
使用clip()裁切路徑
除了之前的stroke與fill裂问,還有一個是clip(),用法語其他兩個一樣牛柒,只是這個是用來裁切的堪簿。注意:裁剪區(qū)域必須放在繪制區(qū)域上面
。
c.arc(0,0,60,0,Math.PI*2,true);
c.fill();
c.clip();
c.fillStyle = "red";
c.fillRect(0,0,150,150);
canvas動畫
動畫的基本步驟
- 清空canvas
- 保存canvas狀態(tài)
- 重繪動畫
- 恢復(fù)canvas
操控動畫
使用
window.setTnterval(function,delay)
window.setTimeote(function,delay)
一般是使用下面這個
window.requestAnimationFrame(callback)