HTML5 Canvas 提供了 saverestore 方法用来绘制复杂图形。

它可以保存 canvas 的状态,包括 canvas 的平移、放缩、旋转、错切、裁剪等操作等等,也可以恢复到上次保存的状态。

相关方法:

// 保存当前环境的状态
context.save()

// 返回之前保存过的路径状态和属性
context.restore()

canvas 的状态存储在内存中,它的数据结构类似于,即符合“先入后出,后入先出”的基本特点。

HTML5 Canvas 支持我们可以直接通过 ImageData 对象操纵 canvas 中像素数据,直接读取或将数据数组写入该对象中。

ImageData 对象

ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:

width :图片宽度,单位是像素
height :图片高度,单位是像素
dataUint8ClampedArray 类型的一维数组,包含着RGBA格式的整型数据,范围在0至255之间(包括255)。

data 属性返回一个 Uint8ClampedArray ,它可以被使用作为查看初始像素数据。每个像素用4个1bytes值(按照红,绿,蓝和透明值的顺序; 这就是"RGBA"格式) 来代表。每个颜色值部份用0至255来代表。每个部份被分配到一个在数组内连续的索引,左上角像素的红色部份在数组的索引0位置。像素从左到右被处理,然后往下,遍历整个数组。

Uint8ClampedArray 包含高度 × 宽度 × 4 bytes数据,索引值从0到(高度×宽度×4)-1

在之前文章的所有例子中,我们有时会将一个图形画在另一个之上,在更多的情况下仅仅这样是远远不够的。

当新绘制的图形和已存在的图形交叠在一起时,对于合成的图形来说,绘制顺序和显示效果会有不同的要求。这里,我们可以利用 globalCompositeOperation 属性来改变这种状况。

相关属性:

// 设置或返回如何将一个源(新的)图像绘制到目标(已有)的图像上。
context.globalCompositeOperation="source-in";

// 更多值的说明
// source-over:默认,新图像会覆盖在原有图像
// source-atop:在目标图像顶部显示源图像。源图像位于目标图像之外的部分是不可见的。
// source-in:在目标图像中显示源图像。只有目标图像内的源图像部分会显示,目标图像是透明的。
// source-out:在目标图像之外显示源图像。只会显示目标图像之外源图像部分,目标图像是透明的。
// destination-over:在源图像上方显示目标图像。
// destination-atop:在源图像顶部显示目标图像。源图像之外的目标图像部分不会被显示。
// destination-in:在源图像中显示目标图像。只有源图像内的目标图像部分会被显示,源图像是透明的。
// destination-out:在源图像外显示目标图像。只有源图像外的目标图像部分会被显示,源图像是透明的。
// darken:显示源图像和目标图像,保留重叠部分最暗的像素
// lighten:显示源图像和目标图像,保留重叠部分最明亮的像素
// lighter:显示源图像和目标图像,重叠区域的颜色做加处理
// copy:显示源图像。忽略目标图像。
// xor:使用异或操作对源图像与目标图像进行组合。

位移

HTML5 Canvas 提供了 translate 方法,可重新映射画布上的 (0,0) 位置,再次绘制图形时,位置会相对新原点进行绘制,从而产生位移的效果。

相关方法:

// 重新映射画布上的 (0,0) 位置。
// x:添加到水平坐标(x)上的值
// y:添加到垂直坐标(y)上的值
context.translate(x, y);

HTML5 Canvas 提供的 clip 可将当前创建的路径设置为当前裁剪路径的方法。

绘制路径后裁切

裁切方法:

// 把已经创建的路径转换成裁剪路径
context.clip();

context.clip(fillRule);

context.clip(path, fillRule);

// 参数:
// fillRule:这个算法判断一个点是在路径内还是在路径外。
// 可选的值:
// "nonzero": 非零环绕原则,默认的原则。
// "evenodd": 奇偶环绕原则。
// path:需要剪切的 Path2D 路径。