Canvas
1.概述
Canvas是HTML5中非常重要的一個(gè)更新亮點(diǎn),畫布薯蝎,替代Flash的!制作動(dòng)畫谤绳、制作游戲占锯。渲染效率非常的高,瀏覽器不需要安裝任何的插件就可以渲染這個(gè)動(dòng)畫缩筛。而Flash需要安裝Flash Player這個(gè)插件才行消略。
Canvas適合動(dòng)態(tài)圖形繪制。小的動(dòng)態(tài)效果也可以使用過渡或動(dòng)畫屬性animation歪脏。
echarts圖表使用Canvas繪制疑俭,https://echarts.apache.org/zh/index.html
1.1. Hello World
canvas是一個(gè)標(biāo)簽粮呢,有一個(gè)默認(rèn)的寬高,此時(shí)注意婿失,如果我們要設(shè)置寬度、高度啄寡,必須設(shè)置在HTML標(biāo)簽上面豪硅,而不能設(shè)置在CSS上。
注意:
- canvas本身布具有繪畫功能, 只是一個(gè)畫布標(biāo)簽, 但是H5提供給js的API具有繪畫功能
2. IE9一下不兼容
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas挺物,請(qǐng)升級(jí)</canvas>
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
//繪制矩形路徑
ctx.rect(50, 50, 50, 50);//距離畫布左上角50 50 寬高50 50懒浮,只是路徑看不到效果
//描邊
ctx.stroke();
//填充
// ctx.fill()
</script>
2. 涉及的API
2.1 getContext()
get表示得到,context是上下文的意思。
canvas起初是空白的砚著。為了展示次伶,首先腳本需要找到渲染上下文,然后在它的上面繪制稽穆。<canvas>
元素有一個(gè)做 getContext() 的方法冠王,這個(gè)方法是用來獲得渲染上下文和它的繪畫功能。getContext()只有一個(gè)參數(shù)舌镶,上下文的格式柱彻。
// 首先獲取canvas 標(biāo)簽的dom對(duì)象
var mycanvas = document.querySelector("canvas");
// 獲取上下文對(duì)象() 參數(shù)是2d繪圖
var ctx = canvas.getContext('2d');
ctx對(duì)象,非常重要所有的繪制都是ctx的方法餐胀。canvas就是畫布,功能就是生產(chǎn)畫筆,
剩下所有的繪制都是有這支畫筆ctx對(duì)象的屬性來操作
//也就是說所有的繪制API都是ctx的事情哟楷,而不是canvas對(duì)象
ctx.fillStyle = "blue";
ctx.arc(300,300,100,0,Math.PI * 2,true);
ctx.fill();
2.2 繪制圓形 arc()
繪制圓形 arc(x,y,r,start, end, bol)
bol,是布爾值, 跟繪制圓弧有關(guān)
ctx.arc(300,300,100,0,Math.PI * 2,true);
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
console.log(ctx);
//繪制一個(gè)圓
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//繪制圓的路徑否灾,圓心位置 圓心位置 半徑 起始為0 終止為Math.PI*2 順時(shí)針繪制
//描邊后才可以看到邊卖擅,之前只是路徑
ctx.strokeStyle = 'blue';//改變描邊顏色
ctx.stroke();
//改變填充顏色,填充之前定義填充顏色
ctx.fillStyle = 'red';
ctx.fill()//填充
</script>
2.3 繪制矩形 rect()
繪制矩形 rect(x,y,w,h)
ctx.rect(200, 200, 100, 100);
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
//繪制矩形路徑
ctx.rect(50, 50, 50, 50);//距離畫布左上角50 50 寬高50 50墨技,只是路徑看不到效果
//描邊
ctx.stroke();
//填充
// ctx.fill()
</script>
2.4 stroke()筆觸
繪制線條
ctx.stroke()
2.5 fill() 填充
ctx.fill()
2.6 可以合在一起寫
strokeRect(x,y,w,h)
-
fillRect(x,y,w,h)
參數(shù):
x,y 為起點(diǎn)的x,y坐標(biāo)
w,h 為要繪制矩形的寬高
注意沒有strokeArc 和 fillArc 的寫法
ctx.strokeRect(100,100,200,100)//通過描邊直接把矩形繪制出來
ctx.fillRect(200,300,200,100)//填充的時(shí)候直接繪制一個(gè)矩形
2.7 清除 clearRect()
清除clearRect(x,y,w,h)
ctx.clearRect(250, 250, 30, 30);
ctx.clearRect(300,300,100,100)
清除在繪制有先后屬性之分
3. 筆觸和填充
Canvas中能夠產(chǎn)生顏色的是兩個(gè)東西磨镶,一個(gè)叫做筆觸(也叫做描邊),一個(gè)叫做填充健提。
3.1. 筆觸(描邊) strokeRect(x,y,w,h)
參數(shù),x,y 左上角起點(diǎn)坐標(biāo),w,h為繪制矩形的寬高
3.1.1 筆觸的使用:
//筆觸
ctx.strokeRect(100,100,300,40);
你會(huì)發(fā)現(xiàn)只有描邊沒有填充色
而我們剛學(xué)的 fillRect() API繪制的矩形是有填充色的
3.1.2 設(shè)置筆觸的顏色
// 設(shè)置筆觸顏色
ctx.strokeStyle = 'red';
// ctx.strokeStyle = 'hsl(250,50%,50%)'
// 繪制筆觸矩形
ctx.strokeRect(100,100,300,50);
此時(shí)你就會(huì)發(fā)現(xiàn)你繪制的是一個(gè)沒有填充色琳猫,只有紅色邊框的矩形
3.1.3 繪制筆觸的寬度
ctx.lineWidth = 20; // 設(shè)置筆觸的寬為20
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
console.log(ctx);
//繪制一個(gè)圓
ctx.arc(200, 200, 100, 0, Math.PI * 2, true);//繪制圓的路徑,圓心位置 圓心位置 半徑 起始為0 終止為Math.PI*2 順時(shí)針繪制
//描邊后才可以看到邊私痹,之前只是路徑
ctx.strokeStyle = 'blue';//改變描邊顏色
ctx.lineWidth =20;
ctx.stroke();
3.1.4 筆觸繪制線段
劃線之前你的先告訴瀏覽器怎么畫
moveTo() 繪制開始位置 lineTo() 畫筆移動(dòng)的下一個(gè)位置
ctx.moveTo(100,100); //將畫筆移動(dòng)到一個(gè)位置(先移動(dòng)到開始點(diǎn)的位置)
ctx.lineTo(300,300); //用畫筆畫脐嫂,此時(shí)是抽象的一個(gè)線,沒有顯示在畫布上(下一個(gè)點(diǎn)的位置)
ctx.stroke(); //劃線(告訴瀏覽器,我說完了,你畫吧)
我們可以多次使用lineTo:
告訴瀏覽器下一個(gè)點(diǎn)的位置,來繪制相鄰點(diǎn)之間的線段
ctx.moveTo(100,100); // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300); // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線紊遵,
ctx.lineTo(300,200); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線账千,
ctx.lineTo(430,180); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.stroke(); // 正式開始劃線
<body>
<canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas暗膜,請(qǐng)升級(jí)</canvas>
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//筆觸寬度
ctx.strokeStyle='red';
//繪制線段
//筆尖不在畫布上moveTo
ctx.moveTo(100, 100)
//筆尖落在畫布上lineTo繪制路徑
ctx.lineTo(200, 200)
ctx.lineTo(200, 300)
ctx.lineTo(400, 300)
//筆觸填充
ctx.stroke()//繪制
</script>
</body>
3.1.5 閉合路徑
而且我們還可以使用closePath() ,來閉合路徑
就是瀏覽器會(huì)自動(dòng)的在開始點(diǎn)moveTo的點(diǎn)和最后一個(gè)lineTo的結(jié)束點(diǎn)之間繪制一條線
ctx.beginPath(); // 開始準(zhǔn)備畫線
ctx.moveTo(100,100); // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300); // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線匀奏,
ctx.lineTo(300,200); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.lineTo(430,180); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線学搜,
ctx.closePath(); // 閉合路徑(加上就閉合了)
ctx.stroke(); // 正式開始劃線
繪制新的線段
<body>
<canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas娃善,請(qǐng)升級(jí)</canvas>
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//筆觸寬度
ctx.strokeStyle = 'red';
//繪制線段
//筆尖不在畫布上moveTo
ctx.moveTo(100, 100)
//筆尖落在畫布上lineTo繪制路徑
ctx.lineTo(200, 200)
//筆觸填充
ctx.stroke()//繪制
ctx.moveTo(300, 200)//繪制新的線條
ctx.lineTo(200, 300)
ctx.stroke()
</script>
</body>
3.1.6 繪制新的線條開始(開始新的路徑)
可以使用beginPath() 表示開始一個(gè)新的路徑
ctx.beginPath()
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.stroke()
ctx.beginPath()
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.stroke()
<body>
<canvas id="canvas" width="500" height="500">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
<script>
//僅僅獲取畫布對(duì)象
let mycanvas = document.getElementById('canvas');
//通過畫布對(duì)象獲取上下文對(duì)象(畫筆對(duì)象)
let ctx = mycanvas.getContext('2d');
ctx.lineWidth = 20;//筆觸寬度
ctx.strokeStyle = 'red';
ctx.beginPath()//開始一個(gè)新路徑beginPath() 一段路徑
ctx.moveTo(100, 100)
ctx.lineTo(200, 200)
ctx.stroke()
ctx.beginPath()//開始一個(gè)新路徑beginPath() 一段路徑
ctx.moveTo(300, 200)
ctx.lineTo(400, 300)
ctx.stroke()
</script>
</body>
可以使用lineWidth屬性設(shè)置線的寬度
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 繪制描邊的顏色
ctx.closePath(); // 閉合路徑
ctx.lineWidth = '10'; // 繪制線的寬度
ctx.stroke();
ctx.filStyle = 'skyblue';// 繪制填充顏色
ctx.fill(); // 繪制填充色
3.1.7 繪制線條的轉(zhuǎn)角
lineJoin : 邊界連接點(diǎn)樣式瑞佩,要在畫ctx.stroke()之前設(shè)置轉(zhuǎn)角
- miter(默認(rèn)值),
- round(圓角),
- bevel(平角)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.closePath()
ctx.strokeStyle = 'red';
ctx.lineWidth = 20;
ctx.lineJoin = 'round'
ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas聚磺,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(100, 100);
ctx.lineTo(300, 300);
ctx.lineTo(300, 200);
ctx.lineTo(430, 180);
ctx.strokeStyle = 'red';
ctx.closePath();
ctx.lineWidth = '10';
ctx.lineJoin = 'round'//線條轉(zhuǎn)角
ctx.stroke();
</script>
</body>
3.1.8 端點(diǎn)樣式
lineCap: 端點(diǎn)樣式
- butt(默認(rèn)值),
- round(圓角) (寬度左右兩邊分別多出線高的一半)
- square(寬度左右兩邊分別多出線高的一半)
ctx.moveTo(50, 50);
ctx.lineTo(300, 300);
ctx.strokeStyle = 'red';
ctx.lineWidth = 50;
ctx.lineCap = 'round'
ctx.stroke()
ctx.beginPath();
ctx.moveTo(490, 100);
ctx.lineTo(490, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'butt'//默認(rèn)
ctx.stroke();
ctx.beginPath();
ctx.moveTo(450, 100);
ctx.lineTo(450, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'round'//圓角,線段寬度左右兩端分別多出線高的一半
ctx.stroke();
ctx.beginPath();
ctx.moveTo(410, 100);
ctx.lineTo(410, 350);
ctx.strokeStyle = 'blue';
ctx.lineCap = 'square'//平角炬丸,線段寬度左右兩端分別多出線高的一半
ctx.stroke();
3.2. 填充 fill()
還可以是用fill()給閉合路徑后的閉合區(qū)域填充顏色
ctx.beginPath(); // 開始準(zhǔn)備畫線
ctx.moveTo(100,100); // 將畫筆移動(dòng)到一個(gè)位置
ctx.lineTo(300,300); // 準(zhǔn)備繪制從開始點(diǎn)到這個(gè)點(diǎn)的線瘫寝,
ctx.lineTo(300,200); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.lineTo(430,180); // 準(zhǔn)備繪制從上一個(gè)點(diǎn)到這個(gè)點(diǎn)的線,
ctx.closePath(); // 閉合路徑
ctx.stroke(); // 正式開始劃線
ctx.fill(); // 繪制填充色
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas焕阿,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.lineWidth = 10;
ctx.moveTo(200, 200);
ctx.lineTo(200, 400);
ctx.lineTo(400, 400);
ctx.lineTo(400, 200);
// ctx.closePath()閉合路徑的方法之一 筆觸
// ctx.stroke();
ctx.fill()//使用填充會(huì)自動(dòng)閉合路徑
</script>
</body>
3.2.1 繪制填充顏色 fillStyle
strokeStyle 屬性修改描邊顏色
fillStyle 屬性修改填充顏色
ctx.beginPath();
ctx.moveTo(100,100);
ctx.lineTo(300,300);
ctx.lineTo(300,200);
ctx.lineTo(430,180);
ctx.strokeStyle = 'red';// 繪制描邊的顏色
ctx.closePath(); // 閉合路徑
ctx.stroke();
ctx.filStyle = 'skyblue';// 繪制填充顏色
ctx.fill(); // 繪制填充色
4.弧與圓形
1.1. 繪制弧度及圓形的公式
ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise)
參數(shù)
- x,y為圓心的坐標(biāo)
- radius 為圓形的半徑
- startAngle 為弧度的起始位置,0是正x軸的
- endAngle 為弧度的終點(diǎn)位置,
- anticlockwise 布爾值,true為逆時(shí)針繪制,false為順時(shí)針繪制
注意
canvas中的度數(shù)都是弧度制
弧和圓形也是筆觸(描邊),所以也需要以beginPath()開始
var ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.arc(150,150,100,0,2*Math.PI,false);
ctx.arc(200,200,100,0,2,false);
ctx.arc(150,150,100,2,2,false);
ctx.fill();
ctx.beginPath();
ctx.arc(150,150,100,2,0,true);
ctx.strokeStyle= 'red';
ctx.lineWidth = 2;
ctx.stroke();
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas咪啡,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.lineWidth = 10;
ctx.beginPath();
ctx.arc(250, 250, 100, 0, Math.PI * 0.5, false);
ctx.stroke()
ctx.beginPath();
ctx.arc(450, 450, 100, Math.PI * 1.5, Math.PI * 0.5, false);
ctx.stroke()
</script>
</body>
5. 繪制曲線
5.1. 繪制弧度曲線
arcTo(x1,y1,x2,y2,r)
x1,y1 坐標(biāo)一 x2,y2坐標(biāo)二 r圓弧半徑
ctx.moveTo(100, 300)
ctx.arcTo(100, 100, 200, 100, 50)
ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100, 300);
ctx.arcTo(100, 100, 200, 100, 50);//弧線
ctx.stroke()
ctx.beginPath();
ctx.moveTo(150, 200);
ctx.arcTo(150, 100, 200, 100, 400);
ctx.stroke()
</script>
</body>
5.2. 繪制貝塞爾曲線
繪制公式
ctx.quadraticCurveTo(cp1x,cp1y,x,y)
參數(shù)
- cp1x, cp1y 為貝塞爾曲線的控制點(diǎn)
- x,y 為繪制曲線的終點(diǎn)
ctx.beginPath()
ctx.moveTo(100,100);
ctx.quadraticCurveTo(200,100,200,200)
ctx.stroke();
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas暮屡,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100,100);//起點(diǎn)
//ctx.lineTo(300,100)//終點(diǎn)
ctx.quadraticCurveTo(150,400,300,100)//一次貝塞爾曲線瑟匆,貝塞爾控制點(diǎn)(150,400),終點(diǎn)
ctx.stroke()
5.3. 繪制二次貝塞爾曲線
繪制公式
ctx.bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)
參數(shù)
- cp1x, cp1y 為貝塞爾曲線的第一個(gè)控制點(diǎn)
- cp2x, cp3y 為貝塞爾曲線的第二個(gè)控制點(diǎn)
- x,y 為繪制曲線的終點(diǎn)
ctx.beginPath()
ctx.moveTo(100,100);
ctx.bezierCurveTo(200,120,50,150,200,200);
ctx.stroke();
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.beginPath();
ctx.lineWidth = 10;
ctx.strokeStyle = 'red';
ctx.moveTo(100,100);//起點(diǎn)
// ctx.bezierCurveTo(150,100,300,100,500,100)點(diǎn)都在一條線上的貝塞爾曲線
ctx.bezierCurveTo(150,300,300,-50,500,100)//貝塞爾端點(diǎn)一 貝塞爾端點(diǎn)二 終點(diǎn)
ctx.stroke()
</script>
6. canvas變換
6.1. translate(x,y)
坐標(biāo)基準(zhǔn)點(diǎn)偏移 : 從起始點(diǎn)為基準(zhǔn)栽惶,移動(dòng)到當(dāng)前位置
ctx.translate(100, 100)ctx.arc(100, 100, 50, 0, Math.PI * 2, true)ctx.strokeStyle = 'red';ctx.lineWidth = 5;ctx.stroke()
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas愁溜,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.translate(100,100);//可以理解為偏移基準(zhǔn)點(diǎn)
ctx.arc(100, 100,50,0,Math.PI*2,true)//元素位置通過基準(zhǔn)點(diǎn)與參考點(diǎn)配合確定,調(diào)誰都可以
ctx.stroke();
</script>
</body>
6.2.rotate(弧度):
旋轉(zhuǎn) 弧度公式 :角度*PI/180
ctx.rotate(Math.PI / 180 * 30)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.translate(100,100)//基準(zhǔn)點(diǎn)
ctx.rotate(Math.PI/180 *80);//旋轉(zhuǎn)外厂,弧度值轉(zhuǎn)成角度值
ctx.strokeRect(0,0,100,100)//參考點(diǎn)在自己中心位置
ctx.strokeRect(-50,-50,100,100)//參考點(diǎn)在自己中心位置
6.3. scale(wb,hb)
縮放比例(縮放canvas繪制的圖片)
ctx.scale(1.5, 1.5)
ctx.rect(200, 200, 100, 100)
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.stroke()
這里將寬冕象、高、圓心坐標(biāo)等比縮放
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.lineWidth=10;
ctx.strokeStyle='red';
ctx.scale(1,0.5);//縮放 基準(zhǔn)點(diǎn) 寬 高 線寬都等比例縮放
ctx.strokeRect(200,200,50,100)
示例:
var can = document.getElementById("canvas");
ctx = can.getContext("2d");
ctx.beginPath();
ctx.translate(160,30);
ctx.fillStyle = "#00ff00";
ctx.fillRect(0,0,100,50);
for (var i=0;i<50 ;i++ ){
ctx.translate(25,25);
ctx.scale(0.9,0.9);//縮放汁蝶,針對(duì)后面要繪制的圖形進(jìn)行縮放(在前面繪制的那個(gè)圖形的基礎(chǔ)上進(jìn)行縮放)
ctx.rotate(Math.PI/10);
ctx.fillRect(0,0,100,50);
}
7. 保存與恢復(fù)路徑
7.1. 保存路徑 save()
保存之前的路徑狀態(tài)
7.2.恢復(fù)路徑 restore()
ctx.save()
ctx.scale(3, 2)
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 100, 20)
ctx.restore()
ctx.beginPath()
ctx.fillRect(0, 50, 100, 20)
會(huì)封閉一個(gè)獨(dú)立路徑 不會(huì)對(duì)外邊的區(qū)域產(chǎn)生影響
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
margin: 50px auto;
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas渐扮,請(qǐng)升級(jí)</canvas>
<script>
let mycanvas = document.getElementById('canvas');
let ctx = mycanvas.getContext('2d');
ctx.strokeStyle = 'blue';
ctx.beginPath();
ctx.save()//保存之前的的路徑狀態(tài)
ctx.strokeStyle = 'red';
ctx.lineWidth = 10;
ctx.moveTo(100, 100);
ctx.lineTo(300, 100);
ctx.stroke()
ctx.beginPath()
ctx.restore() //恢復(fù)之前保存的路徑狀態(tài)
ctx.moveTo(100, 200);
ctx.lineTo(300, 200);
ctx.stroke()
</script>
8 繪制圖片
8.1. 繪制圖片
8.1.1 創(chuàng)建圖片對(duì)象,獲取圖片
圖片預(yù)加載,獲取圖片文件
const img = new Image();
img.src = '../1.jpg'
8.1.2 onload事件,當(dāng)圖片加載完成執(zhí)行繪制
img.onload = function(){}
8.1.3 圖片加載完成后將圖片繪制在畫布上
ctx.drawImage(image, dx, dy, dWidth, dHeight);
繪制圖片(圖片對(duì)象,畫布坐標(biāo)x,畫布坐標(biāo)y,繪制顯示圖片寬度,繪制顯示圖片高度)
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 0, 0, 100, 300)
}
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas掖棉,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let img = new Image();//創(chuàng)建圖片對(duì)象
img.src = './imgs/11.jpg';
img.onload = function () {//加載就會(huì)觸發(fā)onload事件
ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
}
</script>
</body>
8.1.4 切圖
ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
參數(shù):
image 繪制到上下文的元素
-
sx 可選
需要繪制到目標(biāo)上下文中的墓律,
image
的矩形(裁剪)選擇框的左上角 X 軸坐標(biāo)。 -
sy 可選
需要繪制到目標(biāo)上下文中的幔亥,
image
的矩形(裁剪)選擇框的左上角 Y 軸坐標(biāo)耻讽。 -
sWidth 可選
需要繪制到目標(biāo)上下文中的,
image
的矩形(裁剪)選擇框的寬度帕棉。 -
sHeight 可選
需要繪制到目標(biāo)上下文中的针肥,
image
的矩形(裁剪)選擇框的高度。 -
dx
image
的左上角在目標(biāo)canvas上 X 軸坐標(biāo)香伴。 -
dy
image
的左上角在目標(biāo)canvas上 Y 軸坐標(biāo)慰枕。 -
dWidth 可選
image
在目標(biāo)canvas上繪制的寬度。 -
dHeight 可選
image
在目標(biāo)canvas上繪制的高度即纲。 允許對(duì)繪制的image
進(jìn)行縮放具帮。
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
ctx.drawImage(this, 50, 50, 500, 500, 100, 100, 100, 100)
}
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let img = new Image();//創(chuàng)建圖片對(duì)象
img.src = './imgs/11.jpg';
img.onload = function () {//加載就會(huì)觸發(fā)onload事件
ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
ctx.drawImage(this, 50, 50, 100, 100, 20, 350, 300, 300);//可以做放大鏡
}
</script>
</body>
<style>
* {
margin: 0;
padding: 0;
}
body {
background-color: #f3f3f3;
}
#canvas {
/*canvas雖然默認(rèn)寬高300X150,但它是個(gè)行元素inline*/
display: block;
/*變塊才能居中*/
background-color: #fff;
}
</style>
</head>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas低斋,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let img = new Image();//創(chuàng)建圖片對(duì)象
img.src = './imgs/11.jpg';
img.onload = function () {//加載就會(huì)觸發(fā)onload事件
ctx.drawImage(this, 20, 20, 300, 300);//畫圖片
canvas.onmousemove = function (e) {
console.log(e);
let sX = e.clientX - 50;
let sY = e.clientY - 50;
ctx.drawImage(img, sX, sY, 100, 100, 20, 350, 300, 300);
}
}
</script>
</body>
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas蜂厅,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let img = new Image();//創(chuàng)建圖片對(duì)象
img.src = './imgs/11.jpg';
img.onload = function () {//圖片加載就會(huì)觸發(fā)onload事件
//創(chuàng)建背景圖片填充資源
let bg = ctx.createPattern(this, 'repeat')
ctx.fillStyle = bg;//填充背景資源
ctx.fillRect(0, 0, 500, 500)//填充一個(gè)矩形
}
</script>
</body>
8.2. 填充背景
8.2.1 createPattern(img,平鋪方式)
參數(shù): 平鋪方式:repeat,repeat-x,repeat-y,no-repeat
const img = new Image();
img.src = '../1.jpg';
img.onload = function () {
const bg = ctx.createPattern(img, 'no-repeat');
ctx.fillStyle = bg;
ctx.fillRect(100, 100, 300, 200)
}
8.3. 顏色漸變
8.3.1 線性漸變:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐標(biāo)點(diǎn)
x2,y2結(jié)束坐標(biāo)點(diǎn)
8.3.2 徑向漸變:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1內(nèi)圓坐標(biāo)及半徑
x2,y2,r2外圓坐標(biāo)及半徑
8.3.3 addColorStop(位置,顏色)
位置:漸變點(diǎn) 0-1之間 可多個(gè)
例子,
線性漸變
let color = ctx.createLinearGradient(0, 0, 500, 500);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let color = ctx.createLinearGradient(0, 0, 500, 500)//漸變顏色對(duì)象
color.addColorStop(0, 'red')//添加顏色
color.addColorStop(.5, 'yellow')
color.addColorStop(1, 'blue')
ctx.fillStyle = color;//用漸變顏色填充
ctx.fillRect(0, 0, 500, 500)
</script>
</body>
徑向漸變
let color = ctx.createRadialGradient(200, 200, 100, 200, 200, 200);
color.addColorStop(0, 'pink');
color.addColorStop(0.5, 'yellow')
color.addColorStop(1, 'deeppink')
ctx.fillStyle = color;
ctx.fillRect(0, 0, 500, 500)
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas拔稳,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
//加載圖片
let color = ctx.createRadialGradient(200,200,50,200,200,300)//漸變顏色對(duì)象
color.addColorStop(0, 'red')//添加顏色
color.addColorStop(.5, 'yellow')
color.addColorStop(1, 'blue')
ctx.fillStyle = color;//用漸變顏色填充
// ctx.fillRect(0, 0, 500, 500)
ctx.fillRect(0, 0, 100, 100)
</script>
</body>
9.繪制文本
9.1. 繪制文本
- strokeText(文本,x,y); 繪制空心文本(描邊文字)
- fillText(文本,x,y); 繪制實(shí)心文本(填充文字)
- font = "font-size font-family" 注:尺寸 字體缺一不可
- textAlign = "";文本左右對(duì)齊方式 (參考文字坐標(biāo)點(diǎn)對(duì)齊)
start center end left right - textBaseline文本上下對(duì)齊方式
alphabetic 默認(rèn)葛峻。文本基線是普通的字母基線锹雏。
top 文本基線是 em 方框的頂端巴比。。
hanging 文本基線是懸掛基線。
middle 文本基線是 em 方框的正中轻绞。
ideographic 文本基線是表意基線采记。
bottom 文本基線是 em 方框的底端。
let str = 'wuwei'
ctx.font = '50px 宋體'
ctx.textAlign = 'center'
ctx.textBaseline = 'top'
ctx.strokeText(str, 100, 100)
ctx.fillText(str, 100, 200)
9.2. 繪制陰影
- shadowOffsetX,shadowOffsetY x軸政勃、y軸偏移
- shadowBlur 陰影模糊度
- shadowColor 陰影顏色
默認(rèn)顏色:rgba(0,0,0,0)
ctx.shadowOffsetX = '10'
ctx.shadowOffsetY = '10'
ctx.shadowBlur = '3'
ctx.shadowColor = 'red'
案例:
body {
background-color: #000;
}
canvas {
display: block;
margin: 100px auto 0;
border: 1px solid skyblue;
background-color: #fff;
}
.box{
width: 360px;
margin: 10px auto;
}
input{
width: 50px;
height: 20px;
text-align: center;
}
<canvas width="500" height="500"></canvas>
<div class="box">
<input type="color" id='colorList'>
<button id='color'>隨機(jī)顏色</button>
<input type="text" value='2px' id='storke'>
<button id='add'>筆觸增加</button>
<button id='reduce'>筆觸減小</button>
<button id="clear">清屏</button>
</div>
var canvas = document.getElementsByTagName('canvas')[0];
var ctx = canvas.getContext('2d');
var strokeColor = '#000000';
var lineWidth = 2;
colorList.onchange = function () {
strokeColor = colorList.value;
}
color.onclick = function () {
strokeColor = '#' + Math.random().toString(16).slice(2, 8);
colorList.value = strokeColor;
}
add.onclick = function () {
if (lineWidth >= 10) return;
lineWidth += 2;
storke.value = lineWidth + 'px'
}
reduce.onclick = function () {
if (lineWidth <= 2) return;
lineWidth -= 2;
storke.value = lineWidth + 'px'
}
canvas.onmousedown = function (ev) {
ev = ev || window.event;
var This = this;
var x = ev.clientX - this.offsetLeft;
var y = ev.clientY - this.offsetTop;
ctx.strokeStyle = strokeColor;
ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(x, y);
document.onmousemove = function (ev) {
ev = ev || window.event;
var x = ev.clientX - This.offsetLeft;
var y = ev.clientY - This.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
}
document.onmouseup = function () {
this.onmousemove = null;
this.onmouseup = null
}
}
clear.onclick = function () {
console.log(1)
ctx.clearRect(0, 0, 500, 500)
}
<body>
<canvas id="canvas" width="700" height="600">你的瀏覽器不支持canvas唧龄,請(qǐng)升級(jí)</canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let str = 'hello world';
ctx.font = '50px 微軟雅黑'
ctx.textAlign = 'left'
ctx.textBaseline = 'top'
ctx.shadowOffsetX = '10'//水平偏移
ctx.shadowOffsetY = '10'//垂直偏移
ctx.shadowBlur = '3'//模糊
ctx.shadowColor = 'red'//顏色
ctx.strokeText(str, 50, 200)//空心文字
let str2 = '你好呀';
ctx.font = '50px 微軟雅黑'
ctx.textAlign = 'left'
ctx.textBaseline = 'middle'
ctx.fillText(str2, 400, 200)//實(shí)心文字
</script>
</body>
10.API使用總結(jié)
10.1. canvas標(biāo)簽
<canvas width="" height="" id="">
您的瀏覽器不支持canvas,請(qǐng)更換瀏覽器奸远!
</canvas>
默認(rèn)寬度300px既棺,默認(rèn)高度 150px
10.2. canvas繪圖環(huán)境設(shè)置
getContext("2d"); 目前支持2d繪圖環(huán)境
10.3. 繪圖路徑:
- beginPath() :開始路徑
- closePath():閉合路徑
- moveTo(x,y):將觸筆移動(dòng)到x,y點(diǎn)
- lineTo(x,y):繪制到x,y點(diǎn)
- stroke(): 觸筆方法 畫線 默認(rèn)為黑色
- fill():填充方法
- rect(x,y,w,h):矩形路徑
- save():保存路徑
- restore():恢復(fù)路徑
10.4. 繪制矩形:
- fillRect(x,y,w,h) 填充實(shí)心矩形
- strokeRect(x,y,w,h) 繪制空心矩形
- clearRect(x,y,w,h) 清除矩形選區(qū)
10.5. 設(shè)置繪圖樣式:
- fillStyle: 填充顏色
- strokeStyle: 觸筆顏色
- lineWidth: 觸筆寬度(線寬)
10.6. 圖形邊界樣式:
- lineJoin : 邊界連接點(diǎn)樣式
miter(默認(rèn)值),round(圓角),bevel(斜角) - lineCap: 端點(diǎn)樣式
butt(默認(rèn)值),round(圓角),square(高度多出線寬一半)
10.7. 繪制圓形:
- arc(x,y,r,0,360,false)
x,y 圓心坐標(biāo)位置
r 圓半徑
0,360 從0度到360度 繪制一個(gè)圓形(用弧度公式)
true/false 逆時(shí)針/順時(shí)針繪圖
10.8. 繪制曲線
- arcTo(x1,y1,x2,y2,r)
x1,y1 坐標(biāo)一 x2,y2坐標(biāo)二 r圓弧半斤 - quadraticCurveTo(dx,dy,x1,y1)
貝塞爾曲線:dx,dy控制點(diǎn) x1,y1結(jié)束坐標(biāo) - bezierCurveTo(dx1,dy1,dx2,dy2,x1,y1)
貝塞爾曲線:dx1,dy1 控制點(diǎn)一 dx2,dy2控制點(diǎn)二
x1,y1結(jié)束坐標(biāo)
10.9. canvas變換
- translate(x,y)
坐標(biāo)基準(zhǔn)點(diǎn)偏移 : 從起始點(diǎn)為基準(zhǔn),移動(dòng)到當(dāng)前位置 - rotate(弧度): 旋轉(zhuǎn) 弧度公式 :角度*PI/180
- scale(wb,hb)縮放比例(縮放canvas繪制的圖片)
10.10. 繪制圖片
- 圖片預(yù)加載懒叛,獲取圖片文件
- onload事件,監(jiān)聽圖片是否加載完畢,如果加載完畢執(zhí)行第三步
- drawImage(img,x,y,w,h);繪制圖片(圖片,坐標(biāo)x,坐標(biāo)y,寬度,高度)
10.11.設(shè)置背景
- createPattern(img,平鋪方式)
平鋪方式:repeat,repeat-x,repeat-y,no-repeat
10.12. 顏色漸變
- 線性漸變:createLinearGradient(x1,y1,x2,y2)
x1,y1起始坐標(biāo)點(diǎn)
x2,y2結(jié)束坐標(biāo)點(diǎn) - 徑向漸變:createRadialGradient(x1,y1,r1,x2,y2,r2)
x1,y1,r1內(nèi)圓坐標(biāo)及半徑
x2,y2,r2外圓坐標(biāo)及半徑 - addColorStop(位置,顏色)
位置:漸變點(diǎn) 0-1之間 可多個(gè)
10.13. 繪制文本
- strokeText(文本,x,y); 繪制空心文本
- fillText(文本,x,y); 繪制實(shí)心文本
- font = "font-size font-family" 注:尺寸 字體缺一不可
- textAlign = "";文本左右對(duì)齊方式
start center end left right - textBaseline文本上下對(duì)齊方式
alphabetic 默認(rèn)丸冕。文本基線是普通的字母基線。
top 文本基線是 em 方框的頂端薛窥。胖烛。
hanging 文本基線是懸掛基線。
middle 文本基線是 em 方框的正中诅迷。
ideographic 文本基線是表意基線佩番。
bottom 文本基線是 em 方框的底端。
10.14. 陰影
- shadowOffsetX,shadowOffsetY x軸罢杉、y軸偏移
- shadowBlur 陰影模糊度
- shadowColor 陰影顏色
- 默認(rèn)顏色:rgba(0,0,0,0)
畫板例子
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body {
background-color: #000;
}
canvas {
display: block;
margin: 10px auto 0;
border: 1px solid skyblue;
background-color: #fff;
}
.box {
width: 500px;
margin: 10px auto;
}
input {
width: 50px;
height: 20px;
text-align: center;
}
</style>
</head>
<body>
<canvas width="600" height="400"></canvas>
<div class="box">
<input type="color" id='colorList'>
<!--type類型為color表示顏色選擇器 -->
<button id='color'>隨機(jī)顏色</button>
<input type="text" value='2px' id='storke' disabled> <!-- input 的阻止頁面上手動(dòng)編輯 disabled -->
<button id='add'>筆觸增加</button>
<button id='reduce'>筆觸減小</button>
<button id="clear">清屏</button>
</div>
<script>
//獲取canvas
let canvas = document.getElementsByTagName('canvas')[0];
// 獲取上下文對(duì)象(畫筆)
let ctx = canvas.getContext('2d');
//信號(hào)量 定義初始畫筆的顏色和大小
let strokeColor = '#000000';//筆觸顏色信號(hào)量
let lineWidth = 2;//筆觸大小信號(hào)量
//清屏
clear.onclock = function () {
ctx.clearRECT(0, 0, 600, 400)
}
// 顏色選擇
colorList.onchange = function () {
strokeColor = this.value;
}
//隨機(jī)顏色
color.onclick = function () {
strokeColor = '#' + Math.random().toString(16).substr(2, 6);
colorList.value = strokeColor//滑條顏色與隨機(jī)顏色保持一致
}
//加減筆觸
add.onclick = function () {
lineWidth += 2; //畫筆值與頁面顯示保持一致
storke.value = lineWidth + 'px';
}
reduce.onclick = function () {
lineWidth -= 2;
storke.value = lineWidth + 'px';
}
//繪制
canvas.onmousedown = function (ev) {
ev = ev || window.event//事件對(duì)象做兼容
//獲取鼠標(biāo)按下時(shí)距離畫布左上端點(diǎn)的距離 x 有
let x = ev.clientX - this.offsetLeft;//事件對(duì)象距離瀏覽器左邊的距離減去canvas距離瀏覽器左邊的距離
let y = ev.clientY - this.offsetTop;
//繪制
ctx.strokeStyle = strokeColor;
ctx.lineWidth = lineWidth;
//開啟新路徑
ctx.beginPath();
ctx.moveTo(x, y);//鼠標(biāo)按下 繪制的坐標(biāo)就移動(dòng)到x y位置
document.onmousemove = function (ev) {
//使用外部this方法一 let This = this;定義一個(gè)大This趟畏,將外部this傳給里面的This
//使用外部this方法二 .bind(this)
//使用外部this方法三 箭頭函數(shù) (ev)=>{} 箭頭函數(shù)沒有this,只能向上找this
ev = ev || window.event;
let x = ev.clientX - this.offsetLeft;
let y = ev.clientY - this.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
}.bind(this)
//現(xiàn)在的線段是由鼠標(biāo)拖出來的
document.onmouseup = function () {//清理事件滩租。鼠標(biāo)抬起說明畫完了拱镐,清理默認(rèn)事件.onmousedown事件是入口不清理
this.onmousemove = null;
this.onmouseup = null;
}
}
</script>
</body>
</html>