超小Web手势库AlloyFinger原理

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

目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用。

感兴趣的同学可以去Github看看:

https://github.com/AlloyTeam/AlloyFinger

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

 

 

 

基本上只要有图像裁剪、图像查看的地方都会使用到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都能支持。

具体实现

众所周知,浏览器暴露了四个事件给开发者,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。那么用户到底是从上到下,还是从下到上,或者从左到右、从右到左滑动呢?可以根据上面三个判断得出,具体的代码如下:

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

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

责任编辑:庞桂玉 来源: segmentfault
相关推荐

2022-07-01 16:55:17

调试板子手势操作

2013-07-12 13:34:44

JSWeb开发

2017-09-27 15:17:54

HTML5Hybrid手势

2014-05-05 00:31:28

Leap Motion手势操控Web游戏

2015-07-22 10:34:59

手势密码源码

2018-09-07 23:38:45

小程序开发框架

2022-12-14 15:34:33

架构开发双线程

2018-03-22 19:48:47

前端HTML5数学知识

2017-08-15 17:06:55

前端HTML5手势原理

2018-07-12 10:08:31

图像超分辨率重建技术原理

2015-07-14 09:29:44

图标设计

2024-02-01 18:06:04

Python编程系统

2009-03-13 17:33:06

2018-09-28 15:31:51

小觅

2015-03-23 09:44:55

iOS开发技巧

2022-06-27 08:21:05

CSS布局

2020-06-15 14:10:29

Web 开发可视化

2013-07-18 18:14:26

UITableViewiOS长按手势UILongPress

2021-05-20 09:00:27

SwiftUI Swift TapGesture

2022-05-17 12:25:59

物联网智能建筑楼宇自控
点赞
收藏

51CTO技术栈公众号