surface上的手势事件
依赖touch事件就可以封装各种高级的手势,包括单指和多指的手势在ios,android移动设备上已有很多的应用了。
捕获pinch事件demo: http://beyeah.sinaapp.com/line/pinch.html
(此图片来自互联网)
经过测试的浏览器有:
监听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)
//成功捕获后清除手势记录
}
}
}
IE10(仅IE10)有为触控笔和手指触摸特别准备pointer(指针)事件监听。原本在支持touch事件的移动设备浏览器上运行的交互经过较少的修改就可以应用到surface的CHROME、FOREFOX上,IE10则要花一些时间进行兼容了。
if (window.navigator.msPointerEnabled) {
// 支持指针事件
}
if(navigator.msMaxTouchPoints && navigator.msMaxTouchPoints > 1) {
//判断支持多点触控
//console.log(navigator.msMaxTouchPoints)
}
MSPointer[Over|Hover|Down|Move|Up|Out]
Pointer事件出发过程:
每一次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手势方法完成。
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; 可以防止默认的缩放。
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
通过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