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