原文連接:https://github.com/AlloyTeam/AlloyTouch/wiki/AlloyTouch-0.2.0html
公司師姐昨日在KM發了篇長文,主要結論RAF+transform3d就是不如transition+transform3d平滑流暢,可是transition+transform3d沒有translate屬性變動change回調,只有transitionend的事件回調。最後得出的解決方案:git
支持動態切換 raf 和 transition~~github
AlloyTouch在這個基礎上更加激進,直接支持change事件,不用用戶去關心RAF仍是transition,也不用用戶去手動切換。那麼是怎麼作到了?往下看。dom
AlloyTouch CSS版本已經支持change事件回調了函數
魚和熊掌兼得!慢,什麼是魚?什麼是熊掌?
魚,性能。因爲RAF+transform3d就是不如transition+transform3d平滑流暢。CSS版本在處理DOM局部滾動的時候明顯更加smooth。工具
熊掌,change回調。之前使用CSS版本是沒法監聽到dom的translate屬性變動change回調,只有transitionend的事件回調。性能
如今魚和熊掌能夠兼得!動畫
這裏就是使用CSS版本製做的,並且滾動過程當中能夠執行change回調,因此頭部的動畫都在在change回調裏進行處理的。
注意,這裏只是個DEMO頁面,用來展現頭部的動畫,底部顯示正在加載中是加載不出來數據的,因此不用等待了。
用戶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。
問:那麼非CSS版本還有存在的意義嗎?
答:有的,由於非CSS不單單能夠用於DOM,還能用於WebGL、Canvas,而且運動屬性無關。CSS版本沒有這些功能。
問:AlloyTouch如何作到這麼小的尺寸?
答:AlloyTouch專一於數字的加速減速和回彈,抽象級別較高,並且適用場景較廣。
問:有沒有出React版本的計劃?
這個正在計劃當中,可是事實上,不是全部頁面都適合React,好比無限滾動,不使用React性能會更優。有的時候要在體驗最優和工程化最優作一個權衡,若是體驗達不到預期,要學會放棄工程化最優的方案。
問:AlloyTouch和transformjs什麼關係?
沒有關係。AlloyTouch專一於觸摸和運動,transformjs提供DOM和任意對象transformation能力以及一些基礎工具函數。
可是建議一塊兒使用。這裏須要注意的是,CSS版本的AlloyTouch強制必須和transformjs一塊兒使用。
Github:https://github.com/AlloyTeam/AlloyTouch
任何意見和建議歡迎new issue,咱們會第一時間反饋。