AlloyTouch 0.2.0釋出--魚和熊掌兼得

【當耐特】發表於2016-12-28

原文連結:https://github.com/AlloyTeam/AlloyTouch/wiki/AlloyTouch-0.2.0

背景

公司師姐昨日在KM發了篇長文,主要結論RAF+transform3d就是不如transition+transform3d平滑流暢,但是transition+transform3d沒有translate屬性變更change回撥,只有transitionend的事件回撥。最後得出的解決方案:

支援動態切換 raf 和 transition~~

AlloyTouch在這個基礎上更加激進,直接支援change事件,不用使用者去關心RAF還是transition,也不用使用者去手動切換。那麼是怎麼做到了?往下看。

主要更新

AlloyTouch CSS版本已經支援change事件回撥了

魚和熊掌兼得!慢,什麼是魚?什麼是熊掌?
魚,效能。由於RAF+transform3d就是不如transition+transform3d平滑流暢。CSS版本在處理DOM區域性滾動的時候明顯更加smooth。

熊掌,change回撥。以前使用CSS版本是無法監聽到dom的translate屬性變更change回撥,只有transitionend的事件回撥。

現在魚和熊掌可以兼得!

舉個例子

AlloyTouch 0.2.0釋出--魚和熊掌兼得

這裡就是使用CSS版本製作的,而且滾動過程中可以執行change回撥,所以頭部的動畫都在在change回撥裡進行處理的。

原理分析

  • 使用者touchstart的時候開啟RAF定時器
  • 定時器一直計算讀取滾動元素的translate屬性,並拋給使用者傳入的change事件
  • transitionend的時候關閉RAF定時器

對,就是這麼簡單!

程式碼分析

...
...
_start: function (evt) {
    cancelAnimationFrame(this.tickID);
    this._tick();
...
...
_tick: function () {
    this.change.call(this, this.getComputedPosition());
    this.tickID = requestAnimationFrame(this._tick.bind(this));
},
...

touchstart的時候會去觸發_start事件,先去cancelAnimationFrame取消掉當前的迴圈,再重新開啟一個,滾動點停。還可以看到,在不斷tick的過程中,change函式是一直會被執行,而且計算出的translate會傳給change回撥。再看getComputedPosition:

getComputedPosition: function () {
    var matrix = window.getComputedStyle(this.scroller, null);
    matrix = matrix[transform].split(')')[0].split(', ');
    return this.vertical ? (+(matrix[13] || matrix[5])) : (+(matrix[12] || matrix[4]));
},

這裡會通過getComputedStyle去計算出滾動DOM的matrix,然後提取出translate出來。

讀取

...
...
if (this.step) {
    this.correction();
    if (this._endCallbackTag) {
        this._endTimeout = setTimeout(function () {
            this.animationEnd.call(this, current);
            cancelAnimationFrame(this.tickID);
        }.bind(this), 400);
        this._endCallbackTag = false;
    }
} else {
    this.animationEnd.call(this, current);
    cancelAnimationFrame(this.tickID);
}
...

當觸發了_transitionEnd之後,會去清除定時器。這裡需要注意,當使用者傳了step配置,會延遲400ms清除定時器,因為校正step的過程需要400ms。

Q&A

問:那麼非CSS版本還有存在的意義嗎?
答:有的,因為非CSS不僅僅可以用於DOM,還能用於WebGL、Canvas,並且運動屬性無關。CSS版本沒有這些功能。

問:AlloyTouch如何做到這麼小的尺寸?
答:AlloyTouch專注於數字的加速減速和回彈,抽象級別較高,而且適用場景較廣。

問:有沒有出React版本的計劃?
這個正在計劃當中,但是事實上,不是所有頁面都適合React,比如無限滾動,不使用React效能會更優。有的時候要在體驗最優和工程化最優做一個權衡,如果體驗達不到預期,要學會放棄工程化最優的方案。

問:AlloyTouch和transformjs什麼關係?
沒有關係。AlloyTouch專注於觸控和運動,transformjs提供DOM和任意物件transformation能力以及一些基礎工具函式。
但是建議一起使用。這裡需要注意的是,CSS版本的AlloyTouch強制必須和transformjs一起使用。

開始AlloyTouch

Github:https://github.com/AlloyTeam/AlloyTouch

任何意見和建議歡迎new issue,我們會第一時間反饋。

相關文章