xiaoc_

surface上的手势事件

surface上的手势事件


1、surface上的触控事件测试。

  • 手指触控在CHROME和FIREFOX下会触发touch事件,而IE10是不支持touch事件的。
  • 手指触控在三个浏览器下均会触发全部的mouse事件。
  • 触控笔在三个浏览器下均会触发mouse事件。
  • 触控笔的触控不能触发CHROME和FIREFOX下的touch事件。

2、通过touch事件来判断一个双指手势:pinch。

依赖touch事件就可以封装各种高级的手势,包括单指和多指的手势在ios,android移动设备上已有很多的应用了。

touch事件触发过程:
  • 第一根手指按下:touchstart
  • 第二根手指按下:touchstart
  • ……
  • 滑动手指:touchmove
  • 第一根手指抬起:touchend
  • 第二根手指抬起的时候:touchend,此时event.touches.length == 0

捕获pinch事件demo: http://beyeah.sinaapp.com/line/pinch.html

(此图片来自互联网)

经过测试的浏览器有:

  • IOS上的safari和chrome[v28.0.1500],
  • Android上的chrome,
  • surface上的chrome[v28.0.1500]和firefox[v23.0.1](surface上的safari不支持touch事件,不在此次测试范围) 均能正确的通过touch事件捕获pinch手势。

监听touch事件:

 //touchStart 记录的是最后一根手指落下时的状态
 function touchstart(e){
      var touches = e.touches;
           fingers = touches.length;
      touchStart = getTouches(touches,fingers);
 }
 //滑动过程中 任何时候的触摸状态curentTouch与初始状态进行比较
 function touchmove(e){
      var touches = e.touches;
      if(touches.length == fingers){
           curentTouch = getTouches(touches,fingers);
           if(fingers == 2){
                //通过起始和结束的双指距离来判断
                var c_distance = parseInt(distance(curentTouch),10);
                var s_distance = parseInt(distance(touchStart),10);
                var diff = s_distance - c_distance;
                Gesture.pinch_diff = diff;
                if(Math.abs(diff) > 10){
                     //连续触发touchmove :pinching

                }
           }
      }else{...}
 }
 //双指动作抬起则会触发两次touchend事件
 function touchend(e){
      if(fingers == 2){
           if(Math.abs(Gesture.pinch_diff) > 10){
                var type;
                if(Gesture.pinch_diff > 0){
                     type = 'pinchIn';
                }else{
                     type = 'pinchOut';
                }
                alert(type)
                //成功捕获后清除手势记录
           }
      }
 }

3、IE10上的触摸事件以及捕获pinch事件IE10实现

IE10(仅IE10)有为触控笔和手指触摸特别准备pointer(指针)事件监听。原本在支持touch事件的移动设备浏览器上运行的交互经过较少的修改就可以应用到surface的CHROME、FOREFOX上,IE10则要花一些时间进行兼容了。

 if (window.navigator.msPointerEnabled) {
        // 支持指针事件
 }
 if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) {
      //判断支持多点触控
      //console.log(navigator.msMaxTouchPoints)
 }
Pointer事件:

MSPointer[Over|Hover|Down|Move|Up|Out]

Pointer事件出发过程:

  • down:第一根手指down->第二根手指down->
  • move: 第一根手指move->第二根手指move->
  • end: 第一根手指up->第二根手指up->

每一次event都包含当前手指的触摸信息,相比touch事件,Pointer事件提供的接口参数更接近于mouse事件。

捕获pinch事件demo: http://beyeah.sinaapp.com/line/pinch.html

//pointer事件与touch事件数据格式区别较大,故另写方法处理监听
function pointerDown(e){
      var pointerId = e.pointerId;
      var x = e.offsetX;
      var y = e.offsetY;
      //保持事件状态记录的数据格式一致,以便判断
      !pointerStart[pointerId] && (pointerStart[pointerId] = {
           'x' : x,
           'y' : y
      });
 }
 function pointerMove(e){
      var pointerId = e.pointerId;
      var x = e.offsetX;
      var y = e.offsetY;
      curentPointer[pointerId] = {
           'x' : x,
           'y' : y
      }
      _pointerStart = [];
      _curentPointer = [];
      for(var i in pointerStart){
           _pointerStart.push(pointerStart[i]);
           _curentPointer.push(curentPointer[i]);
      }
      //同touch事件判断pinch手势的条件一致
      if(_curentPointer.length == 2){
           var c_distance = parseInt(distance(_curentPointer),10);
           var s_distance = parseInt(distance(_pointerStart),10);
           var diff = s_distance - c_distance;
           POINTER.pinch_diff = diff;
           if(Math.abs(diff) > 10){
                //pinching

           }
      }
 }

至此:兼容surface IE10的捕获pinch手势方法完成。

tips:
  • a、在surface上,长按默认会触发系统右键菜单,在长按行为另有它用的节点上可以这样来禁用掉:

    element.addEventListener("MSHoldVisual", function(e) { e.preventDefault(); }, false); element.addEventListener("contextmenu", function(e) { e.preventDefault(); }, false);

  • b、IE10使用一个css属性:-ms-touch-action: none; 可以防止默认的缩放。

  • c、移动设备safari浏览器上阻止默认双指缩放

    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">

4、IE10的MSGesture对象以及触控笔事件

MSPointer[Over|Hover|Down|Move|Up|Out] ,
  • 触控笔会触发此事件 : over ->hover ->down->move->up-<hover->out
  • 手指触控会触发:over->down->move->up->out
  • 触控笔除了可以比手指更精准的替代鼠标操作外,专门针对触控笔的IE10应用可能会陆续出现。
微软还提供了一个MSGesture对象来支持较高级别的笔势(如按、平移、点击)而无需自己捕获每个指针事件。

通过MSGesture对象来判断滑动:

//实例化一个手势对象
var gesture = new MSGesture();
var elm = document.body;
gesture.target = elm;
//手势对象在手势识别期间处理哪些指针
 elm.addEventListener("MSPointerDown", function (evt) {
      gesture.addPointer(evt.pointerId);
 });

//判断手势状态的三个事件:MSGestureStart、MSGestureChange(随着手势的持续重复触发)和 MSGestureEnd
//MSgesture对象返回的每个事件都包含缩放(收缩)、旋转、转换和速度等相关信息。
//通过连续触发的MSGestureChange事件的速度信息简单的判定一个动态手势

 function handlegesture(e){
    //通过滑动速度判断swipe  
      if(e.velocityX>1.5){
           alert('swipright');
      }
      if(e.velocityX<-1.5){
           alert('swipleft');
      }
      //直接通过scale信息判断pinch
      if(e.scale > 1){
        alert('pinchout')
      }else if(e.scale < 1){
        alert('pinchin')
      }
 }
//轻击,长按等静态手势,则可直接判定:
//MSGestureHold,MSGestureTap
function handlegesturetap(){
      alert('tap')
 }
 //监听事件
elm.addEventListener("MSGestureChange", handlegesture);
elm.addEventListener("MSGestureTap", handlegesturetap);

demo: http://beyeah.sinaapp.com/line/pointer.html

5、小结

  1. 目前通过UA信息无法区分是支持触摸的surface还是普通的PC。可以通过['createTouch' in document]来判断是否支持touch事件。JQuery Mobile封装的tap,swipe等基础的单指手势事件在surface上得到较好的支持。但surface并未被识别为支持触摸的Mobile设备,得到支持是因为JQuery Mobile向mouse事件的兼容。
  2. 如果应用面向全部的移动设备的话,比起使用MSGesture对象提供事件信息,在原touch事件上监听pointer事件向surface-IE10作兼容可能具有更好的扩展性。
  3. 现有的web网页针对surface和大屏的ipad等pad设备在兼容mouse事件的基础上加一些手势交互能较好的提升用户体验。
  4. demo会继续更新并添加更多手势判定
参考文档:
  • http://msdn.microsoft.com/zh-cn/library/ie/hh968249(v=vs.85).aspx
  • http://www.w3.org/TR/touch-events/
  • JQuery Mobile:http://api.jquerymobile.com/

posted on 2013-09-25 17:07  xiaoc_  阅读(4575)  评论(0编辑  收藏  举报

导航