1. 創(chuàng)建Canvas
//HTML
<canvas id="myCanvas" width="400" height="200">
您的瀏覽器不支持canvas!
</canvas>
//JavaScript
var canvas = document.getElementById('myCanvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
}
2. API
顏色、樣式和陰影
fillStyle:設(shè)置或返回用于填充繪畫的顏色、漸變或模式
strokeStyle:設(shè)置或返回用于筆觸的顏色、漸變或模式
shadowColor:設(shè)置或返回用于陰影的顏色
shadowBlur: 設(shè)置或返回用于陰影的模糊級別
shadowOffsetX:設(shè)置或返回陰影距形狀的水平距離
shadowOffsetY:設(shè)置或返回陰影距形狀的垂直距離
createLinearGradient():創(chuàng)建線性漸變(用在畫布內(nèi)容上)
createPattern(): 在指定的方向上重復(fù)指定的元素
createRadialGradient():創(chuàng)建放射狀/環(huán)形的漸變(用在畫布內(nèi)容上)
addColorStop(): 規(guī)定漸變對象中的顏色和停止位置
線條樣式
lineCap:設(shè)置或返回線條的結(jié)束端點(diǎn)樣式
lineJoin:設(shè)置或返回兩條線相交時,所創(chuàng)建的拐角類型
lineWidth:設(shè)置或返回當(dāng)前的線條寬度
miterLimit:設(shè)置或返回最大斜接長度
矩形
rect(x, y, width, height): 創(chuàng)建矩形
fillRect(x, y, width, height): 繪制“被填充”的矩形
strokeRect(x, y, width, height): 繪制矩形(無填充)
clearRect(x, y, width, height): 在給定的矩形內(nèi)清除指定的像素
路徑
fill():填充當(dāng)前繪圖(路徑)
stroke():繪制已定義的路徑
beginPath():起始一條路徑,或重置當(dāng)前路徑
moveTo(x,y):把路徑移動到畫布中的指定點(diǎn),不創(chuàng)建線條
closePath():創(chuàng)建從當(dāng)前點(diǎn)回到起始點(diǎn)的路徑
lineTo():添加一個新點(diǎn),然后在畫布中創(chuàng)建從該點(diǎn)到最后指定點(diǎn)的線條
clip():從原始畫布剪切任意形狀和尺寸的區(qū)域
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
// 剪切矩形區(qū)域
ctx.rect(50,20,200,120);
ctx.stroke();
ctx.clip();
// 在 clip() 之后繪制綠色矩形,只能顯示出部分
ctx.fillStyle="green";
ctx.fillRect(0,0,150,100);
quadraticCurveTo(控制點(diǎn)的 x ,控制點(diǎn)的 y ,結(jié)束點(diǎn)的 x ,結(jié)束點(diǎn)的 y ): 創(chuàng)建二次貝塞爾曲線
bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y): 創(chuàng)建三次方貝塞爾曲線
arc(x, y, radius, startAngle, endAngle, anticlockwise): 創(chuàng)建弧/曲線(用于創(chuàng)建圓形或部分圓)
arcTo(): 創(chuàng)建兩切線之間的弧/曲線
isPointInPath(): 如果指定的點(diǎn)位于當(dāng)前路徑中,則返回 true,否則返回 false
轉(zhuǎn)換
scale(): 縮放當(dāng)前繪圖至更大或更小
rotate(): 旋轉(zhuǎn)當(dāng)前繪圖
translate(): 重新映射畫布上的 (0,0) 位置
transform(): 替換繪圖的當(dāng)前轉(zhuǎn)換矩陣
setTransform(): 將當(dāng)前轉(zhuǎn)換重置為單位矩陣。然后運(yùn)行 transform()
文本
font:ctx.font = "Bold 20px Arial"
textAlign: 對齊方式
textBaseline:
fillText(string, x, y): 在畫布上繪制“被填充的”文本 ,fillText方法不支持文本斷行,即所有文本出現(xiàn)在一行內(nèi)
strokeText(): 在畫布上繪制文本(無填充)
measureText(): 返回包含指定文本寬度的對象
圖像繪制
drawImage(): 向畫布上繪制圖像、畫布或視頻
像素操作
width: ImageData 對象的寬度
height: ImageData 對象的高度
data: ImageData 對象的圖像數(shù)據(jù)
createImageData(): 創(chuàng)建新的、空白的 ImageData 對象
getImageData(): 返回 ImageData 對象,該對象為畫布上指定的矩形復(fù)制像素?cái)?shù)據(jù)
putImageData(): 把圖像數(shù)據(jù)(從指定的 ImageData 對象)放回畫布上
合成
globalAlpha: alpha 或透明值
globalCompositeOperation:
其他
save():保存當(dāng)前環(huán)境的狀態(tài)
restore():返回之前保存過的路徑狀態(tài)和屬性
createEvent():
getContext():
toDataURL():
3. 離屏canvas進(jìn)行預(yù)渲染
用離屏canvas進(jìn)行預(yù)渲染了,原理很簡單,就是先繪制到一個離屏canvas中,然后再通過drawImage把離屏canvas畫到主canvas中
一般例子
ctx.save();
var j = 0;
ctx.lineWidth = borderWidth;
for (var i = 1; i < this.r; i += borderWidth) {
ctx.beginPath();
ctx.strokeStyle = this.color[j];
ctx.arc(this.x, this.y, i, 0, 2 * Math.PI);
ctx.stroke();
j++;
}
ctx.restore();
4. 示例
畫尺子
//canvas寬高為900
let canvas = document.getElementById('c')
let ctx = canvas.getContext('2d');
//畫尺子主體
ctx.lineWidth = 3;
ctx.beginPath();
ctx.moveTo(48, 400);
ctx.lineTo(652, 400);
ctx.strokeStyle = "#666";
ctx.stroke();
//每厘米間隔像素
var rate = 10;
//循環(huán)畫出刻度線
for (var i = 0; i < 61; i++) {
ctx.beginPath();
ctx.moveTo(50 + rate * i, 400);
if (i % 5 == 0 && i % 10 != 0 && i != 0) {
//中間5刻度
ctx.lineWidth = 2;
ctx.fillText(i, 45 + rate * i, 420);
ctx.lineTo(50 + rate * i, 380);
} else if (i % 10 == 0) {
//中間10刻度
ctx.lineWidth = 4;
ctx.fillText(i, 45 + rate * i, 420);
ctx.lineTo(50 + rate * i, 375);
} else {
ctx.lineWidth = 1;
ctx.lineTo(50 + rate * i, 385);
}
ctx.stroke();
}
畫時鐘
let canvas = document.getElementById('c')
let ctx = canvas.getContext('2d');
ctx.translate(400, 400)
ctx.lineWidth = 1;
ctx.strokeStyle = "#666";
//圓圈
ctx.beginPath();
ctx.arc(0, 0, 110, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath()
//刻度盤
ctx.save()
for (var i = 0; i < 60; i++) {
ctx.lineWidth = 1;
ctx.beginPath();
if (i % 5 == 0) {
ctx.lineWidth = 3;
ctx.moveTo(0, 95);
} else {
ctx.moveTo(0, 100);
}
ctx.lineTo(0, 110);
ctx.stroke();
ctx.rotate(6 * Math.PI / 180);
}
ctx.restore()
/**
* @Author: xujianwei
* @Date: 2018-04-14 09:45:08
* @Desc: 畫指針的函數(shù)
* @params: ctx--canvas對象
* @params: rotate--旋轉(zhuǎn)角度系數(shù)
* @params: length--指針長度
* @params: color--指針顏色
*/
function pointer(ctx, rotate, length, color) {
ctx.save()
ctx.beginPath();
ctx.rotate(rotate * Math.PI / 30);
ctx.moveTo(0, -10);
ctx.lineTo(0, length);
ctx.strokeStyle = color
ctx.lineWidth = 3;
ctx.stroke();
ctx.closePath()
ctx.restore()
}
//使畫布的起始點(diǎn)旋轉(zhuǎn)到鐘表的12點(diǎn)刻度
ctx.rotate(Math.PI);
setInterval(function () {
//清理現(xiàn)場
ctx.beginPath();
ctx.arc(0, 0, 85, 0, 2 * Math.PI);
ctx.fillStyle = '#fff'
ctx.fill()
ctx.closePath()
//清理完畢
var date = new Date()
pointer(ctx, date.getSeconds(), 80, '#ff4d4d')
pointer(ctx, date.getSeconds() / 60 + date.getMinutes(), 80, '#333')
pointer(ctx, date.getSeconds() / 720 + date.getMinutes() / 12 + date.getHours() * 5, 30, '#333')
//添加中間原點(diǎn)
ctx.beginPath();
ctx.arc(0, 0, 4, 0, 2 * Math.PI);
ctx.fillStyle = '#ff4d4d'
ctx.fill()
ctx.closePath()
}, 1000)