detect_guester
Version:
this is detect user guester plugin
350 lines (312 loc) • 9.05 kB
JavaScript
var detectGuester = (function() {
var positionX = (positionY = newPositionX = newPositionY = 0);
var _param = null;
var callback = null;
// 滑動
var swipe = function(param) {
_param = param;
if (param.hasOwnProperty('target')) {
if (typeof param.target === 'string') {
var el = $(param.target);
el.on('mousedown touchstart', function(e) {
e.preventDefault();
//e = e || window.event;
positionX = e.clientX;
positionY = e.clientY;
el.on('mouseup touchend', function(e) {
e.preventDefault();
_off(el);
});
el.on('mousemove touchmove', function(e) {
e.preventDefault();
//e = e || window.event;
newPositionX = positionX - e.clientX; // 往左變大, 往右邊小
newPositionY = positionY - e.clientY; // 往上變小,往下變大
var threshold = 100;
var absNewPositionX = Math.abs(newPositionX);
var absNewPositionY = Math.abs(newPositionY);
if (param.hasOwnProperty('direction')) {
if (typeof param.direction === 'string') {
switch (param.direction) {
case 'left':
if (newPositionX > 0) {
if (absNewPositionX >= threshold) {
_checkEventExists(param);
_off(el);
}
}
break;
case 'right':
if (newPositionX < 0) {
if (absNewPositionX >= threshold) {
_checkEventExists(param);
_off(el);
}
}
break;
case 'top':
if (newPositionY > 0) {
if (absNewPositionY >= threshold) {
_checkEventExists(param);
_off(el);
}
}
break;
case 'down':
if (newPositionY < 0) {
if (absNewPositionY >= threshold) {
_checkEventExists(param);
_off(el);
}
}
break;
}
} else {
throw new Error('params direction must be string');
}
} else {
throw new Error('must be set direction params');
}
});
});
} else {
throw new Error('param target element must be string');
}
} else {
throw new Error('no set target element');
}
};
//press
var press = function(param) {
_param = param;
if (param.hasOwnProperty('target')) {
if (typeof param.target === 'string') {
var el = $(param.target);
el.on('mousedown touchstart', function(e) {
e.preventDefault();
_checkEventExists(param);
el.on('mouseup touchend', function(e) {
e.preventDefault();
_off(el);
});
});
} else {
throw new Error('param target must be string');
}
} else {
throw new Error('no set target element');
}
};
//longPress
var longPress = function(param) {
_param = param;
if (param.hasOwnProperty('target')) {
if (typeof param.target === 'string') {
var el = $(param.target);
var waitTime = 1500;
if (param.hasOwnProperty('wait_time')) {
if (typeof param.wait_time === 'integer') {
waitTime = param.wait_time;
} else {
throw new Error('param wait time must be integer');
}
}
el.on('mousedown touchstart', function(e) {
e.preventDefault();
setTimeout(function() {
_checkEventExists(param);
}, waitTime);
el.on('mouseup touchend', function(e) {
e.preventDefault();
_off(el);
});
});
} else {
throw new Error('param target must be string');
}
} else {
throw new Error('no set target element');
}
};
//旋轉
var rotate = function(param) {
_param = param;
if (_param.hasOwnProperty('target')) {
if (typeof _param.target === 'string') {
var el = $(_param.target);
el.on('mousedown touchstart', function(e) {
e.preventDefault();
positionX = e.clientX;
positionY = e.clientY;
if (e.touches instanceof Array) {
if (e.touches.length > 2) {
var firstTouchPositionX = e.touches[0].clientX;
var firstTouchPositionY = e.touches[0].clientY;
var secondTouchPositionX = e.touches[1].clientX;
var secondTouchPositionY = e.touches[1].clientY;
positionX = firstTouchPositionX;
positionY = firstTouchPositionY;
}
}
el.on('mouseup touchend', function(e) {
e.preventDefault();
_off(el);
});
el.on('mousemove touchmove', function(e) {
e.preventDefault();
newPositionX = e.clientX;
newPositionY = e.clientY;
if (e.touches instanceof Array) {
if (e.touches.length > 2) {
var firstNewTouchPositionX = e.touches[0].clientX;
var firstNewTouchPositionY = e.touches[0].clientY;
var secondNewTouchPositionX = e.touches[1].clientX;
var secondNewTouchPositionY = e.touches[1].clientY;
newPositionX = firstNewTouchPositionX;
newPositionY = firstNewTouchPositionY;
}
}
// 計算弧度
/**
* ref :
* https://blog.csdn.net/pvfhv/article/details/6154839
* https://blog.csdn.net/W_han__/article/details/52764433
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan2
* https://zh.wikipedia.org/wiki/Atan2
*/
var arch = Math.atan2(newPositionY - positionY, newPositionX - positionX);
var angle = arch * 180 / Math.PI; // 弧度轉角度
if (angle <= 20 && angle >= -20) {
// alert('rotate right');
_checkEventExists(param);
_off(el);
} else if (angle <= 110 && angle >= 70) {
// alert('rotate down');
_checkEventExists(param);
_off(el);
} else if (angle > 90 && angle < 180) {
// alert('rotate left');
_checkEventExists(param);
_off(el);
}
});
});
} else {
throw new Error('param target must be string');
}
} else {
throw new Error('no set target element');
}
};
// 縮放
// ref: https://developer.mozilla.org/en-US/docs/Web/API/Pointer_events/Pinch_zoom_gestures
var zoom = function(param) {
_param = param;
if (_param.hasOwnProperty('target')) {
if (typeof _param.target === 'string') {
var el = $(_param.target);
if (_param.hasOwnProperty('direction')) {
if (typeof _param.direction === 'string') {
var direction = _param.direction;
var fingers = []; // 存放手指數
var preDiff = -1; // 初始的兩指距離
el.on('pointerdown', function(e) {
fingers.push(e);
if (fingers.length === 2) {
preDiff = Math.abs(fingers[0].clientX - fingers[1].clientX);
}
});
el.on('pointermove', function(e) {
for (var i = 0; i < fingers.length; i++) {
if (fingers[i].pointerId === e.pointerId) {
fingers[i] = e;
}
}
if (fingers.length === 2) {
var curDiff = Math.abs(fingers[0].clientX - fingers[1].clientX);
var diff = curDiff - preDiff;
if (diff > 0 && direction === 'in') {
// zoom in
_checkEventExists(param);
_offPointer(el);
} else if (diff < 0 && direction === 'out') {
// zoom out
_checkEventExists(param);
_offPointer(el);
}
preDiff = curDiff;
}
});
el.on('pointerup', function(e) {
//手指上來時,要從fingers移除
for (var i = 0; i < fingers.length; i++) {
if (fingers[i].pointerId == e.pointerId) {
fingers.splice(i, 1);
break;
}
}
if (fingers.length < 2) {
preDiff = -1;
}
if (fingers.length == 0) {
_offPointer(el);
// _clear();
}
});
} else {
throw new Error('param direction must be string');
}
} else {
throw new Error('param direction must be set');
}
} else {
throw new Error('param target element must be string');
}
} else {
throw new Error('no set target element');
}
};
var _offPointer = function(el) {
el.off('pointerup');
el.off('pointermove');
};
// 清空監聽事件
var _off = function(el) {
el.off('mouseup');
el.off('mousemove');
el.off('touchstart');
el.off('touchmove');
_clear();
};
// 清空變數
var _clear = function() {
positionX = positionY = newPositionX = newPositionY = 0;
_param = null;
};
// 檢查是否有設定callback
var _checkEventExists = function(param) {
if (!_param) _param = param;
if (_param) {
if (_param.hasOwnProperty('callback')) {
if (typeof _param.callback === 'function') {
try {
_param.callback();
} catch (err) {
throw new Error(err.message);
}
} else {
throw new Error('param callback must be function');
}
} else {
throw new Error('not set callback function');
}
}
};
return {
swipe: swipe,
press: press,
longPress: longPress,
rotate: rotate,
zoom: zoom
};
})();