Canvas畫圖之中級篇canvas
前段時間介紹了canvas畫圖的初級篇,今天接着介紹中級篇了...數組
一.繪製形狀ide
繪製圖形不只僅是利用線條來實現繪圖, 還能夠有快捷的繪製圖形的辦法函數
1.繪製矩形字體
2.繪製圓弧動畫
1 繪製矩形spa
繪製矩形的方法指針
CanvasRenderingContext2D.strokeRect對象
CanvasRenderingContext2D.fillRectblog
CanvasRenderingContext2D.rect
注意: rect 方法就是矩形路徑, 還須要使用 fill 或 stroke 才能夠看到效果. 所以通常使用 strokeRect 或 fillRect 直接能夠看到結果.
清除矩形區域
CanvasRenderingContext2D.clearRect
1.1繪製矩形框
語法: CanvasRenderingContext2D.strokeRect( x, y, width. height )
描述:
用來繪製一個矩形. 比起直接使用 moveTo 和 lineTo 方法要簡單許多.
該方法的前兩個參數表示繪製矩形的左上角的座標. 後兩個參數表示這個矩形的寬高.
使用該方法不須要使用 moveTo 方法設置起始點, 也不須要調用 stroke 等繪畫方法.
繪製的矩形支持 strokeStyle 設置顏色樣式.
代碼:
...
ctx.strokeStyle = 'blue';
ctx.strokeRect( 100, 100, 200, 100 );
效果
1.2 繪製填充矩形
語法: CanvasRenderingContext2D.fillRect( x, y, width. height )
描述:
用來繪製一個矩形. 比起直接使用 moveTo 和 lineTo 方法要簡單許多.
該方法的前兩個參數表示繪製矩形的左上角的座標. 後兩個參數表示這個矩形的寬高.
使用該方法不須要使用 moveTo 方法設置起始點, 也不須要調用 stroke 等繪畫方法.
繪製的矩形支持 fillStyle 設置顏色樣式.
案例
...
ctx.fillStyle = 'pink';
ctx.fillRect( 100, 100, 200, 100 );
效果
1.3清除矩形區域
語法: CanvasRenderingContext2D.clearRect( x, y, width, height )
描述:
用於清除畫布中的矩形區域的內容.
參數 x, y 表示矩形區域左上角的座標, width 與 height 表示矩形區域的寬高.
案例
...
ctx.fillRect( 100, 100, 150, 100 );
ctx.clearRect( 120, 120, 60, 60 );
注意:要清除矩形內部的區域時,clearRect的左上角座標的x,y都要略大於矩形左上角座標x,y值,不然清除的不完整。
效果
應用:能夠利用繪製圖形與清除矩形區域實現簡單的動畫
代碼:
...
var x = 10, y = 10, oldx = 10, oldy = 10;
var width = 100, height = 50;
var timerId = setInterval(function () {
ctx.clearRect( oldx - 1, oldy - 1, width + 2, height + 2 );
ctx.strokeRect( x, y, width, height );
oldx = x;
oldy = y;
x += 4;
y += 2;
if ( oldy >= 200 ) {
// clearInterval( timerId );
x = 10, y = 10;
}
}, 20);
有時爲了簡單經常將整個畫布都清除, 這樣就不用每次計算清除的問題.
ctx.clearRect( 0, 0, cas.width, cas.height );
// 也能夠設置畫布寬度, 這樣就會自動清除
cas.width = cas.width;
2.繪製圓弧
繪製圓弧的方法有:
CanvasRenderingContext2D.arc()
CanvasRenderingContext2D.arcTo()
2.1繪製圓弧
語法: CanvasRenderingContext2D.arc( x, y, radius. startAngle. endAngle, anticlockwise )
描述:
a.該方法用於繪製一段弧, 配合開始點的位置 與 stroke 方法或 fill 方法能夠繪製扇形.
b.方法中的前兩個參數 x, y 表示繪製圓弧的圓心座標.
c.參數 radius 表示圓弧半徑, 單位爲弧度.
d.參數 startAngle 與 endAngle 表示開始到結束的角度. 角度以水平向右爲 0 弧度, 順時針爲正方向.
e.參數 anticlockwise 表示是否採用默認的正向角度, 若是傳入 true 表示逆指針爲正. 該參數可選.
代碼:
// 在 200, 200 的地方繪製一段半徑爲 100 的圓弧, 圓心角爲 - PI / 2 到 PI / 4
...
ctx.arc( 200, 200, 100, -Math.PI/2, Math.PI/4 );
ctx.stroke();
// 爲了方便看清楚結構, 繪製座標軸
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo( 50, 200 );
ctx.lineTo( 350, 200 );
ctx.moveTo( 200, 50 );
ctx.lineTo( 200, 350 );
ctx.moveTo( 200, 200 );
ctx.lineTo( 300, 300 );
ctx.stroke();
效果爲:
2.1.1. 注意事項
使用 arc 繪圖的時候, 若是沒有設置 moveTo 那麼會從開始的繪弧的地方做爲起始點. 若是設置了 moveTo, 那麼會連線該點與圓弧的起點.
若是使用 stroke 方法, 那麼會從開始連線到圓弧的起始位置. 若是是 fill 方法, 會自動閉合路徑填充.
例如
2.2繪製扇形動畫
繪製扇形動畫, 就是每隔幾毫秒( 20 毫秒)擦除之前繪製的內容, 而後在之前繪製的基礎上比之前多繪製一點東西. 這裏多繪製的內容就是由角度決定. 好比一開始角度從 -Math.PI / 2 開始繪製. 那麼每次角度都 +0.1, 直到 繪製到 Math.PI * 3 / 2 爲止.
...
ctx.fillStyle = 'green';
var startAngle = -Math.PI / 2,
angle = startAngle,
x = 200, y = 200,
r = 100;
var intervalId = setInterval(function () {
// 清除以前繪製的內容
ctx.clearRect( 0, 0, cas.width, cas.height );
// 角度增量
angle += 0.1;
// 判斷是否中止計時器
if ( angle >= Math.PI * 3 / 2 ) {
clearInterval( intervalId);
angle = Math.PI * 3 / 2;
console.log( '繪製完成' );
}
// 繪製
ctx.moveTo( x, y );
ctx.arc( x, y, r, startAngle, angle );
ctx.fill();
}, 20);
2.3 繪製餅形圖
繪製餅形圖最大的特色是角度是疊加的. 開始從 -Math.PI/2 開始繪製, 達到執行角 x 後, 下一個區域從 x 開始繪製, 而後有到一個角 y 停下來. 如此反覆到 Math.PI * 3 / 2 結束.
2.3.1. 三等分餅形圖
繪製一個三等分的餅形圖, 顏色使用 紅, 綠, 藍.
var x = 200, y = 200,
r = 100,
step = Math.PI * 2 / 3, // 120 度一個區域
start = -Math.PI / 2, // 起始角度
colors = [ 'red', 'green', 'blue' ];
for ( var i = 0; i < 3; i++ ) {
ctx.beginPath();
ctx.moveTo( x, y );
ctx.fillStyle = colors[ i ];
ctx.arc( x, y, r, start, start+=step );
ctx.fill();
}
效果:
2.3.2 根據數據定義角度
根據數據源定義角度, 就是將全部的數據求和, 按照總和爲 2 * Math.PI 的結論計算出每個數據部分的弧度值. 同時顏色能夠提早定義好.
var data = [ 456, 150, 321, 666 ];
//1.應該求得整個數組的和
var sum=0;
data.forEach(function (v) {
sum+=v;
})
//計算每一個數字對應的比例 rdata表示對應的弧度數組
var rdata=data.map(function (v) {
//弧度/2PI=數字/數組數字和 故弧度=數字/數組數字和*2PI
return v*2*Math.PI/sum;
})
//準備顏色
//開始循環繪製
var startAngle=radian(-90);//餅形圖通常默認是從-90度開始繪製的
var x=cas.width/2;
var y=cas.height/2;
var r=100;
rdata.forEach(function (v,i) {
ctx.beginPath();
ctx.moveTo(x,y);
ctx.fillStyle=colors[(i+1)*11];//爲了使各部分選擇的顏色不那麼相近
ctx.arc(x,y,r,startAngle,startAngle+=v);
ctx.fill();
})
效果爲:
2.4. 繪製相切弧
語法: CanvasRenderingContext2D.arcTo( x1, y1, x2, y2, radius )
描述:
該方法用於繪製圓弧
繪製的規則是當前位置與第一個參考點連線, 繪製的弧與該直線相切.
同時鏈接兩個參考點, 圓弧根據半徑與該連線相切
例若有一個起始點 ( 100, 100 ), 那麼繪製其點. 顏色設置爲紅色.
ctx.fillStyle = 'red';
ctx.fillRect( 100 - 4, 100 - 4, 8, 8 );
而後兩個參考點分別爲 ( 100, 300 ) 和 ( 300, 300 ), 繪製出該點
ctx.fillRect( 100 - 4, 300 - 4, 8, 8 );
ctx.fillRect( 300 - 4, 300 - 4, 8, 8 );
鏈接兩個參考點
ctx.beginPath();
ctx.strokeStyle = 'red';
ctx.moveTo( 100, 300 );
ctx.lineTo( 300, 300 );
ctx.stroke();
調用 arcTo 方法繪製圓弧. 記得將起始點設置爲 ( 100, 100 )
ctx.beginPath();
ctx.strokeStyle = 'blue';
ctx.moveTo( 100, 100 );
ctx.arcTo( 100, 300, 300, 300, 100 );
ctx.stroke();
效果爲:
提示: 使用該方法可使用圓弧鏈接兩條直線, 而不用計算複雜的起始角度與結束角度. 所以多用於繪製圓角矩形。
3.繪製文本
繪製文本的方法
CanvasRenderingContext2D.fillText()
CanvasRenderingContext2D.strokeText()
CanvasRenderingContext2D.measureText()
文本樣式
CanvasRenderingContext2D.font
CanvasRenderingContext2D.textAlign
CanvasRenderingContext2D.textBaseline
3.1. 繪製文字
語法:
CanvasRenderingContext2D.strokeText( text, x, y[, maxWidth] )
CanvasRenderingContext2D.fillText( text, x, y[, maxWidth] )
描述:
這兩個方法的功能都是在給定的 x, y 座標下繪製文本內容.
stroke 繪製描邊文字, 文字內空心. fill 繪製填充文字, 即實心文字.
最後一個參數可選, 用於限制文字的總寬. 特殊條件下, 系統會自動調整文字寬度與大小以適應該參數限制.
3.2計算文本尺寸
語法: CanvasRenderingContext2D.measureText()
描述:
該方法返回一個文本尺寸對象, TextMetrics 對象.
TextMetrics 對象屬性不少, 經常使用的 width 屬性能夠獲取文字的寬度.
3.3. 設置文字屬性
3.3.1. 設置文字字體
語法: CanvasRenderingContext2D.font = value
描述:
該屬性用於設置繪製字體的各類信息, 與 CSS 語法一致, 設置字體形狀, 樣式, 字號粗細等.
其順序能夠是: style | variant | weight | size/line-height | family.
默認值爲 10px sans-serif
修改字號後查看 strokeText 與 fillText 的區別
...
ctx.font = '50px 黑體';
ctx.strokeRect( 100, 100, 200, 50 );
ctx.strokeText( 'Hello JK', 100, 100 );
ctx.strokeRect( 100, 200, 200, 50 );
ctx.fillText( 'Hello JK', 100, 200 );
效果爲:
3.3.2. 設置字體水平對齊方式
語法: CanvasRenderingContext2D.textAlign = value
描述:
該屬性用於設置文字的水平對齊方式. 設置文字居中, 靠左右對齊等.
該屬性能夠設置的值有: start( 默認 ), end, left, right, center.
start 表示根據參考基準點的垂直直線左靠對齊
end 表示根據參考基準點的垂直直線右靠對齊
left 與 right 就是左對齊與右對齊的意思
center 就是居中的意思.
3.3.3. 設置字體垂直對齊方式
語法: CanvasRenderingContext2D.textBaseline = value
描述:
該方法設置文字在垂直方向上的對齊方式.
該屬性能夠取值: top, middle, bottom, hanging, alphabetic, ideographic
基於參考點的直線, 其中 top, middle, buttom 分別表示靠上, 居中, 靠下對齊.
alphabetic 表示字母基線, 相似於英文字母的對齊方式. 例如 a, g, f 等字母.
ideographic 表意對齊. 使用字母對齊中超出的字母爲參考. 即比字母基線略靠下.
全部的對齊方式是根據文字特色相關的. 對於中文主要使用的仍是 top, bottom 和 middle.
top, middle, bottom 使用的較多
alphabetic 表示字母參考線, ideographic 會比它低一點, hanging 表示懸掛.
4.繪製圖片
繪製圖像雖然只有一個 drawImage 函數, 可是該函數有多重參數形式.
CanvasRenderingContext2D.drawImage( img, dx, dy ).(三參數)
CanvasRenderingContext2D.drawImage( img, dx, dy, dWidth, dHeight ).(五參數)
CanvasRenderingContext2D.drawImage( img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight ).(九參數)
4.1. 繪製簡單圖像
語法: CanvasRenderingContext2D.drawImage( img, dx, dy )
描述:
使用三個參數, 容許在畫布上的任意位置繪製圖片.
參數 img 是指圖片對象. 能夠是 img 標籤, 或者是 video 標籤, 已經另外一個 canvas 等.
提示:須要注意的是若是直接添加 img 對象是不能夠的, 須要等待其加載,由於加載圖片須要時間, 所以將繪製的方法放在 onload 事件中.
這裏使用 new Image() 與 document.createElement( 'img' ) 是同樣的.
4.2. 在指定區域內繪製圖像
當圖片比較大的時候, 若是使用這樣的方式繪圖, 那麼圖片可能會徹底覆蓋畫布. 例如:
所以, 須要將其控制在一個矩形區域內繪製.
語法: CanvasRenderingContext2D.drawImage( img, dx, dy, dWidth, dHeight )
描述:
參數 dWidth, dHeight 表示繪製的矩形區域. 繪製的 dx, dy 座標決定了開始.
該方法繪製的圖像會在指定範圍內被壓縮顯示.
將上面的圖繪製在 100 * 100 的範圍內.
...
ctx.drawImage( img, 100, 100, 100, 100 );
效果
若是但願正常顯示, 須要固定一個寬度或者高度, 而後根據比例計算出另外一個值. 這裏假定高度是 100. 計算寬度後繪圖.
...
var heigth = 100, width;
img.onload = function () {
width = img.width * height / img.height;
ctx.drawImage( img, 100, 100, width, height );
};
效果
4.3. 繪製任意圖像
相似於 CSS 中處理按鈕等小圖標的技巧, 將不少的效果圖集中在一張 png 格式的背景透明的圖片中, 這樣能夠提升效率也便於維護. 那麼 drawImage 一樣支持該方式繪圖. 在畫布中的指定位子與指定區域內, 繪製圖片中的某個矩形區.
語法: CanvasRenderingContext2D.drawImage( img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight )
描述: 這裏的帶有 s 前綴的參數就是指圖源的矩形區域.
例如將圖片的 ( 100, 100, 300, 200 ) 處的內容繪製到頁面的 ( 100, 100, 300, 200 ) 的位置.
'''
ctx.drawImage( img, 100, 100, 300, 200, 100, 100, 300, 200 );
效果
4.4. 繪製動畫
有了圖片部分繪製的功能, 咱們就能夠嘗試繪製動畫了. 準備一張圖片
而後開始的時候繪製第一行的第一張圖. 計算它的座標與寬高
var img = new Image();
img.src = './imgs士兵(1).png'
img.onload = function () {
var width = img.width / 4;
var height = img.heigth / 4;
// 第一張圖的頂點是 0, 0, 寬高是 width, height
};
那麼第一行的第二張圖就是 ( 0, width, width, height ), 第三張就是 ( 0, width * 2, width, height ). 所以第一行的第 i 張圖就是
var x = 0;
var y = width * ( i - 1 );
同理獲得, 第 j 列的 x 座標是 height * ( j - 1 )
如今繪製第一張圖
...
var img = new Image();
img.src = './imgs/士兵(1).png'
img.onload = function () {
var width = img.width / 4;
var height = img.height / 4;
ctx.drawImage( img, 0, 0, width, height, 100, 100, width, height );
};
如今要求, 每隔 200 毫秒就切換一張圖片, 如今只考慮第一行的圖片.
...
var img = new Image();
img.src = './imgs/士兵(1).png'
img.onload = function () {
var width = img.width / 4;
var height = img.height / 4;
var i = 0;
setInterval(function () {
ctx.clearRect( 0, 0, cas.width, cas.height );
ctx.drawImage( img, width * (i++ % 4), 0, width, height, 100, 100, width, height );
}, 200 );
};