/ Famo.us

[Famo.us] RenderNode 核心說明

[UPDATE] Famo.us 官方已捨棄此模組,詳情請看官方 Github

RenderNode 算是整個 Famo.us 對於元件樹狀結構的核心,他專門用來處理你的元件,在樹狀結構中應該要怎麼長是靠他來處理。


RenderNode 核心

這個核心很特殊,你應該也幾乎沒有機會能直接使用他。他的初始化必須要是一個可渲染(renderable)的元件,而這個元件經過初始化後,自身就會轉換成 RenderNode 物件,來提供給 Famo.us 的引擎去做渲染動作。

什麼叫做可渲染元件?官方定義的有,

  • core/Group
  • core/RenderNode
  • core/Scene
  • core/Surface
  • core/View
  • core/ViewSequence
  • surfaces/ContainerSurface
  • views/EdgeSwapper
  • views/GridLayout
  • views/HeaderFooterLayout
  • views/Lightbox
  • views/RenderController
  • views/ScrollContainer
  • views/Scroller
  • views/Scrollview
  • views/SequentialLayout
  • widgets/Slider
  • widgets/ToggleButton

以後會不會增加,不確定。

渲染

渲染方式是依照堆疊在他的 _child 中的物件分層次,透過 ElementAllocator 將物件產出到 DOM 裡面去,順序這件事情之前在 Famo.us 官方有人提出討論過,實驗的結果,好像是先 var 先贏!

我實際就沒有太深入去研究這個順序問題,不過對於 DOM 來說,誰先誰後好像又會牽扯到 z-index 的問題,官方的解法是要你使用 Transform 去解決,不過,個人覺得,如果你真的很在意 DOM 順序,請在 new 任何可渲染物件的時候,留意一下上下順序(由上到下,DOM 就由先到後

方法

  • add 加一個子元件(一定要有一個可渲染物件
  • get 取得第一個子元件,或是自己
  • set 覆寫所有子元件,或是自己
  • getSize 第一個子元件(或自己)的尺寸

對於 add 有一個特別的使用方式(對於 Modifier 來說),舉例子來看會比較清楚,

define(function(require, exports, module) {
    var Engine     = require("famous/core/Engine");
    var Surface    = require("famous/core/Surface");
    var Modifier   = require("famous/core/Modifier");
    var RenderNode = require("famous/core/RenderNode");

    var mainContext = Engine.createContext();

    var renderNode = new RenderNode();
    var modifier = new Modifier({
        origin: [0.5, 0.5]
    });

    var surface = new Surface({
        size: [100, 100],
        content: "Secondary",
        properties: {
            lineHeight: "100px",
            textAlign: "center",
            backgroundColor: "red"
        }
    });
    renderNode.add(modifier).add(surface);

    console.log(renderNode.get()); // You will get the Modifier, not Surface.

    mainContext.add(renderNode);
});

你會發現,你用 get() 的時候,會拿到 Modifier 而非 Surface,這一點是因為 Modifier 可以被加入到任何 RenderNode 物件裡面,所以即便他並不是可渲染物件,他還是可以存在於 RenderNode 當中,這是比較特別的地方。

好處?好處就是動態效果製作時,我可以直接由 RenderNode 當中取出 Modifier,而不用另外找地方儲存(這樣還得用迴圈去運算,費時耗工

使用時機

通常 RenderNode 只是提供一個容器給物件來做存放,在開發 widgets 或是特殊的 views 的時候比較常見,由於 get() 方法相當方便(如上所述,對於 Modifier 相當友善),所以,如果你不是需要特殊物件的效果,也可以使用 RenderNode 來儲存你的元件。