H5多点触控原理以及对多点触控的追踪
文章目录
- 接触点类Touch
- 触摸事件
- 接触点的生命周期类
- 多点触控的追踪器
- 抛砖引玉
对于PC端,我们的点击事件比较简单,因为鼠标指针只有一个。
但是对于移动端来说,存在多个接触点同时操作的情况,这种情况就是我们今天要研究的主题 – 多点触控。
接触点类Touch
移动端的任何触摸都会触发一个事件,该事件会携带一个touchList列表来表示:当前有哪些接触点正在作用于我们的屏幕。
通俗点的解释,接触点可以理解为你的手指,touchList列表就代表了当前总共有几个手指正在与屏幕接触。
而touchList列表中的每一项都是Touch类
的对象,它包含了我们手指与屏幕接触的必要信息:接触点的位置、压力大小、接触面积等等。
所以,在介绍之前,我们必须要先了解这个类。它代表的是屏幕上接触的点。具体属性值如下:
// Touch类 属性说明// 接触点的唯一标识,每个接触点的id在接触过程中都是唯一的,即每个手指都会分配一个id
`identifier` // 接触点的位置信息,这几个属性与pc端是一样的
`clientX:0`
`clientY:0`
`pageX:0`
`pageY:0`
`screenX:0`
`screenY:0`// 接触点的压力值大小 0.0-1.0之间
`force:0`// 这三个参数指示了包含接触点的最小椭圆
`radiusX:0` //椭圆x轴长
`radiusY:0` //椭圆y轴长
`rotationAngle:0` // 椭圆旋转角度// 接触点接触的HTML对象
`target:DocumentHTMLDom`
读者朋友可以看出来,上面这个类,准确的定义了一个接触点的各种属性。那么,在哪才能得到这些接触点的对象呢?
聪明如你,估计已经猜到了,那就是在触摸事件
中。
注意属性中的identifier
哦~非常重要!
触摸事件
上面也提到了,Touch类只会存在于触摸事件里。常用的触摸事件有touchestart、touchmove、touchend、touchcacel
。
它们都是TouchEvent类
的实例,TouchEvent类的属性包含了前面介绍的接触点Touch实例列表
。我们主要关注它的三个属性即可,如下:
TouchEvent.changedTouches
这是一个只读属性,是一个TouchList对象,它包含了代表所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的 Touch 对象。TouchEvent.touches
这是一个只读属性,是一个TouchList对象,它包含了所有当前正在接触的接触点Touch对象,无论它们的起始于哪个element上,也无论它们状态是否发生了变化。TouchEvent.targetTouches
这是一个只读属性,是一个TouchList对象,它包含了如下触点的 Touch 对象:触摸起始于当前事件的目标 element 上,并且仍然没有离开触摸平面的触点。
完整的属性列表,可以参考MDN文档,https://developer.mozilla.org/zh-CN/docs/Web/API/TouchEvent。
对于手势库来说,这几个TouchList属性已经够用了。
接触点的生命周期类
想一想我们一个手指在屏幕上滑动的过程:开始接触 -> 接触时的移动 -> 接触结束。
这实际上就是一个接触点的生命周期,我们来为这一过程定义一个数据结构吧。
/*** touch事件的生命周期类* @constructor* */
var TouchLife = (function () {var id = 0;return function () {/*** 生命周期的id* @type {number}* */this.id=id++;/*** 开始的touch事件* @type {Touch}* */this.startTouchEvent = null;/*** 结束的touch事件* @type {Touch}* */this.endTouchEvent = null;/*** 移动的touch事件* @type {Touch[]}* */this.moveTouchEventList = [];};
})();
生命周期的开始和结束都只需要一个Touch对象
,而移动可以多次移动,需要一个TouchList
来保存。
另外附加了一个生命周期的ID,用来唯一标识一次生命周期。
多点触控的追踪器
有了接触点的生命周期,我们还需要一个追踪器,用来追踪多个接触点的生命周期。
试想一下,对于PC,只有一个鼠标指针,我们能很好的记录它的运行轨迹。
但是对于移动端,当存在多个接触点同时作用于屏幕时,怎么来记录他们的运行轨迹呢?
这就是追踪器的主要功能:记录接触点的运行轨迹。
除此之外,在某个生命周期状态变化的时候,追踪器应该能通知应用程序做处理。
这里直接给出它的实现:
/*** touch事件追踪器* @param opt* @param opt.target 被追踪的dom对象* @constructor*/
function TouchLifeTracer(opt) {/*** 追踪的对象* */this.target = opt.target;/*** 作用于target的所有生命周期,包含存活和死亡的周期* */this._lifeList = [];/*** 当前存活的生命周期,正在与target接触的触摸点生命周期* */this.currentLifeList = [];/*** 某个生命周期开始* @type {function}* @param callback(life)* */this.onlifestart = null;/*** 某个生命周期状态变更* @type {function}* @param callback(life)* */this.onlifechange = null;/*** 某个生命周期开始* @type {function}* @param callback(life)* */this.onlifeend = null;/*** 添加生命周期* @param life {TouchLife} 生命周期* @return {*}*/this.addLife = function (life) {this._lifeList.push(life);};/*** 根据identifier查找生命周期,此方法只能在生命周期内使用* @param identifier* @return {*}*/this.findCurrentLifeByTouchID = function (identifier) {for(var i=0;i<this.currentLifeList.length;i++){var life = this.currentLifeList[i];if(life.startTouchEvent.identifier===identifier)return life;}};/*** 根据touchID删除当前触摸的生命周期* @param identifier* @return {boolean}*/this.deleteCurrentLifeByTouchID = function (identifier) {for(var i=0;i<this.currentLifeList.length;i++){var life = this.currentLifeList[i];if(life.startTouchEvent.identifier===identifier){this.currentLifeList.splice(i,1);return true;}}return false;};/*** 初始化*/this.init = function () {var self = this;this.target.addEventListener("touchstart",function (e) {e.preventDefault();var touchLife = new TouchLife();touchLife.startTouchEvent = e.changedTouches[0];self.addLife(touchLife);self.currentLifeList.push(touchLife);self.onlifestart && self.onlifestart(life);});this.target.addEventListener('touchmove',function (e) {e.preventDefault();var touches = e.changedTouches;for(var i=0;i<touches.length;i++){var touch = touches[i];var life = self.findCurrentLifeByTouchID(touch.identifier);life.moveTouchEventList.push(touch);self.onlifechange && self.onlifechange(life);}});this.target.addEventListener('touchend',function (e) {e.preventDefault();var touch = e.changedTouches[0];var life = self.findCurrentLifeByTouchID(touch.identifier);life.endTouchEvent = touch;self.deleteCurrentLifeByTouchID(touch.identifier);self.onlifeend && self.onlifeend(life);});};this.init();
}
上面这个算是最简单的追踪器了,它仅仅包含了最基本的属性和方法。包括:
- 几个必要的属性:
追踪器作用的对象、存活的生命周期、全部生命周期
。 - 几个必要的方法:
新增生命周期、删除生命周期、查找生命周期、追踪器的初始化
。 - 几个必要的事件:
生命周期的开始、生命周期的变化、生命周期的结束
。
存活的生命周期,对应于我们正在接触屏幕的手指。
而全部生命周期,对应于我们所有接触屏幕的历史记录。
有了这个追踪器,我们在监控多点触控的时候,就相当的方便了。比如:
// 获取元素
var a1 = document.getElementById('canvasID');// 初始化
var tracer = new TouchLifeTracer({target:a1});
tracer.onlifestart = function (life) {//todo with life startconsole.log('检测到一个新的接触点触摸元素');
};
tracer.onlifeend = function (life) {//todo with life endconsole.log('检测到一个接触点离开元素');
};
抛砖引玉
有了这个追踪器,是不是就可以自己撸一个手势库出来了呢?答案是肯定的。
手势库的原理,也就是多点触控+手势的判断条件,仅此而已!
百度搜手势库比较靠前的,比如Hammer.js,比如AlloyFinger,这些库都是基于这两点基础知识来对手势进行模拟的。
始终相信,别人能做到的,我们也能做到!
那么,下篇文章我们就来真正的实现一个手势库,敬请期待!
觉得有用,还请点赞收藏!
励志前端,CSDN唯一账号!关注我,带你了解更多前端知识!
H5多点触控原理以及对多点触控的追踪相关推荐
- 智能门锁:触控原理概述
智能门锁的识别技术中,密码几乎成为标配功能.相比机械按键的触控方式,电容式触控方式可以在加上一层玻璃甚至金属一体成型之后与用户进行交互,由于进行了物理性隔离,使得外壳更具完整性,物理上安全性更佳. 目 ...
- 惠普触控板使用指南_Windows10触控板的正确使用方法
如何正确使用Windows10系统的触控板?Windows的触控板虽然不及MacBook,但是它的功能也不能小觑哦!如果你觉得Windows的触控板太LOW了,可能是你的使用方法不对.下面小编给大家分 ...
- H5 可视化构建工具原理解析(一)
前言 总共进 8 万行代码实现H5可视化构建工具,自去年十月开始陆续做了大半年,现已投入到业务中使用,虽然算是个人项目,但组件和部署模块涉及大量公司业务代码,就不开源了,主要讲讲实现思路,算是该项目的 ...
- [解决]关于Manjaro KDE更新系统至Manjaro 18.0.4 Illyria在心触控板驱动下轻触功能缺失的问题
如题:关于Manjaro KDE更新系统至Manjaro 18.0.4 Illyria在心触控板驱动下轻触功能缺失的问题 由于xf86-input-synaptics驱动已经停止了维护工作, 所以ma ...
- H5新特性百度地图SDK--API引入、地图控件、地理编码与逆地理编码、地图标注、路径规划(基于2.0)
一.API基本使用 1.1 大致流程 打开,百度地图官网 登录或者注册一个百度账号,并完成相关验证 登陆并申请成为开发者 在百度地图开发平台的首页选择控制台,在控制台中创建应用 创建好应用以后就能在控 ...
- 手机屏幕常见故障_触屏不灵敏、断触怎么回事?手机触摸屏的基本原理与常见问题排查方法介绍...
手机触摸屏断触是怎么回事?大家在日常使用中可能会碰到各种各样的触摸屏问题,类似:断触,滑动屏幕不跟手,输入法打字不灵敏,游戏中多点触摸不灵敏,等问题,下面咱们从利用排除法来进行排查定位.想要弄清手机触 ...
- 工控软件图形界面-控件实现(圆形仪表控件三)(zz)
介绍 在工业控制系统开发过程中,图形显示方面占有着很重要的作用.比起很多专用的组态软件,他们有着强大的在图形系统,能够组态出来非常漂亮的系统.现在的很多的工业图形开发包都需要支付费用,很多漂亮的控件比 ...
- Auto.js 控件属性缺失时获取控件
Auto.js 在控件属性缺失情况下获取控件 群里有很多新人问,各种既没有id也没有text的控件无法获取的问题. 文章目录 Auto.js 在控件属性缺失情况下获取控件 使用环境 一.具体操作 只用 ...
- 2012r2备域控服务器搭建,Windows2012R2备用域控搭建
前置操作 域控 主域控的主dns:自己的ip 备域控的主dns:自己的ip,备dns:主域控的ip 客户端 主dns:主域控的ip,备dns:备域控的ip 一般说主和备,主要是指担任PDC放置的角色的 ...
- Asp.net控件之异同:HTML控件与Web服务器控件
Asp.net之所以现在开发方便和快捷,关键是它有一组强大的控件库,包括web服务器控件,web用户控件,web自定义控件,html服务器控件和html控件等.这里我主要说说html控件.html服务 ...
最新文章
- SRM 397(1-250pt)
- 会声会影X4 初学者速成 转
- 直播回顾 | 数据驱动实践的三大运营场景讲解
- SAP CRM呼叫中心和社交媒体集成的所有BC set实现列表
- Asp.Net Core 中如何设置 IP 白名单
- Linux下scp命令的用法
- 零基础 Amazon Web Services (AWS) 入门教程 (列表)
- 开源软件冲破云霄,“机智号”直升机首飞成功,还带来了第一个火星机场!...
- 关于野指针及指针所指内存被回收后的一些误区
- hdu 3501(欧拉函数)
- 盘点下玩过的解谜游戏
- 计算机开机后无法正常显示桌面图标,电脑开机后不显示桌面图标怎么办
- 18104 练习使用多case解题(3种多case的情况)(c语言或c++)
- 华为多屏互动看学英语
- yii mysql gii_Yii整合mongodb和mysql 使用mongodb gii
- 你觉得一个测试工程师应该具备哪些素质和技能?
- Some Enforcer rules have failed. Look above for specific messages explaining why the rule failed.
- 计算密码子频率的代码R语言_科学网—R语言终止密码子统计 - 熊荣川的博文
- 计算机无法安装蓝牙设备,笔记本蓝牙无法添加设备解决方法
- Lake Shore M91快速霍尔测量仪