以前在作「双十一攻略页」的时候就发现这个细节,可是当时没有太在乎,今天又遇到了。javascript
createjs 的代码:css
var stage = new createjs.Stage(canvas); var container = new createjs.Container(); var rect = new createjs.Shape(); rect.graphics.beginFill("#ff0000").drawRect(0, 0, 750, 1206); var mask = new createjs.Shape(); mask.graphics.beginFill("#000000").drawRect(0, 0, 750, 100); rect.mask = mask; container.regX = container.regY = container.x = container.y = 375; rect.y = 0; // 这里的数值变成 20,能够观察到 BUG container.addChild(rect); stage.addChild(container); stage.update();
rect.y === 0,截图以下:html
rect.y === 20,截图以下:java
mask 在使用过程当中发现:元素的 mask 不会跟随元素一块儿位移与形变(rotate, scale, skew)。css3
原生 canvas 中并无 mask 这个概念,mask 更像是借用了 css3 中的 mask
属性的概念出如今 PIXI or CreateJS 中的。而原生 Canvas 是使用 clip
方法来实现 mask
效果,从原生 canvas 的角度来看:mask 与应用 mask 的元素的地位是等同的。canvas
CreateJS 的文档里对 mask 的解释以下:app
A Shape instance that defines a vector mask (clipping path) for this display object. The shape's transformation will be applied relative to the display object's parent coordinates (as if it were a child of the parent).
https://www.createjs.com/docs...性能
虽然文档明确指出 mask
至关于(as if) 应用了 mask 的元素的父级的子元素;简单地说,mask 与 应用了 mask 的元素是兄弟关系(平级)。能够这样说,mask 和 应用了 mask 的元素是两个彼此独立的元素,这也是「元素的 mask 不跟随元素一块儿位移或形变」的根本缘由。this
从源码上分析:https://www.createjs.com/docs...spa
这一块的逻辑很简单:
Line769 判断「DisplayObject实例」是否存在 mask,若是存在进入第二步,不存在进入第5步
Line 770 获取 mask 的矩阵信息,Line 771 ctx 累加(transfrom) mask 的矩阵;
Line 774 ctx.clip() 锁定可绘画区(即添加蒙层);
Line 776 mtx.invert() 生成一个与 mask 反向的矩阵,Line 777 ctx 累加 mask 的反向矩阵;
Line 780 获取实例的矩阵信息,Line 786 ctx 累加实例的矩阵。
第4步其实很重要,它表示 mask 的矩阵只对它自身产生影响。mtx.invert
方法的定义在:https://www.createjs.com/docs...
其实我也是看了源码才知道原生 canvas 还有一个叫 clip
的方法,以前我一直误觉得 mask 是用 globalCompositeOperation
实现的,因此我一块儿怀疑应用了 mask 后会不会影响到性能,现在看来:mask 并不会影响性能。
为何元素的 mask 不跟随元素一块儿位移或形变?
答案是:元素 与 mask 是兄弟关系。
如何让元素与它mask的位移与形变同步?
给这个元素套上一个 container
,位移和形变由这个 container 完成。