canvas
<canvas>
元素
<canvas id="tutorial" width="150" height="150"></canvas>
<canvas>
元素只有两个属性,width
和height
。这些都是可选的,也可以使用DOM 属性设置。如果未指定no width
和height
属性,则画布最初将为300像素宽和150像素高。可以通过CSS任意调整元素的大小
渲染上下文
素创建一个固定大小的绘图表面暴露一个或多个渲染上下文,其被用于创建和操纵所示的内容
getContext()
,用于获得呈现上下文和它的绘制功能。getContext()
采用一个参数,即上下文的类型。对于2D图形(例如本教程介绍的图形
语法:
var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
浏览器兼容性
通过简单地测试getContext()
方法的存在来以编程方式检查支持
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// drawing code here
} else {
// canvas-unsupported code here
}
小案例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Canvas tutorial</title>
<script type="text/javascript">
function draw() {
var canvas = document.getElementById('tutorial');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
}
}
</script>
<style type="text/css">
canvas { border: 1px solid black; }
</style>
</head>
<body onload="draw();">
<canvas id="tutorial" width="150" height="150"></canvas>
</body>
</html>
通过侦听load
文档上的事件来完成的。这个功能,或者一个喜欢它,也可以使用所谓的window.setTimeout()
,window.setInterval()
或任何其他事件处理程序,只要页面已经被第一次加载。
绘制两个相交的矩形,其中一个具有alpha透明度。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<script type="application/javascript">
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'rgb(200, 0, 0)';
ctx.fillRect(10, 10, 50, 50);
ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
ctx.fillRect(30, 30, 50, 50);
}
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="150" height="150"></canvas>
</body>
</html>
网格
可以吧canvas元素看成指定的片区域把区域内看成有网格左上到右上文x轴
左上到左下为y轴(x,y);如此表示坐标
绘制矩形的三个函数
``仅支持两种基本形状:矩形和路径(由线连接的点的列表)。所有其他形状必须通过组合一个或多个路径来创建。
fillRect(x, y, width, height)
绘制一个填充的矩形。
strokeRect(x, y, width, height)
绘制矩形轮廓。
clearRect(x, y, width, height)
清除指定的矩形区域,使其完全透明。
x
并y
指定矩形左上角在画布上的位置(相对于原点)。width
并height
提供矩形的大小。
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.fillRect(25, 25, 100, 100);
ctx.clearRect(45, 45, 60, 60);
ctx.strokeRect(50, 50, 50, 50);
}
}
绘制路径
路径是由线段连接的点的列表,这些线段可以具有不同的形状(弯曲或不弯曲),不同的宽度和不同的颜色。路径甚至子路径都可以关闭
**思路过程 **
- 首先,创建路径。
- 然后,您可以使用[绘图命令]来绘制路径。
- 创建路径后,您可以描画或填充路径以进行渲染。
操作步骤方法
-
beginPath()
创建一个新路径。创建之后,将来的绘图命令将直接进入路径并用于构建路径。
路径方法
语法:
void ctx.beginPath();
- 例子
创建两个路径
再开始前调用beginPath()方法
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body onload="draw();"> <canvas id="canvas" width="150" height="150"></canvas> </body> <script type="application/javascript"> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // First path ctx.beginPath(); ctx.strokeStyle = 'blue'; ctx.moveTo(20, 20); ctx.lineTo(200, 20); ctx.stroke(); // Second path ctx.beginPath(); ctx.strokeStyle = 'green'; ctx.moveTo(20, 20); ctx.lineTo(120, 120); ctx.stroke(); </script> </html>
结果:
为对象设置不同路径的方法。
-
closePath()
尝试从当前点到当前子路径的起点添加一条直线。如果形状已经闭合或只有一个点,则此功能不执行任何操作。此方法不会直接在画布上绘制任何内容
向路径添加一条直线,转到当前子路径的起点。
-
例子
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body onload="draw();"> <canvas id="canvas" width="400" height="400"></canvas> </body> <script type="application/javascript"> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.moveTo(20, 140); ctx.lineTo(120, 10); ctx.lineTo(220, 140); ctx.closePath(); ctx.stroke(); </script> </html>
此例子中
closePath()
方法创建三角形的底面,该方法会自动连接形状的第一个点和最后一个点。结果如图:
-
* 第二个案例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(240, 20, 40, 0, Math.PI);
ctx.moveTo(100, 20);
ctx.arc(60, 20, 40, 0, Math.PI);
ctx.moveTo(215, 80);
ctx.arc(150, 80, 65, 0, Math.PI);
ctx.closePath();
ctx.lineWidth = 6;
ctx.stroke();
</script>
</html>
结果:
stroke()
通过抚摸轮廓来绘制形状。stroke() 方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色。
fill()
填充图形
通过填充路径的内容区域绘制实体形状。
语法:
void ctx.fill([fillRule]);
void ctx.fill(path [, fillRule]);
-
fillRule
- “nonzero”:非零缠绕规则。默认规则。
**"evenodd"
:奇数缠绕规则。
-
path
Path2D
填补的道路。- 例子
填充矩形本示例使用该
fill()
方法填充矩形。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
ctx.rect(10, 10, 150, 100);
ctx.fill();
</script>
</html>
运行结果:
具体步骤
第一步:
调用beginPath()
。在内部,路径存储为一起形成形状的子路径(线,弧等)的列表。每次调用此方法时,列表都会重置,我们可以开始绘制新形
第二步:
调用实际指定要绘制路径的方法
第三步:
(可选步骤)是closePath()
。此方法尝试通过绘制从当前点到起点的直线来闭合形状。如果形状已经关闭或列表中只有一个点,则此功能不执行任何操作。
画一个三角形:
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(75, 50);
ctx.lineTo(100, 75);
ctx.lineTo(100, 25);
ctx.fill();
}
}
移动笔
该功能是一个会成为上述路径列表的一部分moveTo()
您可能最能想到的是将笔或铅笔从一张纸上的一个位置提起,然后放在另一张纸上。
moveTo(x, y)
移动笔由指定的坐标x
和y
。
初始化或beginPath()
调用画布时,通常将需要使用该moveTo()
函数将起点放置在其他位置。我们还可以moveTo()
用来绘制未连接的路径。看看下面的笑脸。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
ctx.moveTo(110, 75);
ctx.arc(75, 75, 35, 0, Math.PI, false); // Mouth (clockwise)
ctx.moveTo(65, 65);
ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Left eye
ctx.moveTo(95, 65);
ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Right eye
ctx.stroke();
}
}
</script>
</html>
运行结果:
线数
lineTo()方法来绘制直线
lineTo(x, y)
绘制一条从当前绘图位置到所指定的位置的线x
和y
。
案例:
绘制两个三角形一个实心的一个空心的
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
function draw() {
var canvas=document.getElementById('canvas');
if(canvas.getContext){
var ctx=canvas.getContext('2d');
//绘制实心的
ctx.beginPath();
ctx.moveTo(25,25)
ctx.lineTo(105,25);
ctx.lineTo(25,105);
// 绘制实心的
ctx.fill();
//绘制空心的
ctx.beginPath();
ctx.moveTo(125, 125);
ctx.lineTo(125, 45);
ctx.lineTo(45, 125);
// 连接起始点
ctx.closePath();
//绘制形状
ctx.stroke();
}
}
</script>
</html>
效果如下:
弧线
要绘制圆弧或圆,我们使用arc()
或arcTo()
方法。
语法:
void ctx.arc(x, y, radius, startAngle, endAngle [, anticlockwise]);
该arc()
方法创建一个以(x, y)
半径为中心的圆弧。路径从开始于,在结束于,并按照给出的方向(默认为顺时针)行进
-
参量
x
圆弧中心的水平坐标
y
圆弧中心的垂直坐标。
radius
圆弧的半径。必须是积极的。
startAngle
从正x轴开始测量的弧度起始弧度的角度(以弧度表示)。
endAngle
从正x轴开始测量,弧结束的弧度角(以弧度表示)
anticlockwise
可选的可选的
Boolean
。如果为true
,则在起始角度和终止角度之间逆时针绘制圆弧。默认值为false
(顺时针)。 -
例子
画一个完整的圆
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body onload="draw();"> <canvas id="canvas" width="400" height="400"></canvas> </body> <script type="application/javascript"> function draw() { const canvas = document.querySelector('canvas'); const ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.arc(100, 75, 50, 0, 2 * Math.PI); ctx.stroke(); } </script> </html>
贝塞尔曲线和二次曲线
贝塞尔曲线大概就是ps中钢笔工具那个曲线
quadraticCurveTo(cp1x, cp1y, x, y)
从当前笔位置到由指定的结束点绘制的二次贝塞尔曲线x
,并y
使用由指定的控制点cp1x
和cp1y
。
例子:
此示例显示了如何绘制二次贝塞尔曲线。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
//贝塞尔曲线
ctx.beginPath();
ctx.moveTo(50, 20);
ctx.quadraticCurveTo(230, 30, 50, 100);
ctx.stroke();
// 起点和终点
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(50, 20, 5, 0, 2 * Math.PI); //起始点
ctx.arc(50, 100, 5, 0, 2 * Math.PI); // 终点
ctx.fill();
// 控制点
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(230, 30, 5, 0, 2 * Math.PI);
ctx.fill();
</script>
</html>
运行结果:
二次贝塞尔曲线
语法:
void ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
cp1x
第一个控制点的x轴坐标。
cp1y
第一个控制点的y轴坐标。
cp2x
第二个控制点的x轴坐标。
cp2y
第二个控制点的y轴坐标。
x
终点的x轴坐标。
y
终点的y轴坐标。
案例:
绘制一个三次贝塞尔曲线
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
//定义画布和上下文
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 将点定义为{x,y}
let start = { x: 50, y: 20 };
let cp1 = { x: 230, y: 30 };
let cp2 = { x: 150, y: 80 };
let end = { x: 250, y: 100 };
// 三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(start.x, start.y);
ctx.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, end.x, end.y);
ctx.stroke();
// 起始点和终止点
ctx.fillStyle = 'blue';
ctx.beginPath();
ctx.arc(start.x, start.y, 5, 0, 2 * Math.PI); // 起始点
ctx.arc(end.x, end.y, 5, 0, 2 * Math.PI); // 终止点
ctx.fill();
// 控制点
ctx.fillStyle = 'red';
ctx.beginPath();
ctx.arc(cp1.x, cp1.y, 5, 0, 2 * Math.PI); // 控制点一
ctx.arc(cp2.x, cp2.y, 5, 0, 2 * Math.PI); // 控制点二
ctx.fill();
</script>
</html>
结果
案例二:
渲染语音气球
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body onload="draw();">
<canvas id="canvas" width="400" height="400"></canvas>
</body>
<script type="application/javascript">
function draw() {
var canvas = document.getElementById('canvas');
if (canvas.getContext) {
var ctx = canvas.getContext('2d');
// 二次贝塞尔曲线案例
ctx.beginPath();
ctx.moveTo(75, 25);
ctx.quadraticCurveTo(25, 25, 25, 62.5);
ctx.quadraticCurveTo(25, 100, 50, 100);
ctx.quadraticCurveTo(50, 120, 30, 125);
ctx.quadraticCurveTo(60, 120, 65, 100);
ctx.quadraticCurveTo(125, 100, 125, 62.5);
ctx.quadraticCurveTo(125, 25, 75, 25);
ctx.stroke();
}
}
</script>
</html>
效果
长方形
rect(x, y, width, height)
绘制一个矩形,其左上角由(x
,y
)指定,width
并带有指定的和height
。
在执行此方法之前,将moveTo()
使用参数(x,y)自动调用该方法。换句话说,当前笔位置会自动重置为默认坐标。