html5 canvas
html5中的<canvas>標簽是一個可以使用js腳本在其中繪圖的html元素。有強大的API,可用於制作照片集或制作簡單的動畫。有人說canvas是html5的精髓。
一、基本用法
1、初始畫布
一般會拿<canvas>和<img>對比,因為它畫出來也是張圖片,但實際上沒什麽可比性。canvas只有width和height屬性,而且還是可選的。如果沒有給canvas樣式和寬高,則它是透明的,默認大小為300px*150px;可通過css設置,有時候面試題會問anvas的默認大小是多少?。
畫筆默認顏色是黑色。
舉例:初始畫布
給canvas加上邊框,就可以清楚的看到初始畫布大小:300px*150px
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Canvas</title> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="myCanvas"></canvas></body> </html>
渲染過程圖片會縮放以適應布局大小。如果圖片的寬高比和canvas的不同,可能會出現變形。
Note:如果圖片出現變形,在<canvas>標簽中直接設置寬高,而不要在css中設置。
2、後備內容
<canvas>可以像<video>,<audio>或者<picture>元素一樣,在不支持它的瀏覽器中給一些後備內容(fallback content)。
後備內容寫在<canvas></canvas>之間的內容,不支持canvas的瀏覽器忽略canvas渲染裏面的內容,支持canvas的瀏覽器忽略後備內容,正常渲染canvas。
所以在低版本瀏覽器最好給出一些後備內容描述canvas的內容,可以是文字或者圖片。
Note:也是因為後備內容的關系,必須有</canvas>閉合標簽,否則後面所以內容會被當成後備內容,在瀏覽器支持canvas時不顯示。
3、渲染上下文
canvas有一個固定大小的畫布,可以有一個或多個渲染上下文,用來創建和操作繪圖。現在只關註2d渲染上下文。 WebGL用的是3d渲染上下文。
getContext("2d") 對象是內建的 HTML5 對象,擁有多種繪制路徑、矩形、圓形、字符以及添加圖像的API。
一個畫布初始是空白的,要想作畫,首先腳本要獲取渲染上下文才能在畫布上作畫。<canvas>元素通過getContext()
來獲取一個渲染上下文,和畫圖方法。getContext()有一個參數,2d畫圖只需要一個"2d"即可獲取一個 CanvasRenderingContext2D
。
所以畫圖首先需要的就是兩步:
var canvas=document.getElementById(‘myCanvas‘); var ctx=canvas.getContext(‘2d‘);
舉例:一個簡單的例子
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Canvas</title> <style type="text/css"> canvas { border: 1px solid black; } </style> </head> <body> <canvas id="myCanvas" width="150" height="150"></canvas> <script type="text/javascript"> var canvas=document.getElementById("myCanvas"); 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); </script> </body> </html>View Code
二、繪制圖形
通過基本用法我們已經可以畫簡單的圖了,使用canvas主要是要掌握幾個畫圖方法,現在深入了解一下。
1、canvas坐標
默認情況:1個格子對應1px,從(0,0)開始。
我們可以通過一些手段平移坐標起點,旋轉甚至縮放網格。現在就以默認情況介紹。復雜的圖都是由簡單的組合來的,現一一介紹。
2、畫矩形
三個函數:
fillRect(x, y, width, height)
:畫一個填充矩形
strokeRect(x, y, width, height)
:畫矩形輪廓。【stroke英文意思是“筆畫”,所以看到的是落筆與起筆之間的筆畫】
clearRect(x, y, width, height)
:清除指定的矩形區域,使其完全透明。類似橡皮擦。
參數含義都一樣:x,y表示相對origin【默認就是相對左上角】的一個畫圖起點,width,height就是矩形的大小。
舉例:
ctx.fillRect(25,25,100,100);//畫一個黑色最大填充矩形 ctx.clearRect(45,45,60,60);//擦除一塊中等大小透明矩形 ctx.strokeRect(50,50,50,50);//畫一個小矩形輪廓
3、繪制路徑
這裏路徑指的是很多被線段連接起來的點,可以有不同的形狀,完全,顏色和粗細。
繪制路徑步驟:
a、創建path
b、使用 drawing commands 繪制路徑
c、閉合路徑
d、渲染路徑
用到的函數:
beginPath()
:創建一個新的路徑,之後的繪圖命令直接作用於於該路徑。
Path methods:該方法為對象設置不同的路徑。
closePath()
:關閉路徑,很重要,讓之後的繪圖命令再次回到上下文。
stroke()
:繪制路徑輪廓。
fill()
:填充路徑。
Note:調用了fill()方法後,一些打開的shapes自動關閉,而調用stroke卻不會自動關閉。下面舉例來說明這點。
舉例:畫三角形,stroke不會自動閉合,fill自動閉合。
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); var path=new Path2D(); path.moveTo(75,50); path.lineTo(100,75); path.lineTo(100,25); // ctx.stroke(path); ctx.fill(path); </script>
分析:可見stroke不會自動閉合路徑,我們可以通過stroke看到繪制路徑的過程。
4、移動畫筆Moving the pen
移動畫筆指的是一個上面例子中用到的一個函數——moveTo(x,y)。
初始化一張畫布,首先就是舉起畫筆移動到要作畫的位置,就是要用moveTo(x,y)函數。
可以類比一下moveTo就相當於在空中畫線,不會在畫布上留下任何痕跡,延伸一下,我們就知道可以用moveTo來畫一些獨立路徑。
舉例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); var path=new Path2D(); path.arc(75,75,50,0,Math.PI*2,true);//外部圓圈 path.moveTo(110,75); path.arc(75,75,35,0,Math.PI,false); //順時針畫半個圓做嘴巴 path.moveTo(65,65); path.arc(60,65,5,0,Math.PI*2,true);//左眼 path.moveTo(95,65); path.arc(90,65,5,0,Math.PI*2,true);//右眼 ctx.stroke(path); </script>
5、畫線
畫線用LineTo(x,y)函數,表示從當前位置畫一條到左邊(x,y)的線,起點可通過moveTo()函數重置。
舉例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); //填充三角形 var ftriangle=new Path2D(); ftriangle.moveTo(25,25); ftriangle.lineTo(105,25); ftriangle.lineTo(25,105); ctx.fill(ftriangle); //三角形輪廓 var striangle=new Path2D(); striangle.moveTo(125,125); striangle.lineTo(125,45); striangle.lineTo(45,125); striangle.closePath(); //顯示閉合路徑 ctx.stroke(striangle); </script>
5、弧線
畫弧和畫圓都用arc()或arcTo()函數。
arc(x,y,radius,startAngle,endAngle,acticlockwise)
畫弧,弧心為(x,y),半徑為radius,起始弧為startAngle,終止弧到endAngle,方向按照anticlockwise來畫。【clockwise意思是“順時針”,加了anti-前綴就是逆時針,所以默認是逆時針畫弧,可通過true和false來控制】
arcTo(x1,y1,x2,y2,radius)
arcTo()在畫布上創建介於兩個切線之間的弧/曲線。
6、曲線
貝塞爾曲線:
bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
二次曲線:
quadraticCurveTo(cp1x, cp1y, x, y)
(cp1x,cp1y)--控制點 此函數表示從當前的畫筆位置到(x,y)畫一條二次曲線
var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); ctx.beginPath(); ctx.moveTo(20, 20); ctx.quadraticCurveTo(20, 100, 200, 20); ctx.stroke();
Note:二次貝塞爾曲線需要兩個點。第一個點是用於二次貝塞爾計算中的控制點,第二個點是曲線的結束點。曲線的開始點是當前路徑中最後一個點。如果路徑不存在,那麽請使用 beginPath() 和 moveTo() 方法來定義開始點。
- 開始點:moveTo(20,20)
- 控制點:quadraticCurveTo(20,100,200,20)
- 結束點:quadraticCurveTo(20,100,200,20)
三、樣式和顏色
主要是美化作用, 畫線時添加不同顏色,線型,漸變,模式和陰影。
1、顏色
應用顏色用到兩個重要屬性:fillStyle和strokeStyle。
fillStyle=color:填充色。
strokeStyle=color:輪廓色。
//設置橘色的不同寫法
ctx.fillStyle = "orange";
ctx.fillStyle = "#FFA500";
ctx.fillStyle = "rgb(255,165,0)";
ctx.fillStyle = "rgba(255,165,0,1)";
fillStyle取值color可以是普通顏色或一個漸變圖片。
用的時候註意,想換種顏色就必須再次調用fillStyle或strokeStyle屬性。
fillStyle舉例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); for(var i=0;i<6;i++){ for(j=0;j<6;j++){ ctx.fillStyle=‘rgb(‘+Math.floor(255-42.5*i)+‘,‘+Math.floor(255-42.5*j)+‘,0)‘; ctx.fillRect(j*25,i*25,25,25); } } </script>
strokeStyle舉例:
<script type="text/javascript"> var canvas=document.getElementById("myCanvas"); var ctx=canvas.getContext("2d"); for(var i=0;i<6;i++){ for(j=0;j<6;j++){ ctx.strokeStyle=‘rgb(‘+Math.floor(255-42.5*i)+‘,‘+Math.floor(255-42.5*j)+‘,0)‘; ctx.beginPath(); ctx.arc(12.5+j*25,12.5+i*25,10,0,Math.PI*2,true); ctx.stroke(); } } </script>
如果只是修改上例中fillStyle和fillRect為strokeStyle和strokeRect,效果如上圖左。
改為畫圓的方式,效果如上圖右。
要畫半透明圖時,需要用到一個屬性:globalAlpha
globalAlpha=trnaparencyVlaue。
這是個全局屬性,對所有元素都起作用,要在局部圖形使用透明度,可給fillStyle或strokeStyle賦值raba顏色。
2、線型
lineWidth:線寬。可選值:number,當前線條的寬度,單位px。
lineCap:線帽,即線段終點樣式。可選值:butt默認,向線條的每個末端添加平直的邊緣;round,向線條的每個末端添加圓形線帽;square向線條的每個末端添加正方形線帽。
lineJoin:兩條線段交匯時,邊角的類型。可選值:bevel斜角,round圓角,miter默認尖角。
miterLimit:miterLimit 屬性設置或返回最大斜接長度。只有當 lineJoin 屬性為 "miter" 時,miterLimit 才有效。
可選值:number,正數,規定最大斜接長度,如果斜接長度超過 miterLimit 的值,邊角會以 lineJoin 的 "bevel" 類型來顯示(Fig 3)。
getLineDash():獲取當前線段樣式,返回一個 Array
數組。一組描述交替繪制線段和間距(坐標空間單位)長度的數字。如果數組元素的數量是奇數,數組元素會被復制並重復。 例如, 設置線段為 [5, 15, 25]
將會得到以下返回值 [5, 15, 25, 5, 15, 25]。
3、漸變
四、使用圖片
五、轉換
六、合成
七、基本動畫 優化canvas。
本文作者starof,因知識本身在變化,作者也在不斷學習成長,文章內容也不定時更新,為避免誤導讀者,方便追根溯源,請諸位轉載註明出處:http://www.cnblogs.com/starof/p/4596759.html 有問題歡迎與我討論,共同進步。
寫於2015-06-24 08:54
html5 canvas