/ Famo.us

[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;
});

其中我們會看到 commitrender 兩個方法,這兩個方法在模組當中是屬於私有方法。這是 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.usTramsform 所產生的 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