聊聊 DisplayObject 的x/y/regX/regY/rotation/scale/skew 屬性

首先要指出的是:DisplayObject 實例的屬性<x, y> 與 graphics.draw*(x, y, ...) 的參數<x, y>沒有關係。 javascript

在原生的 Canvas 中有 <x, y> 的概念,例如:ctx.rect(x, y, width, height)。因而我天真地覺得 DisplayObject 的<x, y>應該跟原生 API 是一一對應的吧,可是結果給了我一個巴掌,在Graphics 與 DisplayObject 的關係 一文中有說起。css

後來我認真地思考了一下,還真不能把 DisplayObject 的 <x, y> 與 原生的繪製API的<x, y>參數掛勾。由於 Container 實例是一個「概念」 DisplayObject 實例,它沒有與之相對的原生繪製API。html

DisplayObject 的 <x, y> 是如何實現的?
其實 DisplayObject 的 <x, y> 都是經過原生的 API ------ ctx.transform(即「矩陣轉換」) 實現的。提及矩陣 css3 的 transform 與 DisplayObject 的矩陣是能夠一一對應的:
CSS3 -- transfrom
CreateJS.DisplayObject -- 矩陣
translate(x, y)
<x, y>
transform-origin
<regX, regY>
rotate(degX, degY)
rotation
scale(scaleX, scaleY)
<scaleX, scaleY>
skew(degX, degY)
<skewX, skewY>
matrix
-
CSS3 中 translate/rotate/scale/skew/transform-origin 這些方法或屬性最終都會轉換成 matrix。「矩陣」是一個數學工具,因此「DisplayObject 的 <x, y>/<regX, regY>/rotation/<scaleX, scaleY>/<skewX, skewY> 最終也會轉換成原生 Canvas 的 ctx.transform 」。java

關於「矩陣」的入門知識能夠看一下:http://www.zhangxinxu.com/wor...css3

這裏有一個知識點:transform-origin 在矩陣中至關於 translate。同理可得:DisplayObject 的 <regX, regY> 與 <x, y> 在效果上都是 translate。對 DisplayObject 實例設置了 <regX, regY> 後,實例的位置會發生變化,這是由於 CreateJS 執行了 translate(-regX, -regY)。segmentfault

儘管說清楚了 DisplayObject 的 <x, y>/<regX, regY>/rotation/<scaleX, scaleY>/<skewX, skewY> 屬性的工做原理,可是仍是須要經過 CreateJS 的源碼來驗證一下:app

DisplayObject 在渲染的時候經過兩個方法:updateContext & draw。其實 updateContext 在 draw 以前調用,事實上 DisplayObject 的 draw 方法沒什麼東西,幾乎全部操做都是集中在 updateContext 上。因此只須要看 updateContext 便可,以下:ide

https://www.createjs.com/docs...
圖片描述wordpress

786行的代碼是:工具

ctx.transform(mtx.a,  mtx.b, mtx.c, mtx.d, tx, ty);

這一步只能說明了 DisplayObject 底層實現有使用到 ctx.transform,並不能說明「DisplayObject 的 <x, y>/<regX, regY>/rotation/<scaleX, scaleY>/<skewX, skewY> 最終也會轉換成原生 Canvas 的 ctx.transform」。

回頭看看 780行 this.getMatrix(mtx)
https://www.createjs.com/docs...
圖片描述

getMatrix 的代碼以下:

p.getMatrix = function(matrix) {
        var o = this, mtx = matrix&&matrix.identity() || new createjs.Matrix2D();
        return o.transformMatrix ?  mtx.copy(o.transformMatrix) : mtx.appendTransform(o.x, o.y, o.scaleX, o.scaleY, o.rotation, o.skewX, o.skewY, o.regX, o.regY);
    };

在調用 this.getMatrix(mtx) 後,mtx 的屬性會被重置。matrix 是一個 Matrix2D 實例,Matrix2D 的源碼部分以下:
https://www.createjs.com/docs...
圖片描述

經過閱讀 Matrix2D 源碼能夠清晰地了知道,martix/mtx 的上的 a, b, c, d, tx, ty 所有來自 DisplayObject 實例的屬性: <x, y>/<regX, regY>/rotation/<scaleX, scaleY>/<skewX, skewY>。

自此如下結論是正確的:「DisplayObject 的 <x, y>/<regX, regY>/rotation/<scaleX, scaleY>/<skewX, skewY> 最終也會轉換成原生 Canvas 的 ctx.transform

相關文章
相關標籤/搜索