第一章 基础知识

1.1 canvas 元素

  • 需设置 canvas 元素的 widthheight 属性,CSS 属性设置的宽高样式,会被浏览器进行缩放,进而导致奇怪的效果 canvas 的大小称为画布大小,CSS 大小称为绘图大小,当其不一致时,浏览器会对绘图大小进行缩放,因此尽量保持两者进行相同,或者不设置 CSS 属性)
  • fillStyle:填充样式,可选值(颜色字符串,CanvasGradient 对象,CanvasPattern 对象)
  • fillText(text, x, y, [maxWidth]):填充文本
  • strokeStyle:描边样式,同填充样式
  • strokeText(text, x, y, [maxWidth]):描边文本

canvas 元素的 API

属性描述类型默认值
width非负整数300
height非负整数150
getContext()返回与该 canvas 元素相关的绘图环境对象,每个环境对象与一个 canvas 元素相关联
toDataURL(type, quality)返回一个数据地址(data URL),第一个参数为图像的类型:image/jpegimage/png(默认值),第二个参数为图像的质量,值为 0-1.0 之间的浮点数
toBlob(callback, type, quality)创建一个用于表示此 canvas 元素图像文件的 Blob,第一个参数是回调函数,可获得一个单独的 Blob 对象参数,第二个参数为图像类型,第三个参数为图像质量

1.2 canvas 的绘图环境

canvas 元素仅仅是为了充当绘图环境对象的容器而存在,该环境对象提供了全部的绘制功能

2d 绘图环境

除了指向 canvas 元素自身的 canvas 属性之外,其余的 2d 绘图环境属性都与绘图操作有关

属性简介
fillstyle指定该绘图环境在后续的图像填充操作中所使用的颜色、渐变色或图案
font设定在调用绘图环境对象的 fillText()strokeText() 方法时所使用的字形
globalAlpha全局透明度设定,取值为 0-1.0 之间浏览器会将每个像素的 alpha 值与该值相乘,在绘制图像时野生如此
globalCompsiteOperation该值决定了将某个物体绘制在其他物体之上时,所采用的绘制方法,取值详见 2.14 节
lineCap如何绘制线段的端点,取值为:butt(默认值)、roundsquare
lineWidth绘制线段的屏幕像素宽度,必须是非负、非无穷的浮点值,默认值为 1.0
lineJoin如何绘制线段交点,取值为:bevelroundmiter(默认值)
miterLimit如何绘制 miter 形式的线段交点,详见 2.8.7 小节
shadowBlur如何延伸阴影效果,值越高,延伸越远。该值代表高斯模糊方程式中的参数值,并非阴影像素的长度。取值为非负非无穷的浮点值,默认值为 0
shadowColor阴影的颜色,通常采用半透明颜色
shadowOffsetX以像素为单位,指定阴影效果水平方向偏移量
shadowOffsetY以像素为单位,指定阴影效果垂直方向偏移量
strokeStyle对路径进行描边时所用的绘制风格
textAlignfillText()strokeText() 方法进行绘制时,所画文本的水平对齐方式
textBaselinefillText()strokeText() 方法进行绘制时,所画文本的垂直对齐方式

canvas 状态的保存与恢复

  • context.save():保存当前绘图环境所有属性
  • context.restore():恢复

两个方法可以嵌套使用,注意要成对使用,否则可能导致意料之外的效果

注意:canvas 状态不包括当前的路径或位图。路径只能通过 beginPath() 来重置,位图是 canvas 本身的一个属性,不属于绘图环境对象

用法如下

// 保存当前所有属性
context.save();

// 设置新属性
context.fillStyle = 'red';
// 绘制其他东西
// ...

// 恢复,即上面设置的新属性将还原
context.restore();

1.3 程序清单规范格式

<!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>Document</title>
        <style>
            body {
                background: #ddd;
            }
            #canvas {
                background: #fff;
                border: thin inset #aaa;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="600" height="300">
            Canvas not supported
        </canvas>

        <script>
            const canvas = document.getElementById('canvas');
            const context = canvas.getContext('2d');
        </script>
    </body>
</html>

1.4 开始学习 HTML5

1.5 基本的绘制操作

一些例子,暂时略过

1.6 事件处理

鼠标事件

  • canvas.onmousedown = (e) => { ... }
  • canvas.addEventListener('mousedown', (e) => { ... })

其他鼠标事件 mousemovemouseupmouseout 等一样注册

坐标转换

浏览器事件对象传递给监听的坐标是窗口坐标,此时需要将其转换为 canvas 坐标

function windowToCanvas(canvas, x, y) {
    // 获取 canvas 元素的边界框,该坐标是相对于窗口的
    const box = canvas.getBoundingClientRect();
    return {
        // 此处返回的坐标,在 canvas 元素大小与绘图表面大小不相符时进行了缩放
        x: x - box.left * (canvas.width / box.width),
        y: y - box.top * (canvas.height / box.height),
    };
}

键盘事件

除非要在 canvas 中实现字符控制功能,否则处理鼠标事件的场合比处理键盘事件多

  • keydown:查看其返回的 keyCode 属性的值。一般来说,可打印的字符,该值为 ASCII 码。其返回值通常还包含以下布尔值属性:altKeyctrlKeymetaKeyshiftKey
  • keyup:同上
  • keypress:浏览器只在产生可打印字符时才触发该事件,所以处理该事件时可以使用获取 var key = String.fromCharCode(event.which); 字符

触摸事件

  • TouchEvent 对象
  • TouchList 对象
  • Touch 对象

详见 11 章

1.7 绘制表面的保存与恢复

  • getImageData():保存绘图环境的绘图表面
  • putImageData():恢复

使用示例如下

const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
let imageData = '';

function saveDrawingSurface() {
    imageData = context.getImageData(0, 0, canvas.width, canvas.height);
}

function restoreDrawingSurface() {
    context.putImageData(imageData, 0, 0);
}

canvas.onmousedown = (e) => {
    // ...
    saveDrawingSurface();
    // ...
};

canvas.onmousemove = (e) => {
    if (dragging) {
        restoreDrawingSurface();
    }
};

canvas.onmouseup = (e) => {
    restoreDrawingSurface();
};
Last Updated:
Contributors: af, zhangfei