Weex BindingX 嘗鮮

前言

三月初,阿里巴巴開源的一套基于 Weex、React Native 的富交互解決方案 「BindingX」。提供了一種稱之為 「Expression Binding」 的機(jī)制可以在 Weex、React Native 上讓手勢(shì)等復(fù)雜交互操作以60fps的幀率流暢執(zhí)行,而不會(huì)導(dǎo)致卡頓,因而帶來了更優(yōu)秀的用戶體驗(yàn)。

背景

聽上去「高大上」,那為啥要造這個(gè)輪子呢?

這就得從源頭說起,他到底解決了什么問題。

我們知道,Weex 和 React Native 同樣都是三層結(jié)構(gòu),「 JS 層、 Native 層、 Bridge 層」,Native 層負(fù)責(zé)視覺繪制、事件收集,JS 層負(fù)責(zé)視覺控制、事件處理,Bridge 層是 JS 層和 Native 層的溝通橋梁,負(fù)責(zé)指令「翻譯」。以 Weex 為例:

image

想讓 Native 層做一些復(fù)雜的交互操作時(shí),JS 層就需要不停得處理從 Native 層收集來的事件然后作出「及時(shí)」響應(yīng),如果響應(yīng)「不及時(shí)」就會(huì)導(dǎo)致視覺卡頓。

怎么樣才算是「及時(shí)」呢?

我們常說 60fps 幀率是流暢的基礎(chǔ),這就意味著,一次有效的刷新需要在 1/60 s 內(nèi)完成,如果 JS 層從事件接受、處理、回饋到 Native 繪制新的視圖完成超過了 16.67ms 將會(huì)出現(xiàn)「視覺卡頓」。

另外,即使每一次更新都可以完全控制在 16.67ms 內(nèi),大量的通訊操作也會(huì)消耗掉過多的 CPU,以至于加大了 Crash 的風(fēng)險(xiǎn)

如果不突破這層瓶頸,此類技術(shù)將很難達(dá)到一個(gè)新的高度。

BindingX 就是解決這個(gè)問題的。

原理

BindingX 提出的 「Expression Binding」 將具體的手勢(shì)控制行為以 「表達(dá)式」 的方式傳遞給 Native,監(jiān)控「被綁定元素」上發(fā)生的手勢(shì)操作并輸出過程中橫向「x」和縱向「y」的偏移量,因此我們即可將「x,y」作為表達(dá)式「f(x),f(y)」的入?yún)ⅲ槍?duì)性的對(duì)某一目標(biāo)元素的樣式進(jìn)行「綁定變化」。

而這所以操作都是在 Native 層獨(dú)立完成的,大大減小了 JS 層和 Bridge 層的壓力。

「無 Binding 模式」

image

「Binding 模式」

image

表達(dá)式

表達(dá)式,是由數(shù)字、運(yùn)算符、變量等以能求得有意義數(shù)值的字符串。譬如, x\*3+10 就是一個(gè)表達(dá)式,當(dāng)x被賦值時(shí),整個(gè)表達(dá)式就會(huì)有一個(gè)明確的結(jié)果。通過表達(dá)式,我們就可以描述一個(gè)具體的交互行為,比如我們希望x從0變化到100時(shí),透明度能從1變化到0.5,那么表達(dá)式可以描述為: f(alpha) = 1-(x/100)*0.5 也可以是 f(alpha) = 1-x/200 只不過第一種表達(dá)式更直白。

下面舉一個(gè)簡單的例子。

/* 簡碼 */
bindingx.bind({
      anchor:foo_view.ref  ,                    //==> 事件的觸發(fā)者
      eventType:'pan',                          //==> 事件類型
      props: [
          {
            element:foo_view.ref,               //==> 要改變的視圖的引用或者id
            property:'transform.translateX',    //==> 要改變的屬性
            expression:'x+0'                    //==> 表達(dá)式
          }
        ]
    });

就這么簡單,幾行代碼即可綁定 foo_view 實(shí)現(xiàn)視圖隨手勢(shì)移動(dòng)的交互。當(dāng)然復(fù)雜的也有,只不過都是由這么一個(gè)個(gè)小的交互堆積而成的。

除了基本的四則運(yùn)算外,還支持三元運(yùn)算符、數(shù)學(xué)函數(shù)等高級(jí)語法,基本可以滿足絕大部分的場(chǎng)景。

事件類型

前面的例子中用到了 pan 手勢(shì),除手勢(shì)外,BindingX 還支持「列表的滾動(dòng) scroll」、「動(dòng)畫 timing」甚至是「陀螺儀感 orientation」,每種事件類型使用方式大致相同,也有注意點(diǎn),詳細(xì)請(qǐng)參閱《bindingx 官方文檔》。

Do it

怎么樣能快速體驗(yàn)?zāi)兀?/p>

跟上我的腳步

playground

官方雖然也提供了 試驗(yàn)田 https://alibaba.github.io/bindingx/playground,但語法均為 Rax 但 DSL,并不少 Weex 對(duì)外的 Vue 版本,我們無法在線編輯查看效果,只能使用阿里系A(chǔ)pp「如淘寶、閑魚、飛豬」掃碼體驗(yàn)效果。

這些都不是我們想要的。

當(dāng)然方法總是有的。

直接將 BindingX 的官方代碼 clone 下來,上面有支持 Vue 版本的 Weex Playground。

bindingx/weex/playground/[ios|android]

ios 和 android 選一個(gè)用工具安裝到自己的手機(jī)上。此處就不多解釋了,不會(huì)的問下 google,或者下方留言。

使用 http://dotwe.org/vue/ 在線編輯,掃碼看效果。

給大家分享幾個(gè) Vue 版本的 demo。

http://dotwe.org/vue/e50f76a6c13337b6fa4201a045c5dc0c

http://dotwe.org/vue/2dff486956044ea59b3d38a2cf20b506

http://dotwe.org/vue/64998432f2a249f5cb35b4de0040526d

http://dotwe.org/vue/cd942c4bee9c4b7bcceda4e3aaf94c70

嚴(yán)選 demo 引入 BindingX

這是很早以前的一個(gè)小 Demo,感興趣的可以 star 一下
https://github.com/zwwill/yanxuan-weex-demo

下面我基于嚴(yán)選的 Demo 進(jìn)行的小試用。

升級(jí) ios platform

要想使用 BindingX 插件,就必須使自己的 platform 支持。方法很簡單,只需要將 platforms/ios/Podfile 進(jìn)行升級(jí)修改即可。

source 'git@github.com/CocoaPods/Specs.git'
platform :ios, '8.0'                                    #最低8.0
#inhibit_all_warnings!

def common
    pod 'WeexSDK', '0.17.0'                         #升級(jí)至 0.17.0
    pod 'Weexplugin', :path=>'./Weexplugin/'
    pod 'WXDevtool'
    pod 'SDWebImage', '3.7.5'
    pod 'SocketRocket', '0.4.2'
    pod 'BindingX'                                     #增加 BindingX
end

target 'WeexDemo' do
    common
end

target 'WeexUITestDemo' do
    common
end

隨后執(zhí)行一遍 pod install 即可安裝成功。如出現(xiàn)錯(cuò)誤提示,按提示 fix 掉即可。

小試牛刀

Vue 的引入方式不同于 Rax,需要使用 weex.requireModule() API。

<template>
    <div class="wrapper">
        <image ref="headerBg" resize="cover" src="http://cdn.zwwill.com/yanxuan/imgs/bg5.png"></image>
        <scroller ref="contentScroller">
            <div>
                <!-- 省略非關(guān)鍵代碼 -->
            </div>
            <div class="fbs">
                <!-- 省略非關(guān)鍵代碼 -->
            </div>
        </scroller>
    </div>
</template>

<script>
    const binding = weex.requireModule('bindingx');    //引入 bindingx
    export default {
        mounted(){
            this.headerBgBinding();
        },
        beforeDestroy(){
            this.headerBgBindingDestory();
        },
        methods: {
            headerBgBinding(){
                let self = this,
                    scroller = self.$refs.contentScroller.ref,
                    headerBg = self.$refs.headerBg.ref;
                    
                let bindingResult = binding && binding.bind({
                    eventType:'scroll',
                    anchor:scroller,
                    props:[
                        {
                            element:headerBg,
                            property:'transform.scale',
                            expression:{
                                origin:'y<0?(1-y/500):(1+y/500)'
                            }
                        },
                        {
                            element:headerBg,
                            property:'transform.translateY',
                            expression:{
                                origin:'-y/2'
                            }
                        }
                    ]
                },function(e){
                });
                self.gesToken = bindingResult.token;
            }
            headerBgBindingDestory(){
                let self = this;
                if(self.gesToken != 0) {
                    binding.unbind({
                      eventType:'scroll',
                      token:self.gesToken
                    })
                    self.gesToken = 0;
                  }
            }
        }
    }
</script>

實(shí)現(xiàn)的效果就是最常見的個(gè)人信息頁,title 背景隨著滾動(dòng)事件變換大小。

效果動(dòng)圖 http://cdn.zwwill.com/yanxuan/resource/bindingx2.gif

image

寫在最后

Weex 有了 BindingX 如虎添翼。效率更高性!能更穩(wěn)定!同期開源的還有 GCanvas 也是一把神器。

近期工作繁重,通宵寫文章,如發(fā)現(xiàn)文章殘瑕處,敬請(qǐng)諒解!

相關(guān)鏈接

作者: 木羽 zwwill
首發(fā)地址:https://github.com/zwwill/blog/issues/20

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 引子 這篇文章是筆者近期關(guān)于Weex在iOS端的一些研究和實(shí)踐心得,和大家一起分享分享,也算是對(duì)學(xué)習(xí)成果的總結(jié)。文...
    一縷殤流化隱半邊冰霜閱讀 12,402評(píng)論 53 165
  • 昨天下午,我?guī)Ь艢q的兒子和他同學(xué)在學(xué)校的操場(chǎng)上騎自行車??此麄冹`活地拐彎、轉(zhuǎn)圈、穿插。在藍(lán)天白云下,輕和微風(fēng)里,像...
    終將長大閱讀 570評(píng)論 0 3
  • 先推薦情侶裝。什么?你沒有情侶? 那么,你需要一個(gè)情侶。 ——這位看起來還行,那就先做情侶再說吧。(注意,故事從這...
    放肆交流會(huì)閱讀 612評(píng)論 1 1
  • 馬蹄踐踏了生活 卻激不起箱夢(mèng)的漣渏 流漓破碎了空虛 卻牽不住舒心的腳步。 非非只影,無無歸途 是待星宇之期 情情之...
    深深是藍(lán)閱讀 401評(píng)論 3 21
  • 頁面的回流和重繪會(huì)影響JavaScript性能,如果你的html很大很復(fù)雜,頁面的回流和重繪是一個(gè)非常值得關(guān)注的點(diǎn)...
    bingshuihe閱讀 1,071評(píng)論 0 1

友情鏈接更多精彩內(nèi)容