摘要:大部分的原生繪制圖形或圖像的一般是這樣的例如就是。這類繪制大部分被封裝在的類中,它們有一個共同的特點名字都是以開始,例如。基礎圖形實例的作用是提供一個修改圖形接口。如果從嵌套的維度來說與的關系是等基礎圖形其實,完全不需要這么實現。
在原生 Canvas 中,其實并沒有 DisplayObject 的概念,它只有繪制圖像的概念。
大部分的原生繪制圖形或圖像的 API 一般是這樣的:
api(x, y, ...)
例如 rect 就是:ctx.rect(x, y, width, height)。
這類繪制 API 大部分被封裝在 CreateJS 的 Graphics 類中,它們有一個共同的特點 ---- 名字都是以 draw 開始,例如:drawRect / drawCircle 。
為什么說是大部分繪制的API被封裝在 Grahpics 類中呢?
很簡單,Graphics 類處理的是圖形繪制,所以也可以說所有的圖形繪制 API 被封裝在 Graphics 類中。繪制API還有另一個功能 ------ 繪制圖像,這個功能被封裝在 Bitmap 類中。
我曾經這樣覺得:「graphics.draw*(x, y, ...) 的參數
var rect = new createjs.Shape(); rect.graphics.drawRect(50, 50, 100 100); stage.addChild(rect); console.log(rect.x, rect.y);Graphics 的工作原理
來分析 Graphics 的 drawRect API 源碼:
https://www.createjs.com/docs...
https://www.createjs.com/docs...
https://www.createjs.com/docs...
https://www.createjs.com/docs...
代碼很簡單,如下:
創建一個「Rect 實例」;
「Rect 構造函數」將 drawRect 的實現代碼掛載在 prototype.exec 下
將「Rect 實例」append 到數組 _activeInstructions中(第四張截圖);
返回「Graphics」實例
為什么需要一個數組(_activeInstructions)來存儲原生指令?
對于矩形、圓形和圓角矩形來說,確實不需要數組來存儲指令;但是梯形、三角形等圖形沒有對應的原生API,此時需要使用繪制線段或孤線(ctx.moveTo/ctx.lineTo/ctx.arc)來組合產生,而數組 _activeInstructions 就是來處理組合圖形產生的。
Rect實例有什么作用?
Rect實例是 drawRect 返回的實例,Graphics 里還有其它的 draw* API,它們會返回各自圖形的實例,所以可以把 Rect實例和其它實例統稱為「基礎圖形實例」。「基礎圖形實例」的作用是提供一個修改圖形接口。通過第四張截圖,可以看到「基礎圖形實例」最終被掛載在「Graphics 實例」的 command 屬性下,也就是說通過「Graphics實例」的 command 可以訪問到最新的「基礎圖形實例」,寫一個測試代碼如下:
var gcircle = circle.graphics.beginFill("00ff00").drawCircle(0, 0, 10); circle.x = circle.y = 100; stage.addChild(circle); stage.update(); setTimeout(function() { gcircle.command.radius = 50; stage.update(); }, 1000);
這個特性在動態繪制圖形上是很有用的,不過,它有一個短板:通過 command 屬性只能訪問到最近的「基礎圖形實例」。也就是說自定義的組合圖形,如果需要訪問到對應的「基礎圖形實例」就需要把繪制過程拆散,舉個例子:
// 三角形 var threeangle = new createjs.Shape(); threeangle.graphics.beginFill("00ff00").moveTo(50, 0).lineTo(0, 50).lineTo(100, 50).closePath(); stage.addChild(threeangle); stage.update();
如果底部兩個端點要做動畫:
// 三角形 var threeangle = new createjs.Shape(); threeangle.graphics.beginFill("00ff00").moveTo(50, 0); var p1 = threeangle.graphics.lineTo(0, 50).command; var p2 = threeangle.graphics.lineTo(100, 50).command; threeangle.graphics.closePath(); stage.addChild(threeangle); stage.update(); setTimeout(function() { p1.y = 100; stage.update(); }, 1000); setTimeout(function() { p2.y = 200; stage.update(); }, 2000);Shape 的工作原理
https://www.createjs.com/docs...
Shape 極簡單,就是生成一個 DisplayObject 實例,然后在這個實例中掛載一個 Graphics 實例。而它的工作原理(即它的渲染)如下:
https://www.createjs.com/docs...
也就是 Shape 實例的 draw 方法其實是直接調用 Graphics 實例的 draw 方法。
DisplayObject 的工作原理DisplayObject 的核心功能是處理 DisplayObject 實例的「矩陣轉換」(即位移與形變),如下:
https://www.createjs.com/docs...
我在 聊聊 Container 的實現 中介紹了使用原生 Canvas 實現 Container 的原理。其實,Shape 實例也是一個Container,只是 CreateJS 限制了 shape 只能放 Graphics 實例,而且 shape 只能存放一個 Graphics 實例(即shape 下的 graphics 屬性),Graphics 實例下存放多個「基礎圖形實例」。
**如果從嵌套的維度來說 Graphics 與 DisplayObject 的關系是:
Container > Shape > Graphics > Rect/Circle/RoundRect等基礎圖形**
其實,CreateJS 完全不需要這么實現。像 PIXI 在實現 Graphics 的時候,Graphics 也一個 Container,它可以像一個正常的 DisplayObject 一樣被使用,而不用像 CreateJS 一樣麻煩。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89512.html
摘要:首先要指出的是實例的屬性與的參數沒有關系。同理可得的與在效果上都是。對實例設置了后,實例的位置會發生變化,這是因為執行了。自此以下結論是正確的的最終也會轉換成原生的 首先要指出的是:DisplayObject 實例的屬性 與 graphics.draw*(x, y, ...) 的參數沒有關系。 在原生的 Canvas 中有 的概念,例如:ctx.rect(x, y, width, ...
摘要:類介紹繼承自方法把此顯示對象寫進一個新的隱藏的,然后用于接下來的繪制。緩存好的這個顯示對象,可以自由地移動旋轉漸消。 類介紹 繼承自 EventDispatcher DisplayObject is an abstract class that should not be constructed directly. Instead construct subclasses such a...
摘要:可以這樣說,和應用了的元素是兩個彼此獨立的元素,這也是元素的不跟隨元素一起位移或形變的根本原因。結論為什么元素的不跟隨元素一起位移或形變答案是元素與是兄弟關系。 之前在做「雙十一攻略頁」的時候就發現這個細節,但是當時沒有太在意,今天又遇到了。 createjs 的代碼: var stage = new createjs.Stage(canvas); var container = n...
閱讀 1442·2023-04-25 17:18
閱讀 1882·2021-10-27 14:18
閱讀 2124·2021-09-09 09:33
閱讀 1840·2019-08-30 15:55
閱讀 2016·2019-08-30 15:53
閱讀 3440·2019-08-29 16:17
閱讀 3429·2019-08-26 13:57
閱讀 1730·2019-08-26 13:46