超轻量级 Web 手势库 AlloyFinger

MIT
JavaScript 查看源码»
跨平台
腾讯
2016-08-25
开源中国股瞎

AlloyFinger是腾讯AlloyTeam团队开源的超轻量级 Web 手势库。

体积

QQ截图20161111090429

可以看到hammerjs体积远远大于AlloyFinger,对于手机QQ web加载速度性能追求极致的同学来说,使用hammerjs的大小是不可以接受的!
那么,为什么hammerjs这么大?看下架构设计便可知晓。

架构设计

QQ截图20161111090621

图片1

其实,hammerjs抽象出的Class还没有列举全,还有许多。所以过度工程化,导致其体积特别大。
一个好的设计并不需要把每个逻辑点都抽象出来,局部过程化,整体OO是可以。如AlloyFinger的设计。仅仅只有Vector2和AlloyFinger,在touchstart、touchmove、touchend是可以trigger出相关的手势事件的,简单、直接!hammerjs能支持的手势,AlloyFinger都能支持。

具体实现

众所周知,浏览器暴露了四个事件给开发者,touchstart touchmove touchend touchcancel,在这四个事件的回调函数可以拿到TouchEvent。
TouchEvent:
touches:当前位于屏幕上的所有手指动作的列表
targetTouches:位于当前 DOM 元素上的手指动作的列表
changedTouches:涉及当前事件的手指动作的列表
TouchEvent里可以拿到各个手指的坐标,那么可编程性就这么产生了。

Tap点按

图片2

移动端click有300毫秒延时,tap的本质其实就是touchend。但是要判断touchstart的手的坐标和touchend时候手的坐标x、y方向偏移要小于30。小于30才会去触发tap。

longTap 长按

longtap

touchstart开启一个750毫秒的settimeout,如果750ms内有touchmove或者touchend都会清除掉该定时器。超过750ms没有touchmove或者touchend就会触发longTap

swipe 划

swipe

这里需要注意,当touchstart的手的坐标和touchend时候手的坐标x、y方向偏移要大于30,判断swipe,小于30会判断tap。那么用户到底是从上到下,还是从下到上,或者从左到右、从右到左滑动呢?可以根据上面三个判断得出,具体的代码如下:

_swipeDirection: function (x1, x2, y1, y2) {
        return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}

这个手势是使用频率非常高的,如图像裁剪的时候放大或者缩小图片,就需要 pinch。pinch 捏

QQ截图20161111093632

如上图所示,两点之间的距离比值求pinch的scale。这个scale会挂载在event上,让用户反馈给dom的transform或者其他元素的scale属性。

rotate 旋转

QQ截图20161111093842

如上图所示,利用内积,可以求出两次手势状态之间的夹角θ。但是这里怎么求旋转方向呢?那么就要使用差乘(Vector Cross)。
利用cross结果的正负来判断旋转的方向。

cross_show

cross本质其实是面积,可以看下面的推导:

QQ截图20161111094608

所以,物理引擎里经常用cross来计算转动惯量,因为力矩其实要是力乘矩相当于面积:

QQ截图201611110946526

安装:

npm install alloyfinger

使用:

new AlloyFinger(element, {
    touchStart: function () {
    },
    touchMove: function () {
    },
    touchEnd: function () {
    },
    touchCancel: function () {
    },
    multipointStart: function () {
    },
    rotate: function (evt) {
        console.log(evt.angle);
    },
    pinch: function (evt) {
        console.log(evt.scale);
    },
    multipointEnd: function () {
    },
    pressMove: function (evt) {
        console.log(evt.deltaX);
        console.log(evt.deltaY);
    },
    tap: function (evt) {
    },
    doubleTap: function (evt) {
    },
    longTap: function (evt) {
    },
    swipe: function (evt) {
        console.log("swipe" + evt.direction);
    },
    singleTap: function (evt) {
    }
});

React 版本:

render() {
    return (
        <AlloyFinger
            onTap={this.onTap.bind(this)}
            onMultipointStart={this.onMultipointStart.bind(this)}
            onLongTap={this.onLongTap.bind(this)}
            onSwipe={this.onSwipe.bind(this)}
            onPinch={this.onPinch.bind(this)}
            onRotate={this.onRotate.bind(this)}
            onPressMove={this.onPressMove.bind(this)}
            onMultipointEnd={this.onMultipointEnd.bind(this)}
            onDoubleTap={this.onDoubleTap.bind(this)}>
            <div className="test">the element that you want to bind event</div>
        </AlloyFinger>
    );
}

演示地址:http://alloyteam.github.io/AlloyFinger/

部分内容引自:http://www.alloyteam.com/2016/11/11568

的码云指数为
超过 的项目
加载中

评论(0)

暂无评论

暂无资讯

暂无问答

实用高效,27款腾讯热门开源项目推荐

腾讯作为互联网行业的一大巨头,一直都不吝啬将好的技术开放,与广大开发者共享,未来也将推出VR开放平台和AI技术。腾讯在全球合作伙伴大会披露了未来五年的发展思路,在技术共享方面,腾讯希...

2016/10/19 07:11
14.5K
39

没有更多内容

加载失败,请刷新页面

没有更多内容

返回顶部
顶部