移动开发框架剖析(二) Hammer专业的手势控制

浏览器底层并没有给元素提供类似,单击,双击,滑动,拖动这些直接可以用的控制接口,一切的手势动作都只能通过模拟出来。移动端浏览器唯一给我们提供的就只是mousedown -> mousemove -> mouseup三种最基本的事件接口。那么我们只能通过这些简单的接口模拟出复杂的手势出来。

常规的做法流程:

1.给元素上绑定三个事件,mousedown ,mousemove,mouseup

2.在交互的时候,用户只触发mousedown,mouseup没有触发mousemove,就可以单算是一次点击的动作, 这里可以是 单击,双击与长按,具体可以通过间隔的时间判断

3.如果mousemove触发了,自然就是滑动与拖动了

当然手势还要涉及到多点操作缩放与旋转的处理,就之后在讨论。



先抛开流程,我们要知道设计一个手势库需要考虑的问题,至少有2点:

1.运行的平台

2.用户的手势

那么我们可以总结市面上的终端设备有那么三种:

1 手机/pad移动端

2 pc类

3 还有种带触摸屏的电脑一类

用户的手势行为大体分:

单击tap , 双击doubletap,平移pan,滑动swipe,长按press,缩放pinch,旋转rotate



从设计的角度来讲,有着不同的兼容与选择问题,却又有着一些相同的共性与处理我们要如何去组织结构?

当然依旧是OOP设计了,抽出父类,实现继承,引入策略模式

我们看看Hammer在结构上是如何实现这类设计的

常规来说手势的处理,要分为初始化与执行期。初始化的时候构建所有相关的参与与方法

hammer源码里面分几大块:

1. Hammer类,一个简单的工厂方法,用来创建一个管理和初始化默认的识别器。Hammer.defaults配置一些基本的选项

包括针对每种识别器的配置与元素CSS属性的设置

2. Manager类,整个库的管理类。内部初始化了input输入对象,所有手势对象,元素css设置对象touchAction

3. InputHandler类,事件回调的具体加工类,用来生成包装后的事件对象与派发事件到每一个识别器

4. TouchAction类,设置元素的touchAction属性

5. Input类,事件处理类。用来处理绑定与销毁,事件句柄的回调。每一个输入类都需要继承

6. Recognizer类,所有识别器需要继承的基类

以上就是整个库的类块了,当然5与6都是属于基类继承的,在代码运行的时候就自动构建完毕了



关于继承inherit方法

hammer用的是传统的类似继承

function inherit(child, base, properties) {
    var baseP = base.prototype,
        childP;

    childP = child.prototype = Object.create(baseP);
    childP.constructor = child;
    childP._super = baseP;

    if (properties) {
        extend(childP, properties);
    }
}

只继承了原型的方法,因为原型都是共享的,如果放置属性可以被任何一个继承的子类所有修改,所以属性的继承需要用call方法

继承的子类有一个私有属性 _super指向父类,同时还能额外的扩展方法

inherit(MouseInput, Input, {
     handler: function MEhandler(ev){
    }
}

子类MouseInput继承父类Input类的所有原型方法,并扩展了handler方法



输入设备初始化继承:就是通过什么设备触发动作(PC,手机,ipad等等)

输入设备hammer分为

MouseInput,PointerEventInput,SingleTouchInput,TouchInput,TouchMouseInput

我们看看最简单的桌面PC的鼠标输入处理MouseInput,其余的结构基本类似。

function MouseInput() {
    this.evEl = MOUSE_ELEMENT_EVENTS;
    this.evWin = MOUSE_WINDOW_EVENTS;
    //用来禁止TouchMouse事件
    this.allow = true; // used by Input.TouchMouse to disable mouse events
    //鼠标按下的状态
    this.pressed = false; // mousedown state
    Input.apply(this, arguments);
}

inherit(MouseInput, Input, {
     handler: function MEhandler(ev){
       ..//////////////
    }
}

MouseInput初始化了几个必要的判断属性,然后就只handler方法, 此外还集成了Input输入类

比如我们调用

new MouseInput(callback)的时候,通过Input.apply(this, arguments)去初始化了基类input类,然后基类内部的init绑定了事件,并且把事件的回调,

this.domHandler指向了外部的callback回调,其实也就是handler方法了

addEventListeners(this.element, this.evEl, this.domHandler);

另一个基类就是Recognizer

因为我们把用户的行为分为单击tap , 双击doubletap,平移pan,滑动swipe,长按press,缩放pinch,旋转rotate,那么类似相同点我们也必须抽象成一个基类

Recognizer比如复杂,留在执行期的时候讲解。



Hammer 使用:

var mc = new Hammer(el);

那么内部的构建

function Hammer(element, options) {
    options = options || {};
    //配置手势识别器参数
    options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);
    return new Manager(element, options);
}

可见最终是Manager构建的对象实例了

Manager内部,通过createInputInstance创建一个输入环境的实例对象,创建一个输入环境的实例对象

this.input = createInputInstance(this);

createInputInstance的作用主要是用来选择当然的平台,不同的平台会调用不同的手势输入处理,这里就有策略选择了的处理了

function createInputInstance(manager) {
    var Type;
    var inputClass = manager.options.inputClass;

    if (inputClass) {
        Type = inputClass;
    } else if (SUPPORT_POINTER_EVENTS) {
        Type = PointerEventInput;
    } else if (SUPPORT_ONLY_TOUCH) {
        Type = TouchInput; //移动手机端
    } else if (!SUPPORT_TOUCH) {
        Type = MouseInput; //桌面
    } else {
        Type = TouchMouseInput;
    }
}

如果是桌面PC端,我们就会走MouseInput

return new MouseInput(manager, inputHandler);

这样把具体的通过Input类绑定的回调放到MouseInput的handler处理了,最终的回调会进入总处理inputHandler类

inputHandler类就会遍历所有的手势识别器把输入的input传入

manager.recognize(input);

每一个识别器各自处理其行为了,当然这里面倒是如何触发,手势识别器如何判断是那种手势,就放一章了。

官方:http://hammerjs.github.io/

我的:https://github.com/JsAaron/hammer-js

时间: 2024-10-12 08:46:09

移动开发框架剖析(二) Hammer专业的手势控制的相关文章

移动开发框架剖析(一) Hammer专业的手势控制

一直在写jQuery的源码教程,都没时间研究别的框架了.Hammer是我项目御用的一个手势库,早期1.x版本的swipe事件的响应不灵敏的问题而改过源码,2.x就已经更正过来,而且源码的结构也整个翻新了一遍,不管从逻辑还是组织结构上,我个人都觉得有必要深入,所以就当作一个系列教程一起学习吧. 本章主要讲解下使用,因为官方的API都是英文的,中文资料也相对较少,源码的分析后续再更新. 通过网方的教程还是有很多地方不是很明白的,可能需要后期看源码才能弄懂了. Hammer.js是一个专门用于控制.定

libevent源码深度剖析二

libevent源码深度剖析二 --Reactor模式 张亮 前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reactor模式进行必要的介绍,并列出libevnet中的几个重要组件和Reactor的对应关系,在后面的章节中可能还会提到本节介绍的基本概念. 1 Reactor的事件处理机制 首先来回想一下普通函数调用的机制:程序调用某函数?函数执行,程序等待?函数将结果和控制权返回给程序?程序继续处理. Reactor释义"反应堆",是一种事件驱动机制.和普通

为大二软件工程专业大学生解答的几个问题

[前言] 好久没有收到有深度的学生来信了.这与自己近一年来,忙于建设在线教学资源的缘故,没有时间动笔针对大学生学习中的问题,专门写指导性文章有关.没有了"引子",IT学子指导专栏有些冷清. 收到了某大学小谭同学的来信"致神交已久的贺利坚老师",照例回复,并发布博文. [来信] (一)自我介绍 首先还是应该自我介绍一下,我是XX大学软件工程(服务外包)专业的学生,目前是大二.我们这个专业与普通的软件工程有所不同,当初在面向山东省招生时是一个二本专业,我当初高考发挥失利

boost.asio源码剖析(二) ---- 架构浅析

* 架构浅析 先来看一下asio的0层的组件图.                     (图1.0) io_object是I/O对象的集合,其中包含大家所熟悉的socket.deadline_timer等对象,主要功能是提供接口给用户使用. services服务是逻辑功能的实现者,其中包含提供定时功能的deadline_timer_service.提供socket相关功能的win_iocp_socket_service(windows平台)/reactive_socket_service(其他

Unity3D中使用Leap Motion进行手势控制

Leap Motion作为一款手势识别设备,相比于Kniect,优点在于精确度. 在我的毕业设计<场景漫游器>的开发中,Leap Motion的手势控制作为重要的一个环节.以此,谈谈开发中使用Leap Motion进行手势识别的实现方式以及需要注意的地方. 一.对Leap Motion的能力进行评估 在设定手势之前,我们必须知道Leap Motion能做到哪种程度,以免在设定方案之后发现很难实现.这个评估依靠实际对设备的使用体验,主要从三个方面: 1.Leap Motion提供的可视化的手势识

利用手势控制动画的进度

最近在研究一个项目,利用手势控制动画的进度,发现简单的还可以,如果遇到了复杂的情况就比较麻烦了,ios7新出了一个特性,可以利用NavigationController的自定义转场动画,提供进度来控制. //这个方法控制转场动画的进度 - (id <UIViewControllerInteractiveTransitioning>)navigationController:(UINavigationController *)navigationController               

Perl入门(二)Perl的流程控制

Perl是一种粘性语言,如果你有其他语言的基础的话,你会发现他的流程控制完全和你所知的一模一样. 简单说一下他们的区别: Perl的elsif在其他语言里头可能表示为else if Perl的last,next在其他语言里头可能叫break和continue 不用找了,Perl中没有switch,其实这用if else也是可以实现的,不是么? Perl可能比你知道的语言里头多了这些:条件控制结构unless.循环控制结构until Perl还有一些特殊的写法 还是详细介绍一下Perl的流程控制吧

错误总结之播放器(vitamio)音量实体键与触摸手势控制,音量调节冲突

这个可是独家心得:经过几天的网上资料查询未果,在群里遇到一同行.然后让他帮我看了看,最终解决了该冲突.此时,谨以此来感谢那位同僚的热情帮助: 说说这个问题吧: 目前我在做一款影视方面的项目,在该项目中肯定是要用到视频播放这一块,视频播放是引用了vitamio类库,播放页面使用的是SurfaceView控件.然后在视频播放的期间,有这些要求:手势滑动调节音量.当我费劲千辛万苦搞定之后,没有想到却遇到了按音量实体键的时候播放页面退出的冲突问题.那么怎么解决该问题呢?很简单,几行代码的事情. 返回键监

前端手势控制图片插件书写一

1.前端图片处理需求场景   前端图片处理应用在很多方面,在做业务过程中我也遇到了以下问题用到前端图片处理插件. 头像上传 背景图片上传 信用卡的Diy卡面上传 H5贴纸及合成 2.手势控制的数学知识 如果想要做图片旋转放大和拖动操作,一定会涉及到移动端的手势识别和手势操作. 在移动端控制图片操作中涉及到以下几个手势:单指拖动,单指缩放,单指旋转,双指缩放,双指旋转这五种手势 . 下面来介绍下如果使用向量来识别手势. 下图是单指在图片上旋转缩放时的示意图.只需要算出bs向量和bs'向量的夹角和他