初识 Canvas(使用 Canvas 绘制直线图形)
- 参考
- 描述
- Canvas
- Canvas 与 SVG
- Canvas 元素
- 替补元素
 
 
- 使用
- 检测
 
 
 
 
- 绘制直线图形
- 直线
- 同时绘制多条直线
- 指定起点
- 首尾相接
 
- 多彩的直线
 
 
 
 
- 矩形
- 描边矩形
- 填充矩形
- 结合体
- 清除矩形区域
 
 
- 多边形
参考
描述
Canvas
你可以使用 JavaScript 在 HTML 5 元素 Canvas 上进行 2D 或 3D 图形的绘制。Canvas 最早由 Apple 引入 WebKit,用于 Mac OS X 的 Dashboard,随后被各个浏览器实现。如今,所有主流的浏览器都支持它。
Canvas 与 SVG
HTML 5 有两个主要的 2D 图形技术,即 Canvas 与 SVG 。两者的区别如下:
| 项目 | Canvas | SVG | 
|---|---|---|
| 生成方式 | 通过 JavaScript 动态生成。 | 使用 XML 静态描述。 | 
| 结果 | 位图 | 矢量图 | 
| 重绘 | 若发生修改,Canvas 需要进行重绘 | 不需要重绘 | 
Canvas 元素
Canvas 是一个行内块元素,即该元素的 display 属性的值为 inline-block 。默认情况下,Canvas 元素的宽与高分别为 300px 、150px 。在创建 Canvas 元素时,你可以通过该元素的属性 width 为该元素指定宽度,使用属性 height 元素为该元素指定高度。
替补元素
Canvas 元素已被大多数浏览器所支持,如果你担心旧版本浏览器无法显示 Canvas 元素,你可以在 Canvas 元素内部嵌套另一个元素(替补元素)。如果浏览器支持 Canvas 元素,则 Canvas 元素内部嵌套的另一个元素将被忽略;如果浏览器不支持 Canvas 元素,则 Canvas 元素将被忽略,而其内部的元素将正常发挥作用。例如:
<canvas id="canvas" width="600px" height="400px">
    <h1>当前浏览器不支持 HTML 5 元素 Canvas,如果 Canvas 元素影响了您的体验,请更换浏览器访问本网页。</h1>
</canvas>
注:
请不要省略 canvas 元素的结束标签 </canvas>,否则该元素后的元素都将被认为是 canvas 元素的替补元素。如果浏览器支持 canvas 元素,则 canvas 之后的元素都将无法正常显示。
使用
canvas 元素创造了一个固定大小的画布,它公开了一个或多个渲染上下文,其可以用来绘制和处理要展示的内容。
 canvas 起初是空白的。为了展示,首先 JavaScript 脚本需要找到渲染上下文,然后在它的上面绘制。canvas 元素对应的 DOM 对象有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。该方法可以接收一个参数,用于指定上下文的类型。对于 2D 图像的绘制,你可以使用 2d 作为该函数的参数。
检测
你可以通过检测 canvas 元素对应的 DOM 对象的 getContext 属性是否为 undefined 来判断该浏览器是否支持 canvas,并依次决定下一步的操作。
index.html
<!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>初识 Canvas(使用 canvas 绘制直线图形)</title>
    <style>
        *{
            /* 去除元素的部分默认属性 */
            margin: 0px;
            padding: 0px;
            box-sizing: border-box;
        }
        body{
            /* 使 canvas 元素在浏览器视口(可视区域)居中显示 */
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        canvas{
            /* 为 canvas 元素设置边框并为边框设置圆角 */
            border: 2px solid dodgerblue;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600px" height="400px">
        <h1>当前浏览器不支持 HTML 5 元素 Canvas,如果 Canvas 元素影响了您的体验,请更换浏览器访问本网页。</h1>
    </canvas>
    <script src="./index.js"></script>
</body>
</html>
index.js
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 的渲染上下文
    const canvas = canvas_e.getContext('2d');
}else{
    console.log('Canvas Not Supported')
}
绘制直线图形
使用 canvas 绘制不同的直线图形,需要变化的仅仅只是 JavaScript 部分的代码。在本篇文章的后续讲解中,默认 HTML 部分使用如下代码:
index.html
<!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>初识 Canvas(使用 canvas 绘制直线图形)</title>
    <style>
        *{
            /* 去除元素的部分默认属性 */
            margin: 0px;
            padding: 0px;
            box-sizing: border-box;
        }
        body{
            /* 使 canvas 元素在浏览器视口(可视区域)居中显示 */
            min-height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        canvas{
            /* 为 canvas 元素设置边框并为边框设置圆角 */
            border: 2px solid dodgerblue;
            border-radius: 5px;
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="600px" height="400px">
        <h1>当前浏览器不支持 HTML 5 元素 Canvas,如果 Canvas 元素影响了您的体验,请更换浏览器访问本网页。</h1>
    </canvas>
    <script src="./index.js"></script>
</body>
</html>
直线
在 Canvas 中,我们可以使用 canvas 元素对应的 DOM 对象的 lineTo() 及 moveTo() 方法的配合来绘制直线。
 其中,lineTo() 用于描述画笔的走向,而 moveTo() 则用于移动画笔。lineTo() 及 moveTo() 函数均接收两个参数,其中第一个参数为 X 轴坐标,第二个参数为 Y 轴坐标。坐标 (0, 0) 位于画布的左上角。
注:
- 在 Canvas 的坐标系中,Y 轴坐标有上到下是递增的。

- canvas 元素对应的 DOM 对象的方法在需要距离的地方直接使用数字即可,默认单位为 像素 。
- 画笔没有默认的起始位置。因此,在绘制图形之前,你必须使用 moveTo() 方法将画笔移动至画布中的某个地方,否则图形将无法被成功绘制。
- 使用 moveTo() 与 lineTo() 方法仅仅只是对线条的描述,如果需要将描述付诸实际还需要在对线条描述完成后使用 stroke() 方法将线条画出来。
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    // 指定开始绘制的起始地点
    canvas.moveTo(0, 0);
    // 移动画笔至画布中坐标为 (200px, 200px) 的位置
    canvas.lineTo(200, 200);
    // 开始对图形进行绘制
    canvas.stroke();
}else{
    console.log('Canvas Not Supported')
}
效果:

同时绘制多条直线
指定起点
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.moveTo(0, 0);
    canvas.lineTo(200, 200);
    canvas.moveTo(0, 0);
    canvas.lineTo(150, 300);
    canvas.stroke();
}else{
    console.log('Canvas Not Supported')
}
注:
你可以在每次使用 lineTo() 方法对直线的轨迹进行描述前通过 moveTo() 方法为该直线的绘制指定绘制的起点。
执行效果:

首尾相接
如果你没有在多个 lineTo() 之间使用 moveTo() 函数来为直线的绘制指定绘制的起点,那么上一条直线的终点将作为下一条直线的起点(第一条直线的起点必须使用 moveTo() 方法来进行指定)。
让我们利用这个特性来绘制一个三角形:
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.moveTo(0, 0);
    canvas.lineTo(150, 300);
    canvas.lineTo(300, 150);
    canvas.lineTo(0, 0);
    canvas.stroke();
}else{
    console.log('Canvas Not Supported')
}
效果:

多彩的直线
你可以通过使用 canvas 对应的 DOM 对象的 strokeStyle 属性来指定画笔的颜色。颜色你可以通过赋予 strokeStyle 属性如下类型的表示进行指定。
- 十六进制表示的颜色值
- rgba()
- rgb()
- 颜色关键字,如 red 。
使用如下代码绘制一个红色的三角形:
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.moveTo(0, 0);
    canvas.strokeStyle = "rgb(255, 0, 0)";
    canvas.lineTo(150, 300);
    canvas.lineTo(300, 150);
    canvas.lineTo(0, 0);
    canvas.stroke();
}else{
    console.log('Canvas Not Supported')
}

矩形
canvas 提供了两种方法绘制矩形:
| 项目 | 描述 | 
|---|---|
| fillRect(x, y, width, height) | 绘制填充矩形 | 
| strokeRect(x, y, width, height) | 绘制描边矩形 | 
其中:
fillRect() 与 strokeRect() 方法的参数及意义均相同。
 x 与 y 表示矩形左上角所在的坐标;
 width 与 height 则分别表示矩形宽度与高度。
描边矩形
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.strokeRect(150, 100, 300, 200);
}else{
    console.log('Canvas Not Supported')
}
效果:

注:
同直线一样,你可以在使用 strokeRect() 方法绘制描边矩形之前通过 strokeStyle 属性来设置矩形边框的颜色。
填充矩形
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.fillRect(150, 100, 300, 200);
}else{
    console.log('Canvas Not Supported')
}
效果:

注:
你可以在使用 fillRect() 方法绘制描边矩形之前通过 fillStyle 属性来设置填充矩形所用到的颜色。
结合体
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.strokeStyle = "dodgerblue";
    canvas.strokeRect(150, 100, 300, 200);
    canvas.fillStyle = "pink";
    canvas.fillRect(150, 100, 300, 200);
}else{
    console.log('Canvas Not Supported')
}
效果:

清除矩形区域
你可以使用 clearRect(x, y, width, height) 来指定需要被清除的矩形区域,被清除的区域将不会有任何 canvas 内容。
// 通过 DOM API 获取 canvas 元素对应的 DOM 元素
const canvas_e = document.querySelector('#canvas');
// 检测浏览器对 canvas 元素的支持性
if(canvas_e.getContext){
    // 如果浏览器支持则获取 canvas 元素的渲染上下文
    const canvas = canvas_e.getContext('2d');
    canvas.strokeStyle = "dodgerblue";
    canvas.strokeRect(150, 100, 300, 200);
    canvas.fillStyle = "pink";
    canvas.fillRect(150, 100, 300, 200);
    // 对绘制的矩形进行部分清除
    canvas.clearRect(250, 150, 200, 100)
}else{
    console.log('Canvas Not Supported')
}
效果:

注:
- 观察本示例效果图可以发现,矩形的边框并没有被清除。这表明为矩形添加边框,边框并不是在原矩形内部生成的,而是在矩形的外围生成的。矩形的总面积(矩形面积及边框面积)在添加边框后增大了。
- 在本示例中,你可以使用 clearRect(0, 0, canvas.width, canvas.height) 清除 Canvas 中的所有内容。
多边形
Canvas 并没有提供绘制多边形的 API ,但我们可以通过绘制多条直线的方式绘制各种各样的多边形。



















