[Famo.us] SlideShow 模組開發

[UPDATE] Famo.us 官方已捨棄此模組,所以本範例只能在舊有的 Famo.us 上面運行,詳情請看官方 Github

身為農夫,種點菜也是很合理的。


Slideshow

slideshow sketch

概念是這樣,我們利用左右兩邊的頁面來置換中間的頁面,所以只需要兩段 Transform 來做這個動作。這個東西其實用 Famo.us 幾個模組就能兜出來,只是為了方便起見,所以才把它打包成模組方便使用。

Famo.us 模組

由於 Famo.us 是使用 AMD 的方式來載入外部組件,所以基本上,就是寫一個屬於你自己的元件來使用。一個基本元件構成需要這幾個部分,

define(function(require, exports, module) {
  'use strict';

  function Slidershow(options) {
  }

  Slidershow.DEFAULT_OPTIONS = {
  };

  Slidershow.prototype.commit = function commit() {
    return this.container.render();
  };


  Slidershow.prototype.render = function render() {
    return [
      {
        target: this.container.render()
      }
    ];
  };

  module.exports = Slidershow;
});

其中我們會看到 commit 與 render 兩個方法,這兩個方法在模組當中是屬於私有方法。這是 Famo.us 將元件交給 Engine 的時候所需要的方法。目前官方並沒有特別去解釋這兩個方法應該如何使用,不過萬能的原始碼還是會告訴我們一些端倪。

其中,如果你的 render 並不是返回 RenderNode 所需陣列,那你就必須要使用 commit 方法來返回單一 render 後的結果。

意思就是說,以下這兩種方法式可以交互使用的,

define(function(require, exports, module) {
  'use strict';

  function Slidershow(options) {
    this.id = Entity.register(this);
  }

  Slidershow.DEFAULT_OPTIONS = {
  };

  Slidershow.prototype.commit = function commit() {
    return this.container.render();
  };

  Slidershow.prototype.render = function render() {
    return this.id;
  };

  module.exports = Slidershow;
});
define(function(require, exports, module) {
  'use strict';

  function Slidershow(options) {
  }

  Slidershow.DEFAULT_OPTIONS = {
  };

  Slidershow.prototype.render = function render() {
    return [
      {
        target: this.container.render()
      }
    ];
  };

  module.exports = Slidershow;
});

渲染方式

是的,你可以不使用 commit,但是你不能省略 render 這個方法。但是,其中 render 所返回的物件,根據原始碼觀落陰得知,大概是下列元件(這一點尚未跟官方證實,

{
  align: null,
  opacity: 1,
  origin: [0, 0],
  size: null,
  target: 0,
  transform: [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,0,0]
}

其中 align 代表原件對齊的方式,僅接受二維陣列,例如 [0, 0] 或是 [0.5, 0.5] 這樣的寫法。而 origin 則是原件對齊的基準點,基本上是 [0, 0] 代表左上角。這兩個設定必須要同時存在,才會發生效用,如果其中一方是 null 則物件不會受到對齊的影響。

opacity 則是指定整個物件的透明度,而 size 目前完全看不出來有什麼干擾,而 transform 則是接受 Famo.us 的 Tramsform 所產生的 Matrix3D 陣列,如果你想自己手寫也沒什麼問題。

而 target 就是最終要交給 RenderNode 去做產出的東西,如果你的 target 只是單純指定一個 id 或是字串,那麼你就必須要有 commit 來返回你需要演算的結果(也就是可渲染物件( renderable

所以,要就是使用 render 方法返回所有你需要渲染的物件,不然就是利用 commit 來返回單一渲染物件,差別僅在此。

初始化

首先,我們需要一個工具來管理我們的設定值,所以可以直接使用 OptionsManager 來達到我們的需求,然後,我們再給他一個基本的 ContainerSurface 好讓 render 可以去渲染這個元件,

define(function(require, exports, module) {
  'use strict';

  var OptionsManager       = require('famous/core/OptionsManager');
  var ContainerSurface     = require('famous/surfaces/ContainerSurface');

  function Slidershow(options) {
    this.options = Object.create(Slidershow.DEFAULT_OPTIONS);
    this._optionsManager = new OptionsManager(this.options);

    if (options) this.setOptions(options);

    this.container = new ContainerSurface();
  }

  Slidershow.prototype.setOptions = function setOptions(options) {
    this._optionsManager.setOptions(options);
  };

  Slidershow.prototype.render = function render() {
    return [
      {
        target: this.container.render()
      }
    ];
  };

  Slidershow.DEFAULT_OPTIONS = {
    width: window.innerWidth,
    height: 500,
    dotNav: true,
    controlNav: true,
    transition: {
      duration: 600,
      curve: 'easeInOut'
    }
  };

  module.exports = Slidershow;
});

然後我們就做完了(咦!咦!咦!

小結

實際操作請參考這裡,

http://famous.hinablue.me/SlideShow/

原始碼請到我的 github 上面抄(誒

https://github.com/hinablue/famous.tw/blob/master/SlideShow/js/Slidershow.js

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