超小Web手势库AlloyFinger原理(转载)
感兴趣的同学可以去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。那么用户到底是从上到下,还是从下到上,或者从左到右、从右到左滑动呢?可以根据上面三个判断得出,具体的代码如下:
_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的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
本文转载自AlloyTeam:http://www.alloyteam.com/2016/11/11568/,如需转载请注明出处:https://www.cnblogs.com/zhuchenglin/p/7788035.html
超小Web手势库AlloyFinger原理(转载)的更多相关文章
- 超小Web手势库AlloyFinger原理
目前AlloyFinger作为腾讯手机QQ web手势解决方案,在各大项目中都发挥着作用. 感兴趣的同学可以去Github看看:https://github.com/AlloyTeam/AlloyFi ...
- 超级小的web手势库AlloyFinger发布
简介 针对多点触控设备编程的Web手势组件,快速帮助你的web程序增加手势支持,也不用再担心click 300ms的延迟了.拥有两个版本,无依赖的独立版和react版本.除了Dom对象,也可监听Can ...
- 超级小的web手势库AlloyFinger
针对多点触控设备编程的Web手势组件,快速帮助你的web程序增加手势支持,也不用再担心click 300ms的延迟了.拥有两个版本,无依赖的独立版和react版本.除了Dom对象,也可监听Canvas ...
- vue在移动端使用alloyfinger手势库操作图片拖拽、缩放
最近开发一个活动需要在手机上给上传的头像加上边框.装饰,需要拖拽.手势缩放边框下的头像图片,因为是vue项目,开始尝试了vue-drag-resize这个组件,对图片拖拽支持很完美,但是无法手势缩放, ...
- 强悍的javascript手势库
/** * Toucher * git:https://github.com/cometwo/Toucher-1 */ "use strict"; (function (root, ...
- 创建超小的Golang docker 镜像
原文: http://colobu.com/2015/10/12/create-minimal-golang-docker-images/ 本文对于创建超小的镜像非常有用 Docker是PaaS供应商 ...
- 移动端手势库hammerJS 2.0.4官方文档翻译
hammerJS是一个优秀的.轻量级的触屏设备手势库,现在已经更新到2.04版本,跟1.0版本有点天壤地别了,毕竟改写了事件名并新增了许多方法,允许同时监听多个手势.自定义识别器,也可以识别滑动方向. ...
- Web程序的运行原理及流程(一)
自己做Web程序的开发也有两年多了 从最开始跟风学框架 到第一用上框架的欣喜若狂 我相信每个程序员都是这样过来的 在大学学习一门语言 学会后往往很想做一个实际的项目出来 我当时第一次做WEB项目看 ...
- 实现一个javascript手势库 -- base-gesture.js
现在移动端这么普及呢,我们在手机上可以操作更多了.对于网页来说实现一些丰富的操作感觉也是非常有必要的,对吧(如果你仅仅需要click,,那就当我没说咯...)~~比如实现上下,左右滑动,点击之类的,加 ...
随机推荐
- [物理学与PDEs]第3章第2节 磁流体力学方程组 2.4 不可压情形的磁流体力学方程组
不可压情形的磁流体力学方程组 $$\beex \bea \cfrac{\rd {\bf H}}{\rd t}-({\bf H}\cdot\n){\bf u}&=\cfrac{1}{\sigma ...
- [物理学与PDEs]第2章习题10 一维理想流体力学方程组的 Lagrange 形式
试证明: 一维理想流体力学方程组的 Lagrange 形式 (5. 22)-(5. 24) 也可写成如下形式 $$\beex \bea \cfrac{\p \tau}{\p t}-\cfrac{\p ...
- jQuery提示组件toastr(取代alert)
给大家推荐一款jquery提示插件:toastr 它是一个可以取代alert的提示信息框,它在PC,移动设备上都有不错的UI效果. 具体使用方法如下: 1.首先在网页头站调用他需要的js和css文件. ...
- Java8从对象列表中取出某个属性的列表
List<属性值类型> 属性List = 对象List.stream().map(对象::get方法()).collect(Collectors.toList()); 例如: List&l ...
- torch.utils.data.DataLoader对象中的迭代操作
关于迭代器等概念参考:https://www.cnblogs.com/zf-blog/p/10613533.html 关于pytorch中的DataLoader类参考:https://blog.csd ...
- Linux Django项目部署
步骤 .数据库的处理 1.1 上传bbs.sql 1.2 在mysql中创建bbs库,并导入数据库SQL脚本 mysql> create database bbs charset utf8mb4 ...
- 【原创】Linux基础之SSH秘钥登录
官方:https://www.ssh.com/ssh/ The SSH protocol uses encryption to secure the connection between a clie ...
- iOS -- Effective Objective-C 阅读笔记 (9)
// 将类的实现方法代码反三到便于管理的数个分类之中. // 类中经常容易填满各种方法, 而这些方法的代码则全部堆在一个巨大的实现文件中, 有时这么做事不合理的,因为即使通过重构把这个类 ...
- PID控制器开发笔记之十二:模糊PID控制器的实现
在现实控制中,被控系统并非是线性时不变的,往往需要动态调整PID的参数,而模糊控制正好能够满足这一需求,所以在接下来的这一节我们将讨论模糊PID控制器的相关问题.模糊PID控制器是将模糊算法与PID控 ...
- 【异常处理】Java异常如何做异常处理
类似SpringMVC项目的异常处理可以这样做: 整个项目创建全局的: 1.一个自定义异常如OneException和错误码,统一封装所有异常. 2.一个返回实体类ResponseEntity,包含返 ...