超多經(jīng)典 canvas 實(shí)例
普及:<canvas>
元素用于在網(wǎng)頁(yè)上繪制圖形。這是一個(gè)圖形容器,您可以控制其每一像素,必須使用腳本來(lái)繪制圖形。
注意:IE 8 以及更早的版本不支持 <canvas>
元素。
貼士:全部例子都分享在我的 GayHub - https://github.com/bxm0927/canvas-special
尤雨溪個(gè)人主頁(yè)炫彩三角紐帶效果,點(diǎn)擊還可變換
知乎登錄注冊(cè)頁(yè)動(dòng)態(tài)離子背景效果
基于 canvas 的五子棋完整功能實(shí)現(xiàn)
基于 canvas 的《是男人就下100層》小游戲完美實(shí)現(xiàn)
毛筆字書寫田字格,可以寫字
隨心而動(dòng),隨刃而行。輸入文字顯示動(dòng)畫粒子特效
鼠標(biāo)移動(dòng)炫彩小球
2048
貪吃蛇
看你有多色
坦克大戰(zhàn)
宇宙行星旋轉(zhuǎn)特效
支付寶咻咻咻動(dòng)畫特效
程序員表白代碼
心形文字
照片墻
License
The code is available under the MIT license.
<marquee>不斷更新,歡迎補(bǔ)充!</marquee>
!canvas 簡(jiǎn)介
<canvas>
元素用于在網(wǎng)頁(yè)上繪制圖形。這是一個(gè)圖形容器,您可以控制其每一像素,必須使用腳本來(lái)繪制圖形。
<canvas>
標(biāo)記和 SVG 以及 VML 之間的一個(gè)重要的不同是,<canvas> 有一個(gè)基于 JavaScript 的繪圖 API,而 SVG 和 VML 使用一個(gè) XML 文檔來(lái)描述繪圖。
注意:IE 8 以及更早的版本不支持 <canvas>
元素。
canvas 初體驗(yàn)
<canvas id="myCanvas" width="450" height="450">
Your browser does not support the Canvas API, Please upgrade your browser.
</canvas>
<script>
let myCanvas = document.getElementById('myCanvas');
let ctx = myCanvas.getContext('2d');
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(200, 300);
ctx.stroke();
</script>
canvas 核心 API 講解
建議大家看官方文檔來(lái)系統(tǒng)的學(xué)習(xí) canvas API,本文下面的例子只是對(duì)知識(shí)點(diǎn)的鞏固。
- MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial
- 菜鳥教程:http://www.runoob.com/tags/ref-canvas.html
- w3school:http://www.w3school.com.cn/tags/html_ref_canvas.asp
顏色、樣式和陰影
fillStyle
、strokeStyle
fillStyle 屬性設(shè)置或返回用于填充繪畫的顏色、漸變或模式。
strokeStyle 屬性設(shè)置或返回用于筆觸的顏色、漸變或模式。
// 用藍(lán)色填充矩形
ctx.fillStyle="#0000ff";
ctx.fillRect(20,20,150,100);
// 漸變填充
var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(1,"white");
ctx.fillStyle=my_gradient;
ctx.fillRect(20,20,150,100);
// 圖像填充
var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;
ctx.fill();
!
shadowBlur
、shadowColor
shadowBlur 設(shè)置或返回用于陰影的模糊級(jí)別
shadowColor 設(shè)置或返回用于陰影的顏色
注釋1:請(qǐng)將 shadowColor 屬性與 shadowBlur 屬性一起使用,來(lái)創(chuàng)建陰影。
注釋2:請(qǐng)通過(guò)使用 shadowOffsetX 和 shadowOffsetY 屬性來(lái)調(diào)節(jié)陰影效果。
ctx.shadowBlur=20;
ctx.shadowColor="black";
ctx.fillStyle="blue";
ctx.fillRect(20,20,100,80);
!
createLinearGradient()
、createRadialGradient()
context.createLinearGradient(x0,y0,x1,y1)
創(chuàng)建線性漸變
context.createRadialGradient(x0,y0,r0,x1,y1,r1)
創(chuàng)建放射狀/環(huán)形的漸變
注釋:addColorStop(stop,color)
方法與 createLinearGradient()
或 createRadialGradient()
一起使用。
var my_gradient=ctx.createLinearGradient(0,0,0,170);
my_gradient.addColorStop(0,"black");
my_gradient.addColorStop(0.5,"red");
my_gradient.addColorStop(1,"white");
ctx.fillStyle=my_gradient;
ctx.fillRect(20,20,150,100);
!var grd=ctx.createRadialGradient(75,50,5,90,60,100);
grd.addColorStop(0,"red");
grd.addColorStop(1,"white");
ctx.fillStyle=grd;
ctx.fillRect(10,10,150,100);
!context.createPattern()
context.createPattern(image,"repeat|repeat-x|repeat-y|no-repeat")
重復(fù)繪制元素,元素可以是圖片、視頻,或者其他 <canvas> 元素。
var img=document.getElementById("lamp");
var pat=ctx.createPattern(img,"repeat");
ctx.rect(0,0,150,100);
ctx.fillStyle=pat;
ctx.fill();
!線條樣式
lineCap
context.lineCap="butt|round|square"
設(shè)置或返回線條的結(jié)束端點(diǎn)樣式 (平直的邊緣(默認(rèn))、圓形線帽、正方形線帽)
lineJoin
context.lineJoin="miter|bevel|round"
設(shè)置或返回兩條線相交時(shí),所創(chuàng)建的拐角類型 (尖角(默認(rèn))、斜角、圓角)
ctx.beginPath();
ctx.lineJoin="round";
ctx.moveTo(20,20);
ctx.lineTo(100,50);
ctx.lineTo(20,100);
ctx.stroke();
!lineWidth
ctx.lineWidth = 10
設(shè)置或返回當(dāng)前的線條寬度,單位 px
矩形
rect()
、fillRect()
、strokeRect()
context.rect(x,y,width,height)
創(chuàng)建矩形
context.fillRect(x,y,width,height)
創(chuàng)建已填色的矩形,默認(rèn)的填充顏色是黑色。
context.strokeRect(x,y,width,height)
創(chuàng)建不填色的矩形,默認(rèn)的筆觸顏色是黑色。
// 紅色矩形
ctx.beginPath();
ctx.lineWidth="6";
ctx.strokeStyle="red";
ctx.rect(5,5,290,140);
ctx.stroke();
clearRect()
clearRect() 在給定的矩形內(nèi)清除指定的像素
// 在給定矩形內(nèi)清空一個(gè)矩形
ctx.fillStyle="red";
ctx.fillRect(0,0,300,150);
ctx.clearRect(20,20,100,50);
!路徑
提示:請(qǐng)使用這些方法來(lái)創(chuàng)建路徑:moveTo()、lineTo()、quadricCurveTo()、bezierCurveTo()、arcTo() 以及 arc()。
fill()
填充當(dāng)前的圖像(路徑)。默認(rèn)顏色是黑色。
提示:請(qǐng)使用 fillStyle
屬性來(lái)填充另一種顏色/漸變。
注釋:如果路徑未關(guān)閉,那么 fill() 方法會(huì)從路徑結(jié)束點(diǎn)到開始點(diǎn)之間添加一條線,以關(guān)閉該路徑,然后填充該路徑。
// 繪制 150*100 像素的矩形,然后用綠色來(lái)給它填色:
ctx.rect(20,20,150,100);
ctx.fillStyle="green";
ctx.fill();
!stroke()
stroke() 方法會(huì)繪制出通過(guò) moveTo() 和 lineTo() 方法定義的路徑。默認(rèn)顏色是黑色。
提示:請(qǐng)使用 strokeStyle
屬性來(lái)繪制另一種顏色/漸變。
beginPath()
beginPath() 起始一條路徑,或重置當(dāng)前路徑
closePath()
closePath() 創(chuàng)建從當(dāng)前點(diǎn)回到起始點(diǎn)的路徑
moveTo()
、lineTo()
moveTo() 把路徑移動(dòng)到畫布中的指定點(diǎn),不創(chuàng)建線條
lineTo() 添加一個(gè)新點(diǎn),然后在畫布中創(chuàng)建從該點(diǎn)到最后指定點(diǎn)的線條
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(300,150);
ctx.stroke();
quadraticCurveTo()
、bezierCurveTo()
context.quadraticCurveTo(cpx,cpy,x,y);
創(chuàng)建二次貝塞爾曲線
context.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y);
創(chuàng)建三次方貝塞爾曲線
ctx.beginPath();
ctx.moveTo(20,20);
ctx.quadraticCurveTo(20,100,200,20);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(20,20);
ctx.bezierCurveTo(20,100,200,100,200,20);
ctx.stroke();
arc()
、arcTo()
context.arc(x,y,r,sAngle,eAngle[,counterclockwise]);
創(chuàng)建弧/曲線(用于創(chuàng)建圓形或部分圓)
context.arcTo(x1,y1,x2,y2,r);
創(chuàng)建兩切線之間的弧/曲線
ctx.beginPath();
arc(100, 75, 50, 0*Math.PI, 1.5*Math.PI)
ctx.stroke();
ctx.beginPath();
ctx.moveTo(20,20); // 創(chuàng)建開始點(diǎn)
ctx.lineTo(100,20); // 創(chuàng)建水平線
ctx.arcTo(150,20,150,70,50); // 創(chuàng)建弧
ctx.lineTo(150,120); // 創(chuàng)建垂直線
ctx.stroke(); // 進(jìn)行繪制
!clip()
clip() 從原始畫布剪切任意形狀和尺寸的區(qū)域
// 剪切矩形區(qū)域
ctx.rect(50,20,200,120);
ctx.stroke();
ctx.clip();
// 在 clip() 之后繪制綠色矩形
ctx.fillStyle="green";
ctx.fillRect(0,0,150,100);
!isPointInPath()
isPointInPath() 如果指定的點(diǎn)位于當(dāng)前路徑中,則返回 true,否則返回 false
ctx.rect(20,20,150,100);
if (ctx.isPointInPath(20,50)) {
ctx.stroke()
}
轉(zhuǎn)換
scale()
scale() 縮放當(dāng)前繪圖至更大或更小
// 繪制矩形,放大到 200%,然后再次繪制矩形:
ctx.strokeRect(5,5,25,15);
ctx.scale(2,2);
ctx.strokeRect(5,5,25,15);
!rotate()
rotate() 旋轉(zhuǎn)當(dāng)前繪圖
// 將矩形旋轉(zhuǎn) 20 度:
ctx.rotate(20 * Math.PI / 180);
ctx.fillRect(50,20,100,50);
!translate()
translate() 重新定義畫布上的 (0,0) 位置
ctx.fillRect(10,10,100,50);
ctx.translate(70,70);
ctx.fillRect(10,10,100,50);
!
transform()
、setTransform()
context.transform(a,b,c,d,e,f);
替換繪圖的當(dāng)前轉(zhuǎn)換矩陣
context.setTransform(a,b,c,d,e,f);
將當(dāng)前轉(zhuǎn)換重置為單位矩陣。然后運(yùn)行 transform()
文本
font
、textAlign
、textBaseline
font 設(shè)置或返回文本內(nèi)容的當(dāng)前字體屬性
textAlign 設(shè)置或返回文本內(nèi)容的當(dāng)前對(duì)齊方式
textBaseline 設(shè)置或返回在繪制文本時(shí)使用的當(dāng)前文本基線
fillText()
、strokeText()
、measureText()
context.fillText(text, x, y, maxWidth);
在畫布上繪制被填充的文本
context.strokeText(text,x,y,maxWidth);
在畫布上繪制文本(無(wú)填充)
context.measureText(text).width;
返回包含指定文本寬度的對(duì)象
ctx.font="30px Arial";
ctx.fillText("Hello World", 10, 50);
ctx.font="40px Arial";
// 創(chuàng)建漸變
var gradient=ctx.createLinearGradient(0, 0, myCanvas.width, 0);
gradient.addColorStop("0", "magenta");
gradient.addColorStop("0.5", "blue");
gradient.addColorStop("1.0", "red");
// 用漸變填色
ctx.strokeStyle=gradient;
ctx.strokeText("Hello World", 10, 90);
圖像繪制
drawImage()
context.drawImage(img,x,y,width,height);
向畫布上繪制圖像、畫布或視頻
var img=document.getElementById("tulip");
ctx.drawImage(img, 10, 10);
像素操作
width
、height
、data
width 返回 ImageData 對(duì)象的寬度
height 返回 ImageData 對(duì)象的高度
data 返回一個(gè)對(duì)象,其包含指定的 ImageData 對(duì)象的圖像數(shù)據(jù)
createImageData()
、getImageData()
、putImageData()
createImageData() 創(chuàng)建新的、空白的 ImageData 對(duì)象
getImageData() 返回 ImageData 對(duì)象,該對(duì)象為畫布上指定的矩形復(fù)制像素?cái)?shù)據(jù)
putImageData() 把圖像數(shù)據(jù)(從指定的 ImageData 對(duì)象)放回畫布上
合成
context.globalAlpha = number;
設(shè)置或返回繪圖的當(dāng)前 alpha 或透明值
context.globalCompositeOperation="source-in";
設(shè)置或返回新圖像如何繪制到已有的圖像上
其他
save()
、restore()
save() 保存當(dāng)前環(huán)境的狀態(tài)
restore() 返回之前保存過(guò)的路徑狀態(tài)和屬性
getContext
let cxt = Canvas.getContext('2d')
為不同的繪制類型 (2d、3d)
提供不同的環(huán)境,當(dāng)前唯一支持的是 2d
環(huán)境