canvas學習(一)

weixin_33782386發表於2016-06-08

簡介:

canvas是html5最重要的元素,提供了一個畫布的功能,有強大的圖形處理能力

2036150-cc335a9e646d54b8.jpg
思維導圖

canvas標籤新增

要使用canvas,首先要在body中新增上canvas標籤

canvas標籤是一塊預設300*150大小的畫布

畫布寬高設定:

使用canvas標籤的屬性,width及height直接在行間設定

此處注意:不要用css樣式去改畫布大小,這個會導致畫布中的影像被拉伸

<canvas id="canvas1" width="800" height="500"></canvas>

畫布css樣式

畫布的其他css樣式可以正常設定

canvas標籤中的內容
canvas標籤中的內容是(包括標籤)只有在不支援此效果的低版本瀏覽器中才會顯示的;在高版本瀏覽器中不會顯示出來

<canvas id="canvas1" width="800" height="500">
    只是一個canvas標籤,然而你看不到
</canvas>

獲取canvas標籤及上下文

canvas標籤使用js正常dom節點的獲取方法獲取

var canvas = document.getElementById('canvas1');

上下文是記錄canvas執行命令語句的地方,獲取如下,後面的引數現在只有2d可選

var context = canvas.getContext('2d');

canvas座標系

左上角是00點,x軸正方向向右,y軸正方向向下

2036150-257c6e062a75a863.jpg

樣式設定

邊框設定:context.strokeStyle
填充設定:context.fillStyle
線寬設定:context.lineWidth

context.strokeStyle = "red";
context.lineWidth = 2;
context.fillStyle = 'yellow';

繪製圖形

繪製命令
  1. 邊框式繪製:context.stroke();
  2. 填充式繪製:context.fill();
新建路徑beginPath()

這個方法代表重新開始一段路徑,也可以理解為新建一個圖層
這個的方法之後執行的繪製動作,不會執行到這個方法之前的命令

context.beginPath();
繪製直線:
  1. 設定畫筆開始位置:context.moveTo(x,y)
  2. 設定畫筆結束位置:context.lineTo(x,y)
  3. 線段兩邊圓角:context.lineCap = "round"

context.strokeStyle = "red";
context.lineWidth = 2;
context.moveTo(100,100);
context.lineTo(500,100);
context.stroke();
2036150-0552904a160960db.jpg
繪製三角:方法就是繪製3條直線

繪製多條連續線段時,不必每次重新定義起始點
畫筆會停在上一段線段的終點,並預設為下一次繪製的起始點

context.strokeStyle = "red";
context.lineWidth = 2;

context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.lineTo(10,10);
context.stroke();

注意,此處用繪製直線的方法,進行圖形的繪製時;直線封閉處會出現瑕疵,不會完全閉合


2036150-59991ba466a5aa9e.jpg

2036150-af5a3aa504013d5e.jpg
閉合方法:context.closePath()

加上上面的閉合命令後,閉合處的瑕疵就會被修復
這個方法會自動將起點與末點相連,所以不必再將路徑回到起始點

context.strokeStyle = "red";
context.lineWidth = 2;

context.beginPath();
context.moveTo(10,10);
context.lineTo(10,110);
context.lineTo(110,110);
context.closePath();  //封閉路徑後最後一個點就不用定義了
context.stroke();
2036150-a729a9021461f376.jpg

2036150-835a33f84a69caf0.jpg
繪製矩形

定義矩形:context.rect(x,y,w,h);

  1. x:起始位置x座標(矩形左上角)
  2. y:起始位置y座標(矩形左上角)
  3. w:矩形寬
  4. h:矩形高

直接繪製:省去了定義矩形的步驟,按照定義的樣式直接填充或描邊

context.fillRect(x,y,w,h)
context.strokeRect(x,y,w,h)

橡皮擦功能:clearRect(x,y,w,h)

  1. 擦除矩形範圍之內的內容
  2. 常用來擦除整個畫布以實現動畫效果
圖形繪製方式

邊框式繪製:

context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();
2036150-81cca4973b65b207.jpg

填充式繪製:

context.fillStyle = 'yellow';
context.rect(150,150,200,100);
context.fill();
2036150-a8b52dca2548eea6.jpg
填充+描邊同時使用注意:

這兩個效果同時使用時,先後順序的不同會導致效果的差異

一般是在填充後再去描邊,如下效果

context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.fill();
context.stroke();
2036150-30185676a501faca.jpg

如果是描邊後再填充的話,填充效果會遮擋一半的邊框

//線寬被遮擋一半
context.strokeStyle = "red";
context.lineWidth = 2;
context.rect(150,150,200,100);
context.stroke();
context.fill();
2036150-81b82a74f1f6ecf8.jpg
繪製弧形

常用方法:context.arc(x,y,r,θ1,θ2,boolean)

  1. x:中心點x座標
  2. y:中心點y座標
  3. r:圓半徑
  4. θ1:起始角度
  5. θ2:結束角度
  6. 布林值:false逆時針(預設),true順時針

//畫弧線
context.strokeStyle = "red";
context.lineWidth = 2;
context.arc(300,100,100,0,Math.PI/2,true)
context.stroke();
2036150-ee0a1110ce8d25cc.jpg
//畫圓
context.beginPath();
context.arc(300,200,100,0,Math.PI*2,true)
context.stroke();
2036150-63238cf83c6c0a21.jpg
繪製文字

設定文字樣式:context.font = 'italic size family'

  1. italic:斜體
  2. size:字型大小
  3. family:字型

設定文字內容:context.strokeText("text",x,y)

  1. "text":中文字內容
  2. x:起始x座標
  3. y:起始y座標

context.lineWidth = 1;
context.strokeStyle = "green";
context.font = "italic 150px arial"
context.strokeText("我是文字",50,200);
2036150-a1fdf2d49e8b9c72.jpg
漸變樣式

線性漸變:createLinearGradient(x1,y1,x2,y2)

  1. x1/y1:漸變起始位置座標
  2. x2/y2:漸變結束位置座標

徑向漸變:createRadiusGradient(x1,y1,r1,x2,y2,r2)

  1. x1/y1:漸變起始圓的圓心位置座標
  2. r1:漸變起始圓半徑
  3. x2/y2:漸變結束圓的圓心位置座標
  4. r2:漸變結束圓半徑

漸變顏色設定:addColorStop(%,"color");

  1. %:漸變進度,用[0,1]之間的數字表示
  2. "color":每個漸變階段的顏色

var linearGradient = context.createLinearGradient(100,300,800,500);

linearGradient.addColorStop(0,"red");
linearGradient.addColorStop(0.4,"yellow");
linearGradient.addColorStop(0.8,"green");
linearGradient.addColorStop(1,"blue");

context.fillStyle = linearGradient;

context.font = "italic 150px arial"
context.fillText("我是文字",50,200);
2036150-edbe89cf2ad2ba14.jpg
繪製陰影

陰影顏色:shadowColor = "color";
陰影模糊度:shadowblur = number;
陰影偏移X:shadowOffsetX = number;
陰影偏移Y:shadowOffsetY = number;

context.shadowColor = "black";
context.shadowBlur = 20;
context.shadowOffsetX = 10;
context.shadowOffsetY = 5;

context.strokeRect(100,100,100,100);
2036150-ec64567bfd9d32cc.jpg

座標變換

相關例子可以看我的另一篇部落格canvas鐘錶效果
座標系平移:translate(x,y)
  1. 即是將座標系的00點變換到(x,y)位置
座標系旋轉:rotate(θ)
  1. 將座標系旋轉θ度
  2. θ > 0時順時針旋轉,θ < 0時逆時針旋轉
座標系縮放:scale(x,y)
  1. 將座標系x方向放大x倍
  2. 將座標系y方向放大y倍

注意:因為座標系在經過變換之後,之後重新繪製的圖形都會以這個新的座標系為參考;所以在繪製的時候會非常的麻煩

解決方案如下:

save():儲存當前座標系

restore():讀取儲存的座標系

  1. 每次在進行座標系變換之前,先使用save()將原始座標系儲存下來
  2. 在進行變換之後,再使用restore()將座標系恢復為初始座標系
  3. 每個restore()對應相應的一個save(),所以在全域性中儲存一次隨後無限restore()的做法是無效的

繪製貝塞爾曲線/二次曲線

相關例子可以看我另一篇部落格canvas隨拖動變化的貝塞爾曲線
先用moveTo(x,y)設定起始點座標
貝塞爾曲線:bezierCurveTo(cpx1,cpy1,cpx2,cpy2,dx,dy)
  1. cpx1/xpy1:控制點1座標
  2. cpx2/xpy2:控制點2座標
  3. dx/dy:終點座標
二次曲線quadraticCurveTo(cpx,cpy,dx,dy)
  1. cpx/xpy:控制點座標
  2. dx/dy:終點座標

context.beginPath();
context.moveTo(300,100);
//貝塞爾曲線
context.bezierCurveTo(200,100,300,300,200,300);
context.stroke()

//二次曲線
context.moveTo(300,300);
context.quadraticCurveTo(400,150,500,300);
context.stroke();
2036150-78d3963d0a402aec.jpg

相關文章