如何建立一个canvas
- 首先在页面写一个canvas标签,设置宽度和高度,如果不设置属性,canvas会初始化宽度为300像素和高度为150像素,我们这里设置的宽高是400*300像素。注意: canvas 中的文字,会在不支持canvas标签的浏览器中展示,在支持canvas的浏览器中,标签不会展示。
- 获取页面的canvas元素,document.getElementById(‘canvas’) 获取canvas获取元素, canvas元素通过调用getContext方法,传入’2d’参数,获取 CanvasRenderingContext2D 实例,为 <canvas> 元素的绘图表面提供2D渲染上下文,能够在上面进行线,图形,图像等元素的绘制。
<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>
</head>
<body>
<canvas id="canvas" width="400" height="300">
您的浏览器不支持canvas
</canvas>
<script>
const canvas = document.getElementById("canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
}
</script>
</body>
</html>
给canvas添加一个阴影的属性,方便进行查看。
<style>
#canvas {
box-shadow: 0px 0px 6px #ccc;
}
</style>
canvas 的创建主要是以上两步,拿绘画做对比,第一步就像我们拿了一个画板,第二部就好比我们把绘画的纸铺在画板上,可以在纸上进行作画。下面就让我们进行一些实践。
画直线
画直线前,让我们先了解几个函数:
1.moveTo()
初始化起始点的位置,传入坐标的x和y的值。
2.lineTo()
直线的终点位置,传入坐标的x和y的值。
3.stroke()
通过线条将相邻的两个点连接成一条直线。
const canvas = document.getElementById("canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
// 绘制一条从起点(x: 50, y:50)到 另一个点(x: 200, y:200)的直线
ctx.moveTo(50, 50);
ctx.lineTo(200, 200);
ctx.stroke();
}
通过以上代码,我们完成了一条从起始点 (50, 50) 到 (200, 200)的直线,如图所示:
画三角形
画三角形就是画三条首尾相接的直线,通过 stroke 描边新形成三角形的形状,代码和效果图如下:
const canvas = document.getElementById("canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.moveTo(50, 50);
ctx.lineTo(200, 200);
ctx.lineTo(50, 200);
ctx.lineTo(50, 50);
ctx.stroke();
}
画长方形
canvas 提供了三种绘制长方形的方法:
- strokeRect(x, y, width, height) 绘制一个矩形的边框
- fillRect(x, y, width, height) 绘制一个填充的矩形
- clearRect(x, y, width, height) 清除指定矩形区域,让清除部分完全透明。
其中的参数x, y对应矩形的左上顶点的横坐标值和纵坐标值, width, height 分别对应长方形的宽和高。
绘制边框矩形
const canvas = document.querySelector("#canvas")
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.strokeRect(50, 50, 300, 200)
}
通过向 strokeRect 方法中传递参数横坐标50px, 纵坐标50px,宽度300px,高度200px, 绘制矩形的边框如下:
绘制填充的矩形
const canvas = document.querySelector("#canvas")
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.fillRect(50, 50, 300, 200)
}
通过向 fillRect 方法中传递参数横坐标50px, 纵坐标50px,宽度300px,高度200px, 绘制矩形的填充区域如下:
我们可以看到 strokeRect 和 fillRect 的区别是 stroke 和 fill , 在英文中的意思分别是描边和填充。通俗的理解,描边就是把点连在一起形成一个边框的正方形,填充就是把多个点所在的区域内都填满颜色。
清除矩形区域
const canvas = document.querySelector("#canvas")
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.fillRect(50, 50, 300, 200)
// 清除掉 左上顶点在(100, 100) 宽高分别为200和100的矩形区域
ctx.clearRect(100, 100, 200, 100)
}
我们在上边绘制好的填充矩形中,清除掉左上顶点在(100, 100) 宽高分别为 200px 和 100px 的矩形区域,效果如下:
绘制弧形和圆
canvas 提供了绘制弧形和圆的方法:arc(x, y, radius, startAngle, endAngle, anticlockwise),x 和 y 值是圆心的坐标,radius是圆形的半径,startAngle 是圆弧或圆开始的位置,以X轴方向进行计算,endAngle 是圆弧的结束位置。anticlockwise 是绘制的方向(默认值为false,从顺时针方向进行绘制)。
需要注意的是,startAngle 和 endAngle 的值代表的是弧度,弧度的计算公式为:弧度=(Math.PI/180)*角度。
const canvas = document.querySelector("#canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.arc(100, 100, 50, 0, Math.PI / 2, false)
ctx.stroke()
}
以(100, 100)为圆心,50px半径,起始位置0度,结束位置Math.PI / 2, 顺时针绘制弧形如下:
我们再在圆心(200, 100)的位置画一个半径50px,其实位置是 0 到 Math.PI*3/4 位置,逆时针的弧形。
const canvas = document.querySelector("#canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.arc(100, 100, 50, 0, Math.PI / 2, false)
ctx.stroke()
ctx.arc(250, 100, 50, 0, Math.PI * 3 / 4, true)
ctx.stroke()
}
绘制的图形如上所示,效果不是想象的那样重新画一个弧形,而是两个弧形连接在了一起。
这是因为绘制图像的时候没有结束上一条路径的绘制,所以就连在了一起。举个例子,我们在纸上画线条,当我们第一个弧完成后,不提起笔,就去画第二条弧,两个弧就会连在一起,向以上的效果。这就要用到两个方法:
beginPath
生成一条新路径,像我们把笔放在纸上。
closePath
闭合一条路径,像我们把笔从纸上拿起来。
我们重新绘制上边的两个弧形,效果如下:
const canvas = document.querySelector("#canvas");
if (canvas.getContext) {
// 获取绘图上下文
var ctx = canvas.getContext("2d");
ctx.beginPath()
ctx.arc(100, 100, 50, 0, Math.PI / 2, false)
ctx.stroke()
ctx.closePath()
ctx.beginPath()
ctx.arc(250, 100, 50, 0, Math.PI * 3 / 4, true)
ctx.stroke()
ctx.closePath()
}
如图,我们通过 beginPath 创建路径 和 closePath 闭合路径,分别在各自的路径内进行绘制,完成了两个独立的圆形。这个过程很像,我们将笔放在纸上(beginPath)开始绘制,然后进行图形的绘制(ctx.lineTo, ctx.arc, ctx.strokeRect),最后笔离开纸完成这一段的绘制(closePath)。不断的重复, beginPath => 绘制 => closePath 完成多个图形的绘制。