HTML5 画布形状
最后修改于 2023 年 7 月 17 日
在本部分 HTML5 画布教程中,我们创建了一些基本和更高级的几何形状。
矩形
第一个程序绘制了两个矩形。
<!DOCTYPE html> <html> <head> <title>HTML5 canvas rectangles</title> <script> function draw() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillStyle = 'gray'; ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 100, 60); } </script> </head> <body onload="draw();"> <canvas id="myCanvas" width="350" height="250"> </canvas> </body> </html>
示例使用 drawRect
方法绘制矩形。
ctx.fillStyle = 'gray';
矩形的内部以灰色填充。
ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 100, 60);
fillRect
方法用于绘制正方形和矩形。前两个参数是形状的 x 和 y 坐标。最后两个参数是形状的宽度和高度。

基本形状
在下面的程序中,我们绘制了一些基本形状。
<!DOCTYPE html> <html> <head> <title>HTML5 canvas shapes</title> <script> function draw() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillStyle = 'gray'; ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 90, 60); ctx.beginPath(); ctx.arc(250, 40, 32, 0, 2*Math.PI); ctx.fill(); ctx.beginPath(); ctx.moveTo(10, 160); ctx.lineTo(90, 160); ctx.lineTo(50, 110); ctx.closePath(); ctx.fill(); ctx.save(); ctx.scale(2, 1); ctx.beginPath(); ctx.arc(72, 130, 25, 0, 2*Math.PI); ctx.fill(); ctx.restore(); ctx.beginPath(); ctx.arc(250, 120, 40, 0, Math.PI); ctx.fill(); } </script> </head> <body onload="draw();"> <canvas id="myCanvas" width="350" height="350"> </canvas> </body> </html>
画布上绘制了六种不同的形状。
ctx.fillStyle = 'gray';
形状将以灰色填充。
ctx.fillRect(10, 10, 60, 60); ctx.fillRect(100, 10, 90, 60);
矩形使用 fillRect
方法绘制。矩形是唯一一个不使用 beginPath
方法初始化的形状。
ctx.beginPath(); ctx.arc(250, 40, 32, 0, 2*Math.PI); ctx.fill();
圆使用 arc
方法绘制。该方法将一个弧添加到创建的路径中。前两个参数定义了弧的中心点的 x 和 y 坐标。接下来的两个参数指定了弧的起始角和结束角。角度以弧度定义。最后一个参数是可选的;它指定了绘制弧的方向。默认方向是顺时针。
ctx.beginPath(); ctx.moveTo(10, 160); ctx.lineTo(90, 160); ctx.lineTo(50, 110); ctx.closePath(); ctx.fill();
使用 moveTo
和 lineTo
方法,我们绘制了一个三角形。closePath
方法会将画笔移回到当前子路径的起点。在我们的例子中,它完成了三角形的形状。
ctx.save(); ctx.scale(2, 1); ctx.beginPath(); ctx.arc(72, 130, 25, 0, 2*Math.PI); ctx.fill(); ctx.restore();
椭圆形是通过缩放圆形绘制的。这些操作放在 save
和 restore
方法之间,这样缩放操作就不会影响后续的绘图。
ctx.beginPath(); ctx.arc(250, 120, 40, 0, Math.PI); ctx.fill();
最后一个形状,一个半圆,是使用 arc
方法绘制的。

饼图
饼图是一种圆形图表,分为多个扇形以说明数字比例。
<!DOCTYPE html> <html> <head> <title>HTML5 canvas pie chart</title> <style> canvas {background: #bbb} </style> <script> function draw() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); var beginAngle = 0; var endAngle = 0; var data = [170, 60, 45]; var total = 0; var colours = ["#95B524", "#AFCC4C", "#C1DD54"]; const SPACE = 10; for (var i = 0; i < data.length; i++) { total += data[i]; } ctx.strokeStyle = 'white'; ctx.lineWidth = 2; for (var j = 0; j < data.length; j++) { endAngle = beginAngle + (Math.PI * 2 * (data[j] / total)); ctx.fillStyle = colours[j]; ctx.beginPath(); ctx.moveTo(canvas.width/2, canvas.height/2); ctx.arc(canvas.width/2, canvas.height/2, canvas.height/2 - SPACE, beginAngle, endAngle, false); ctx.closePath(); ctx.fill(); ctx.stroke(); beginAngle = endAngle; } } </script> </head> <body onload="draw();"> <canvas id="myCanvas" width="350" height="300"> </canvas> </body> </html>
示例绘制了一个饼图。它有三个扇区,以不同深浅的绿色填充。
<style> canvas {background: #bbb} </style>
为了让图表的白色轮廓清晰可见,我们将画布的背景颜色更改为灰色。
var data = [170, 60, 45];
这是饼图说明的数据。
const SPACE = 10;
SPACE
常量是饼图到画布边界的距离。
endAngle = beginAngle + (Math.PI * 2 * (data[j] / total));
该公式计算当前绘制扇形的结束角度。
ctx.moveTo(canvas.width/2, canvas.height/2); ctx.arc(canvas.width/2, canvas.height/2, canvas.height/2 - SPACE, beginAngle, endAngle, false); ctx.closePath();
使用三个方法绘制当前扇形:moveTo
、arc
和 closePath
。
ctx.fill(); ctx.stroke();
我们同时绘制了形状的内部和轮廓。
beginAngle = endAngle;
对于下一个扇形,最后一个结束角度成为起始角度。

星形
以下示例创建了一个星形。
<!DOCTYPE html> <html> <head> <title>HTML5 canvas star shape</title> <script> function draw() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.fillStyle = 'gray'; var points = [ [ 0, 85 ], [ 75, 75 ], [ 100, 10 ], [ 125, 75 ], [ 200, 85 ], [ 150, 125 ], [ 160, 190 ], [ 100, 150 ], [ 40, 190 ], [ 50, 125 ], [ 0, 85 ] ]; var len = points.length; ctx.beginPath(); ctx.moveTo(points[0][0], points[0][1]); for (var i = 0; i < len; i++) { ctx.lineTo(points[i][0], points[i][1]); } ctx.fill(); } </script> </head> <body onload="draw();"> <canvas id="myCanvas" width="350" height="250"> </canvas> </body> </html>
星形由一系列点创建。
var points = [ [ 0, 85 ], [ 75, 75 ], [ 100, 10 ], [ 125, 75 ], [ 200, 85 ], [ 150, 125 ], [ 160, 190 ], [ 100, 150 ], [ 40, 190 ], [ 50, 125 ], [ 0, 85 ] ];
这是星形的坐标。
ctx.moveTo(points[0][0], points[0][1]);
我们使用 moveTo
方法移动到形状的初始坐标。
for (var i = 0; i < len; i++) { ctx.lineTo(points[i][0], points[i][1]); }
在这里,我们使用 lineTo
方法连接星形的所有坐标。
ctx.fill();
fill
方法使用定义的(灰色)颜色填充星形的内部。

三个圆
可以使用复合(compositing)来创建新形状。复合是决定画布上形状混合方式的规则。
<!DOCTYPE html> <html> <head> <title>HTML5 Canvas three circles</title> <script> function draw() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.lineWidth = 3; ctx.fillStyle = 'gray'; ctx.beginPath(); ctx.arc(90, 90, 60, 0, 2*Math.PI); ctx.stroke(); ctx.beginPath(); ctx.arc(120, 150, 60, 0, 2*Math.PI); ctx.stroke(); ctx.beginPath(); ctx.arc(150, 100, 60, 0, 2*Math.PI); ctx.stroke(); ctx.globalCompositeOperation='destination-out'; ctx.beginPath(); ctx.arc(90, 90, 60, 0, 2*Math.PI); ctx.fill(); ctx.beginPath(); ctx.arc(120, 150, 60, 0, 2*Math.PI); ctx.fill(); ctx.beginPath(); ctx.arc(150, 100, 60, 0, 2*Math.PI); ctx.fill(); } </script> </head> <body onload="draw();"> <canvas id="myCanvas" width="400" height="350"> </canvas> </body> </html>
该示例通过组合三个圆的轮廓来创建一个形状。这三个圆会重叠。
ctx.beginPath(); ctx.arc(90, 90, 60, 0, 2*Math.PI); ctx.stroke();
画布上绘制了一个圆。
ctx.globalCompositeOperation='destination-out';
复合操作设置为 destination-out
。在此模式下,当源和目标不重叠时,目标将显示在所有地方。在其他所有地方,将显示透明度。
ctx.beginPath(); ctx.arc(90, 90, 60, 0, 2*Math.PI); ctx.fill();
现在,相同的圆以灰色填充。新的绘图将在重叠的地方擦除现有绘图。结果是,只剩下轮廓。

在本部分 HTML5 画布教程中,我们涵盖了一些 HTML5 画布中的基本和更高级的形状。