超小Web手势库AlloyFinger原理

目前AlloyFinger做为腾讯手机QQ web手势解决方案,在各大项目中都发挥着做用。
感兴趣的同窗能够去Github看看:git

https://github.com/AlloyTeam/AlloyFingergithub

在腾讯,如:兴趣部落、QQ群、QQ动漫、腾讯学院、TEDxTencent、 AlloyTeam、腾讯CDC等多个部门、团队和项目都在使用AlloyFinger。以下图所示:web

基本上只要有图像裁剪、图像查看的地方都会使用到AlloyFinger。所以AlloyFinger也入选了腾讯code平台的精品组件:编程

除了国内外的项目团队都在使用AlloyFinger,国内外的各大IT网站也进行了转载报道,做为超级小的手势库,腾讯的web项目为何不选择hammerjs而选择AlloyFinger?下面从各个角度、架构、原理上进行一下分析。浏览器

体积

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

架构设计

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

具体实现

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

Tap点按

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

longTap长按

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

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。

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

rotate旋转

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

cross本质实际上是面积,能够看下面的推导:

因此,物理引擎里常常用cross来计算转动惯量,由于力矩其实要是力乘矩至关于面积:

总结

主要的一些事件触发原理已经在上面讲解,还有如multipointStart、doubleTap、singleTap、multipointEnd能够看源码,不到200行的代码应该很容易消化。trigger手势事件的同时,touchStart、touchMove、touchEnd和touchCancel一样也能够监听。
详细的Vector2和AlloyFinger代码能够去Github上查阅:
https://github.com/AlloyTeam/AlloyFinger
任何意见或者建议欢迎提issue:
https://github.com/AlloyTeam/AlloyFinger/issues

相关文章
相关标签/搜索