如何創造一個畫布呢?javascript
首先在html頁面中聲明html
<canvas id='canvas'></canvas>java
而後再js中獲取這個標籤canvas
var canvas = document.getElementById('canvas');ide
var context =canvas.getContext('2d');函數
//使用context進行繪製spa
1.首先從繪製直線說提及code
canvas.htmlhtm
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>canvas詳解</title> <script src="canvas.js"type="text/javascript"></script> </head> <body> <canvas id="canvas" style="border:1px solid black;margin:300px"></canvas> </body> </html>
canvas.jsblog
/** * Created by Administrator on 2016/9/26. */ window.onload=function(){ var canvas = document.getElementById('canvas'); canvas.width = 500; canvas.height = 500; var context = canvas.getContext('2d'); context.moveTo(100,100); context.lineTo(400,400); context.lineWidth =5; context.strokeStyle ='#058' context.stroke(); }
canvas是一種基於狀態的繪製,因此先設置狀態
context.moveTo(100,100);設置從哪裏開始繪製 context.lineTo(400,400);//設置繪製到什麼位置 context.lineWidth =5;線段的寬度 context.strokeStyle ='#058'設置繪製的顏色
context.stroke()繪製線段;
如何畫折線
context.moveTo(100,100); context.lineTo(400,400); context.lineTo(400,100);//多加一條就能夠畫出折線,這時會鏈接(400,400)到(400,100) context.lineWidth =5; context.strokeStyle ='#058' context.stroke();
在看下面的一個例子
context.moveTo(100,200); context.lineTo(300,400); context.lineTo(100,600); context.moveTo(300,200); context.lineTo(500,400); context.lineTo(300,600); context.moveTo(500,200); context.lineTo(700,400); context.lineTo(500,600); context.lineWidth =5; context.strokeStyle ='#058' context.stroke();
結果:
moveTo表示的是把畫筆放在什麼位置,lineTo表示畫到什麼位置
canvas陷阱
context.moveTo(100,200); context.lineTo(300,400); context.lineTo(100,600); context.strokeStyle ='red' context.stroke(); context.moveTo(300,200); context.lineTo(500,400); context.lineTo(300,600); context.strokeStyle ='blue' context.stroke(); context.moveTo(500,200); context.lineTo(700,400); context.lineTo(500,600); context.lineWidth =5; context.strokeStyle ='green' context.stroke();
這個時候繪製的不是三條不一樣顏色的線,而是三種顏色相同的線段,由於canvas是基於狀態的繪製,因此每次stroke時都會把以前因此的狀態繪製一邊,因此最後的顏色是green
如何解決這個bug呢
此時就要引入beginPath(),這個表示的是重新開始繪製,此時開始一條新的路徑
context.beginPath() context.moveTo(100,200); context.lineTo(300,400); context.lineTo(100,600); context.lineWidth =5; context.strokeStyle ='red' context.stroke(); context.beginPath() context.moveTo(300,200); context.lineTo(500,400); context.lineTo(300,600); context.lineWidth =5; context.strokeStyle ='blue' context.stroke(); context.beginPath() context.moveTo(500,200); context.lineTo(700,400); context.lineTo(500,600); context.lineWidth =5; context.strokeStyle ='green' context.stroke();
此時繪製的是三條不一樣顏色的線段
還有注意一下beginPath()下面的moveTo能夠改成lineTo
如何實現封閉線
context.beginPath(); context.lineTo(100,350); context.lineTo(500,350); context.lineTo(500,200); context.lineTo(700,400); context.lineTo(500,600); context.lineTo(500,450); context.lineTo(100,450); context.lineTo(100,350); context.lineWidth =5; context.strokeStyle ="#58"; context.stroke();
這樣就連成一條封閉的圖形
可是放大後能夠看出最後鏈接處有點小瑕疵
如何避免這種問題呢
其實若是要繪製封閉的圖形,最標準的方法是最後還要加上context.closePath(),這樣就會把鏈接處的問題處理掉。
此外如何你用了closePath()的話,最有一句lineTo()寫不寫無所謂的,由於他會自動幫你封閉起來。
填充色
如何給封閉的圖形填充顏色呢?
context.lineWidth =10; context.strokeStyle ="#58"; context.fillStyle ='yellow'; context.fill(); context.stroke();
經過fillStyle ,fill()就能夠給封閉的圖形填充相應的顏色,此外,千萬要注意一點就是,若是咱們把fill()寫在stroke()的後面的話,此時邊框雖然爲10px可是內部的5px被填充色給覆蓋了,因此要將stroke放在fill後面
編寫繪製矩形的函數
var canvas = document.getElementById('canvas'); canvas.width = 800; canvas.height = 800; var context = canvas.getContext('2d'); DrawRect(context,100,100,300,300,10,'red','blue') function DrawRect(txt,x,y,width,height,strokeWidth,strokeStyle,fillStyle){ txt.beginPath() txt.lineTo(x,y); txt.lineTo(x+width,y); txt.lineTo(x+width,y+height); txt.lineTo(x,y+height); txt.closePath(); txt.strokeStyle =strokeStyle; txt.fillStyle =fillStyle; txt.lineWidth = strokeWidth; txt.fill(); txt.stroke(); }
其實canvas中有專門的繪製矩形的藉口
rect(x,y,width,height);//這一句話是給出了矩形的狀態,至關於
txt.lineTo(x,y);
txt.lineTo(x+width,y); txt.lineTo(x+width,y+height); txt.lineTo(x,y+height);
txt.beginPath() txt.rect(x,y,width,height); txt.closePath(); txt.strokeStyle =strokeStyle; txt.fillStyle =fillStyle; txt.lineWidth = strokeWidth; txt.fill(); txt.stroke();
還有兩種方法:fillRect(x,y,width,height);strokeRect(x,y,width,height);
這兩種方法不只定義了狀態了實現了繪製。
txt.strokeStyle =strokeStyle; txt.fillStyle =fillStyle; txt.lineWidth = strokeWidth; txt.fillRect(x,y,width,height); txt.strokeRect(x,y,width,height);
線條的屬性
對於線條的屬性:lineWidth就是其中一個,其次接着講lineCap字面的意思是線條的帽子,也就是線條結尾處和開始出的形狀(即便是折線也只會在整個線段的開始和結尾處添加,折線處不會)
lineCap有三個取值:butt(default) , round(圓形), square(正方形),注意對於round和square來講,是在原來的基礎上添加的,也就是線段會變長。
小小例子-----繪製五角星
如何繪製一個小小的五角星來着
如何實現狀態的鏈接呢?
function DrawStar(txt,R,r,x,y,rot){ txt.beginPath() for(var i=0;i< 5;i++){ txt.lineTo(Math.cos((18 + 72*i - rot)/180 * Math.PI ) * R + x, -Math.sin((18+ 72 * i - rot)/180 * Math.PI) * R+ y); txt.lineTo(Math.cos((54 + 72 * i - rot)/180 * Math.PI) * r + x, -Math.sin((54+ 72*i - rot)/180 * Math.PI) * r + y); } txt.closePath(); }
這樣就能夠實現
具體代碼
window.onload=function(){ var canvas = document.getElementById('canvas'); canvas.width = 800; canvas.height = 800; var context = canvas.getContext('2d'); context.lineWidth =5; DrawStar(context,300,150,400,400,30); context.stroke(); } function DrawStar(txt,R,r,x,y,rot){ txt.beginPath() for(var i=0;i< 5;i++){ txt.lineTo(Math.cos((18 + 72*i - rot)/180 * Math.PI ) * R + x, -Math.sin((18+ 72 * i - rot)/180 * Math.PI) * R+ y); txt.lineTo(Math.cos((54 + 72 * i - rot)/180 * Math.PI) * r + x, -Math.sin((54+ 72*i - rot)/180 * Math.PI) * r + y); } txt.closePath(); }
線條屬性之lineJoin
這個屬性表示的線條鏈接時的狀態
默認有三個取值(miter,bevel,round)默認值是miter表示尖角,會一直延伸到兩條先交到一塊兒。
還有一個屬性miterLimit,這個屬性只有當lineJoin選擇miter的時候纔有效,表示的是鏈接線的內接點與外接點的距離。
fillStyle屬性:注意這個屬性不光光能夠設置顏色,還能夠設置漸變色,如何設置漸變色呢?(漸變色分爲線性漸變色,和徑向漸變色)
首先以線性漸變色爲例子來講
第一步:var grd =context.createLinearGradient(xstart,ystart,xend,yend);
第二步:grd.addColorStop(stop,color);其中stop表示的是位置(值取0-1之間);
var linearGrad = context.createLinearGradient(0,0,800,800); linearGrad.addColorStop(0.0,'#FFF'); linearGrad.addColorStop(1.0,'#000'); context.fillStyle =linearGrad;
其中
addColorGradient能夠取不少,此外若是沒有在整個畫布內漸變的話,剩餘的部分會以最後的顏色填充。此外咱們開始漸變的位置和結束的位置能夠超出畫布的部分
2, 徑向漸變
步驟一:var grd = context.createRadiaGradient(x,y,r1,x,y,r2);
步驟二: grd.addColorStop(0.0,'white');
grd.addColorStop(0.25,'yellow');
grd.addColorStop(0.5,'green');
grd.addColorStop(0.75,'blue');
grd.addColorStop(1.0,'block')
context.fillStyle = grd;
漸變色在第一個圓與第二個圓之間漸變。
3.重點注意
createPattern(img,repeat-style);
repeat-style:no-repeat;
repeat-x;
repeat-y;
repeat
具體實現:
var backgroundImage =new Image(); backgroundImage.src ='1.jpg'; backgroundImage.onload = function(){ var pattern = context.createPattern(backgroundImage,'repeat'); context.fillStyle = pattern; context.fillRect(0,0,800,800); }
此外createPattern(canvas,repeat-style)不只能夠引入圖片,也可讓另一個畫布做爲背景);
還能夠creatPattern(video,repeat-style);
繪製圓弧
context.arc(centerX,centerY,radius,startingAngle,endindAngle,anticlockwise=false)
參數的意思:圓心的X座標,Y座標,起點角度,終點角度,是否順時針(默認狀況下是順時針);
此時不管是順時針仍是逆時針,角度都是不變的,好比逆時針的話,0.5pi是在下面的那個位置如圖所示,而不是上面的1.5pi位置
第二種繪製弧線的方法:arcTo(x1,y1,x2,y2,radius);
這個方法是如何繪製弧線的呢?
其實他是以最近的moveTo或者lineTo爲起點,而後鏈接(x1,y1)和點(x2,y2)造成一個折線,而後以(x0,y0)爲起點,相切於這兩條線的弧線就是咱們要繪製的弧線,此外,弧線的終點不必定是(x2,y2);此外(x0,y0)也不必定是切點,千萬要注意了。
二次貝塞爾曲線其實貝塞爾曲線跟arcTo差很少,可是也有區別首先也是以最近的一個moveTo或者lineTo爲起點開始的,context.moveTo(x0,y0);context.quadraticCurveTo(x1,y1,x2,y2);區別在於曲線是以(x0,y0)爲起點的,以(x2,y2)爲重點的,而且相切於這兩個點。三次貝塞爾曲線,context.move(x0,y0)context.bezierCurveTo(x1,y1,x2,y2,x3,y3);此時原理仍是同樣,只不過這時候控制點就是(x1,y1),(x2,y2);