Canvas

概述

Canvas API 提供了一个通过 Js 和 html 的元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。我在此仅介绍关于绘制 2d 的图片功能,若想绘制 3d 图形,请读者自行阅读 Three.js 的专栏

示例:

1
2
3
4
5
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");

ctx.fillStyle = "green";
ctx.fillRect(10, 10, 150, 100);

基本用法

canvas 标签

1
<canvas id="tutorial" width="150" height="150"></canvas>

canvas 元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。canvas 起初是空白的。为了展示,首先脚本需要找到渲染上下文,然后在它的上面绘制。

通过getContext()方法来获得渲染上下文和它的绘制功能;

1
2
var canvas = document.getElementById("tutorial");
var ctx = canvas.getContext("2d");

绘制图形

canvas 仅支持两种图形绘画,矩形和路径(由一系列的点所连成的线段);

  • 矩形:

    1
    2
    3
    4
    5
    6
    7
    8
    // 绘制一个填充的矩形
    fillRect(x, y, width, height);

    // 绘制一个矩形的边框
    strokeRect(x, y, width, height);

    // 清除一个指定的区域,使得清除的位置完全透明
    clearRect(x, y, width, height);
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    function draw() {
    const canvas = document.getElementById("canvas");
    if (canvas.getContext) {
    const ctx = canvas.getContext("2d");

    ctx.fillRect(25, 25, 100, 100);
    ctx.clearRect(45, 45, 60, 60);
    ctx.strokeRect(50, 50, 50, 50);
    }
    }
  • 路径:

    beginPath():新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。

    closePath():闭合路径之后图形绘制命令又重新指向到上下文中。

    stroke():通过线条来绘制图形轮廓。

    fill():通过填充路径的内容区域生成实心的图形。

    moveTo(x,y):移动笔触

    lineTo(x,y):从当前位置指向(x,y)画一条直线

    arc(x,y,radius,startAngle,endAngle,anticlockwise):画一个以(x,y)为圆心的以 radius 为半径的圆弧(圆),从 startAngle 开始到 endAngle 结束,按照 anticlockwise 给定的方向(默认为顺时针)来生成。

    这里详细介绍一下 arc 方法,该方法有六个参数:x,y为绘制圆弧所在圆上的圆心坐标。radius为半径。startAngle以及endAngle参数用弧度定义了开始以及结束的弧度。这些都是以 x 轴为基准。参数anticlockwise为一个布尔值。为 true 时,是逆时针方向,否则顺时针方向。

Path2D 对象:用来缓存或记录绘画命令,这样你将能快速地回顾路径。

​ 生成 path2D 对象:

1
2
3
new Path2D(); // 空的 Path 对象
new Path2D(path); // 克隆 Path 对象
new Path2D(d); // 从 SVG 建立 Path 对象

色彩

fillStyle=color:填充图形颜色

strokeStyle=color:设置图形轮廓的颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function draw() {
const ctx = document.getElementById("canvas").getContext("2d");
// 画背景
ctx.fillStyle = "#FD0";
ctx.fillRect(0, 0, 75, 75);
ctx.fillStyle = "#6C0";
ctx.fillRect(75, 0, 75, 75);
ctx.fillStyle = "#09F";
ctx.fillRect(0, 75, 75, 75);
ctx.fillStyle = "#F30";
ctx.fillRect(75, 75, 75, 75);
ctx.fillStyle = "#FFF";

// 设置透明度值的方法
ctx.globalAlpha = 0.2;

// 画半透明圆
for (let i = 0; i < 7; i++) {
ctx.beginPath();
ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
ctx.fill();
}
}

canvas 还可以绘制文本,使用图片、音频等,关于怎样操作我这里就不多说明了,例如使用图片,我们知道 canvas 可以使用图片之后,当我们需要对特定的图片进行操作时,只需要想到 canvas 可以处理就足够了,至于如何操作,我们不需要了解,查找官方文档或者其他资料就可以


变形和组合:移动、缩放、旋转,我们需要用到的时候查找相关文档就可以

我们先了解两个方法状态保存 save()和状态恢复 restore();

save():保存画布所有状态,会将所有状态信息保存到栈当中

restore():恢复状态

我们展示一个完整示例

定义一个 canvas 画布:

1
<canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
let raf;

const ball = {
x: 100,
y: 100,
vx: 5,
vy: 2,
radius: 25,
color: "blue",
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = this.color;
ctx.fill();
},
};

function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ball.draw();
ball.x += ball.vx;
ball.y += ball.vy;
ball.vy *= 0.99;
ball.vy += 0.25;

if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
ball.vy = -ball.vy;
}
if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
ball.vx = -ball.vx;
}

raf = window.requestAnimationFrame(draw);
}

canvas.addEventListener("mouseover", (e) => {
raf = window.requestAnimationFrame(draw);
});

canvas.addEventListener("mouseout", (e) => {
window.cancelAnimationFrame(raf);
});

ball.draw();

canvas 还可以直接操作像素,关于其用法请查阅相关文档,我们的 canvas 的内容就到此为此了。接下来我们将会了解其他绘图的第三方库。