以前在作「雙十一攻略頁」的時候就發現這個細節,可是當時沒有太在乎,今天又遇到了。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 完成。