[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 來儲存你的元件。

Hina Chen
偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。
Taipei