HTML5 Canvas Canvas ,HTML 5中引入它,可以做很多事情:畫圖、動畫、游戲開發等等。本篇就主要講解一下Canvas的基本作圖。 內容摘要 1、Canvas 基礎知識 1.1 Canvas元素 1.2 CanvasRenderingContext2D簡介 2、Canvas 基本作 ...
HTML5 Canvas
Canvas ,HTML 5中引入它,可以做很多事情:畫圖、動畫、游戲開發等等。本篇就主要講解一下Canvas的基本作圖。
內容摘要
1、Canvas 基礎知識
1.1 Canvas 元素
Canvas 中文翻譯為:畫布。
<canvas id=”yourCanvasId” width=”300” height=”150” />
Canvas元素除了公用屬性外,只有兩個額外的屬性:width, height,他們都是沒有單位的,其實單位是px,但是不能寫單位。如果不指定這兩個屬性,預設是width為300,height為150。
眾所周知,html元素的樣式,都可以用css樣式來指定。Canvas也不例外。
<html> <head> <title>Canvas - 01</title> <style> body{ background:#dddddd; }
#canvas{ margin:20px; padding:20px; background:#ffffff; border:thin inset #aaaaaa; width:600px; height:300px; } </style> </head> <body> <canvas id="canvas"> Canvas not supported </canvas> <script type="text/javascript"> var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d");
ctx.font='38pt Arial'; ctx.fillStyle='cornflowerblue'; ctx.strokeStyle='blue'; ctx.fillText("Hello Canvas", canvas.width/2 -150, canvas.height/2 + 15); ctx.strokeText("Hello Canvas stroke", canvas.width/2 -200, canvas.height/2 + 80); </script> </body> </html> |
我們期望的結果是這樣的:
而實際的執行結果:
從執行結果看,它確實一個放大的hello,這是為什麼呢?
其實我認為可以這樣理解它,它是一個放映布,因為真正的繪圖不在它上的,而是在一個繪圖板上,繪圖完畢投影到放映布上。這一點,類似於我們中學時候用過的幻燈片放映機,在一張玻璃板(繪圖板)上寫上習題,然後投影到放映布或者白牆上(畫布)。
所以呢,這樣一想,就明白了,當css樣式中的width,height屬性值與canvas元素的width,height的屬性值不同時,會自動的將繪圖板上的內容進行縮放到畫布上。
Canvas 元素目前有三個方法:
通過getContext(“2d”);能夠取得CanvasRenderingContext2D對象,然後就可以基於此上下文對象來作2d圖了
通過getContext(“3d”);就可以進行3d作圖,3d作圖底層用的是WebGL。
1.2 CanvasRenderingContext2D簡介
2、基本作圖
2.1、線條
使用Canvas作圖時,預設情況下是有這樣一個坐標軸的:
在使用canvas作圖時,需要按照一定的順序來編寫代碼。
1)直線(Line)
要畫一條線,代碼編寫過程一般是這樣的:
Ctx.beginPath(); // 聲明要開始一條線
Ctx.moveTo(x,y);// 指定線的起點。moveTo,就像是將畫筆移動到某個點。
Ctx.lineTo(x,y);// 指定線的終點
Ctx.lineCap=”round”;// 設置線的兩端(線帽),可選值有:butt,round,square。
Ctx.lineWidth=15;// 指定線的寬度
Ctx.strokeStyle=”#ff0000”;// 設置線的顏色,不設置則根據當前顏色。預設是黑色。
Ctx.stroke(); // 開始描邊
2)曲線(Curves)
使用canvas可以做的曲線主要包括:圓弧、bezier曲線、quadratic曲線。
2.1) 圓弧(arc)
要做一條圓弧,編碼的順序一般是這樣的:
Ctx.beginPath(); // 聲明要開始一條新的path。
Ctx.arc(x,y,radius,startAngle,endAngle,antiClockwise); //指定弧線path
Ctx.lineWidth=15;// 指定線的寬度
Ctx.strokeStyle=’black’; // 指定線的顏色
Ctx.lineCap=”square”;// 指定線帽
Ctx.stroke();// 開始描邊
在做圓弧時,最主要的就是ctx.arc。
該方法的參數列表:
參數 |
描述 |
x |
圓的中心的 x 坐標。 |
y |
圓的中心的 y 坐標。 |
r |
圓的半徑。 |
startAngle |
起點的弧值。(弧的圓形的三點鐘位置是 0 度)。 |
endAngle |
終點的弧值。 |
antiClockwise |
是否逆時針繪圖,可選。False = 順時針,true = 逆時針。 |
這裡用的是弧度,不是角度。可能大家對角度都比較熟悉。
從起點,按照順時針(或者逆時針)方向轉一周,是360度(角度)。
如果以弧度來表示,則是按照順時針(或者逆時針)方向轉一周,弧度是 2*PI。
既然這裡要求的是弧度值,大家熟悉的是角度,那麼怎麼將角度轉換為弧度呢?
假定 f(x) => 360x = 2*PI 可以很容易推導出x=PI/180。也就是1度(角度)=PI/180弧度。
那麼90o = 90 * PI /180= 0.5 PI; 180o = PI; 360o = 2*PI。
下圖是一張按照順時針轉動的弧度:
2.2)二次方曲線(quadratic curves)
二次方曲線,也稱為拋物線。
維基百科時有關二次方曲線的描述:
https://en.wikipedia.org/wiki/Quadratic_function
Ctx.beginPath(); // 開始畫線
Ctx.moveTo(x,y);// 起點
Ctx.quadraticCurveTo(cx,cy,ex,ey);// 指定要畫拋物線
Ctx.lineWidth=12; // 指定線寬頻
Ctx.strokeStyle=”black”;// 指定線顏色
Ctx.lineCap=’butt’; // 指定線帽
Ctx.stroke(); // 開始描邊
其中quadraticCurveTo(cx,cy,ex,ey)前兩個參數表示控制點坐標,後兩個參數表示終點坐標。
下麵是一個demo:
2.3)三次方曲線(Bezier Curve)
Quadratic curve 有一個控制點,而Bezier curve 有兩個控制點。
指定畫bezier曲線的方法是:
Ctx.bezierCurveTo(c1x,c1y, c2x, c2y, ex, ey);
3) Path
在畫line,curve時,我們都用beginPath()來表示要啟動一條path,然後進行畫直線或者曲線。其實可以將他們串連起來。
在多條線串聯的地方,稱為lineJoin,它有三種形式:
4) 矩形(rectangle)
4.1 繪製矩形
繪製矩形,有兩種方式:
Ctx.rect(x,y, width, height);
Ctx.strokeRect(x,y,width, height);
區別是第一種需要beginPath(),第二種不需要。
4.2 填充矩形
繪製並填充矩形。
Ctx.fillRect(x,y,width, height);
4.3 清理rect
會把指定矩形內的內容全部清空。
Ctx.clearRect(x,y,widht, height);
5) 線條樣式
從圖上很容易看出來,butt,round,square的區別來。
2.2、文本
2.1 文本樣式
在css中,設置問題的屬性有:
然而並不能通過css style設定canvas中文本的樣式。
Canvas中的text有自己的一套設置格式:
Ctx.font=”${font-style} ${font-size} ${font-family}” // 指定文本樣子,大小,字體
Ctx.fillStyle=”blue” ;// 指定文本顏色
Ctx.textAlign=”center”; // 指定水平方向上的對齊方式
Ctx.textBaseline=”middle” 指定豎直方向上的對齊方式
Ctx.strokeStyle=”blue”; // 指定文本stroke顏色
2.2 填充文本
Ctx.fillText(text, x, y);
在canvas中填充的文本,是不會自動折行的,所以如果文本太長的話,需要自己控制折行顯示。
2.3、圖像、視頻
在canvas加入圖像、畫布、視頻,,使用drawImage即可。在將圖像、畫布、視頻放到canvas時,可以整體放入,也可以剪切後放入。在使用API時,也有三種用法:
假設要添加的圖像、畫布、視頻為源:
1)drawImage(img,x,y);
將源放到canvas的x,y處。
2)drawImage(img,x,y,width,height);
將源放到x,y處,並將源以width,height的尺寸來縮放顯示。
3)drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
將源從sx,sy出開始截取swidth,sheight的內容,然後縮放到width,height的尺寸,放到canvas的x,y處。
Image:要使用的圖片、畫布、視頻
Sx,sy:從源的sx,sy坐標處剪切
Swidth,Sheight:源的寬,高
X,y:放到canvas的x位置
2.4、填充樣式
在填充時,可以有三種填充方式:
·color 填充為某種顏色
·gradient 填充為漸變顏色
·按pattern進行填充(使用它可以填充圖片)
http://www.w3school.com.cn/tags/canvas_fillstyle.asp
3、坐標平移、轉換、旋轉
預設情況下,坐標原點是在Canvas的左上角。有時我們需要移動坐標軸、或者xy軸轉換來進行操作。
3.1 translate 平移坐標軸
該方法是對坐標軸平移。
在執行完 translate後,坐標軸原點位置由原來的 (0,0)變為原來的(70,70)。之後的作圖,就以新的坐標原點為(0,0)。
那麼想要再將坐標原點重置,則需要將坐標軸再進行平移。
Translate(tx,ty),實際在作圖(點,線,面)時,會對grid內每一個要做圖點,基於(tx,ty)進行平移運算。這個其實是向量運算。也可以看作是矩陣加運算。
(x,y) 經過 (tx, ty) 平移後的點的計算,使用矩陣運算就是:
[ x ] + [tx] => [x+tx]
[ y ] [ty] [y+ty]
3.2 scale 縮放
scale(xPercent, yPercent) 參數是x,y軸的縮放百分比。 大於1是放大,小於1是縮小。
假設預設是 1個長度占用1個像素。假設畫一條長度為 10的直線,就是占用10個像素。
使用scale放大到200%後,畫一條長度為 10的直線,就是占用20個像素。
也就是縮放的是坐標軸的長度。
[x,y] s [sx, sy] => [sx*x + sy * y]
3.3 rotate 旋轉
該方法是對坐標軸旋轉。
rotate(angle)參數是弧度。之前已經說過了,1度(角度)=PI/180弧度,那麼假設你想轉90o,那麼應該是rotate(90 * Math.PI/180 )。
3.3 transform 變換
transform(xs,xr,yr,ys,xt,yt) 該方法是對坐標系進行平移、縮放、旋轉的綜合的操作。
xs:x軸縮放
xr:x軸旋轉
yr:y軸旋轉
ys:y軸縮放
xt:y軸平移
yt:y軸平移