Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Weex】Weex BindingX 尝鲜 #20

Open
zwwill opened this issue Mar 8, 2018 · 2 comments
Open

【Weex】Weex BindingX 尝鲜 #20

zwwill opened this issue Mar 8, 2018 · 2 comments

Comments

@zwwill
Copy link
Owner

zwwill commented Mar 8, 2018

image

前言

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

背景

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

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

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

想让 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 模式」

「Binding 模式」

表达式

表达式,是由数字、运算符、变量等以能求得有意义数值的字符串。譬如, 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

写在最后

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

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

相关链接

作者: 木羽 zwwill
首发地址:#20

@zyg-github
Copy link

GCanvas 会来一遍么?
话说 前端交互 该怎么学 水好深 有探究吗?
寒冬大大说 “我觉得图形学这样的东西未来应该成为前端的基本技能了吧,发展到一定阶段大家肯定不满足于用脚本排列组合改改属性,要开始自己画东西了吧” 觉得该准备学点什么吗?

@zidanDirk
Copy link

赞👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants