Weex BindingX 尝鲜

前言

三月初,阿里巴巴开源的一套基于 Weex、React Native 的富交互解决方案 「BindingX」。提供了一种称之为 「Expression Binding」 的机制可以在 Weex、React Native 上让手势等复杂交互操作以60fps的帧率流畅执行,而不会导致卡顿,因而带来了更优秀的用户体验。

背景

听上去「高大上」,那为啥要造这个轮子呢?

这就得从源头说起,他到底解决了什么问题。

我们知道,Weex 和 React Native 同样都是三层结构,「 JS 层、 Native 层、 Bridge 层」,Native 层负责视觉绘制、事件收集,JS 层负责视觉控制、事件处理,Bridge 层是 JS 层和 Native 层的沟通桥梁,负责指令「翻译」。以 Weex 为例:

image

想让 Native 层做一些复杂的交互操作时,JS 层就需要不停得处理从 Native 层收集来的事件然后作出「及时」响应,如果响应「不及时」就会导致视觉卡顿。

怎么样才算是「及时」呢?

我们常说 60fps 帧率是流畅的基础,这就意味着,一次有效的刷新需要在 1/60 s 内完成,如果 JS 层从事件接受、处理、回馈到 Native 绘制新的视图完成超过了 16.67ms 将会出现「视觉卡顿」。

另外,即使每一次更新都可以完全控制在 16.67ms 内,大量的通讯操作也会消耗掉过多的 CPU,以至于加大了 Crash 的风险

如果不突破这层瓶颈,此类技术将很难达到一个新的高度。

BindingX 就是解决这个问题的。

原理

BindingX 提出的 「Expression Binding」 将具体的手势控制行为以 「表达式」 的方式传递给 Native,监控「被绑定元素」上发生的手势操作并输出过程中横向「x」和纵向「y」的偏移量,因此我们即可将「x,y」作为表达式「f(x),f(y)」的入参,针对性的对某一目标元素的样式进行「绑定变化」。

而这所以操作都是在 Native 层独立完成的,大大减小了 JS 层和 Bridge 层的压力。

「无 Binding 模式」

image

「Binding 模式」

image

表达式

表达式,是由数字、运算符、变量等以能求得有意义数值的字符串。譬如, x\*3+10 就是一个表达式,当x被赋值时,整个表达式就会有一个明确的结果。通过表达式,我们就可以描述一个具体的交互行为,比如我们希望x从0变化到100时,透明度能从1变化到0.5,那么表达式可以描述为: f(alpha) = 1-(x/100)*0.5 也可以是 f(alpha) = 1-x/200 只不过第一种表达式更直白。

下面举一个简单的例子。

/* 简码 */
bindingx.bind({
      anchor:foo_view.ref  ,                    //==> 事件的触发者
      eventType:'pan',                          //==> 事件类型
      props: [
          {
            element:foo_view.ref,               //==> 要改变的视图的引用或者id
            property:'transform.translateX',    //==> 要改变的属性
            expression:'x+0'                    //==> 表达式
          }
        ]
    });

就这么简单,几行代码即可绑定 foo_view 实现视图随手势移动的交互。当然复杂的也有,只不过都是由这么一个个小的交互堆积而成的。

除了基本的四则运算外,还支持三元运算符、数学函数等高级语法,基本可以满足绝大部分的场景。

事件类型

前面的例子中用到了 pan 手势,除手势外,BindingX 还支持「列表的滚动 scroll」、「动画 timing」甚至是「陀螺仪感 orientation」,每种事件类型使用方式大致相同,也有注意点,详细请参阅《bindingx 官方文档》

Do it

怎么样能快速体验呢?

跟上我的脚步

playground

官方虽然也提供了 试验田 https://alibaba.github.io/bindingx/playground,但语法均为 Rax 但 DSL,并不少 Weex 对外的 Vue 版本,我们无法在线编辑查看效果,只能使用阿里系App「如淘宝、闲鱼、飞猪」扫码体验效果。

这些都不是我们想要的。

当然方法总是有的。

直接将 BindingX 的官方代码 clone 下来,上面有支持 Vue 版本的 Weex Playground。

bindingx/weex/playground/[ios|android]

ios 和 android 选一个用工具安装到自己的手机上。此处就不多解释了,不会的问下 google,或者下方留言。

使用 http://dotwe.org/vue/ 在线编辑,扫码看效果。

给大家分享几个 Vue 版本的 demo。

http://dotwe.org/vue/e50f76a6c13337b6fa4201a045c5dc0c

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

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

http://dotwe.org/vue/cd942c4bee9c4b7bcceda4e3aaf94c70

严选 demo 引入 BindingX

这是很早以前的一个小 Demo,感兴趣的可以 star 一下
https://github.com/zwwill/yanxuan-weex-demo

下面我基于严选的 Demo 进行的小试用。

升级 ios platform

要想使用 BindingX 插件,就必须使自己的 platform 支持。方法很简单,只需要将 platforms/ios/Podfile 进行升级修改即可。

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

def common
    pod 'WeexSDK', '0.17.0'                         #升级至 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

随后执行一遍 pod install 即可安装成功。如出现错误提示,按提示 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>
                <!-- 省略非关键代码 -->
            </div>
            <div class="fbs">
                <!-- 省略非关键代码 -->
            </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>

实现的效果就是最常见的个人信息页,title 背景随着滚动事件变换大小。

效果动图 http://cdn.zwwill.com/yanxuan/resource/bindingx2.gif

image

写在最后

Weex 有了 BindingX 如虎添翼。效率更高性!能更稳定!同期开源的还有 GCanvas 也是一把神器。

近期工作繁重,通宵写文章,如发现文章残瑕处,敬请谅解!

相关链接

作者: 木羽 zwwill
首发地址:https://github.com/zwwill/blog/issues/20

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容