You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
263 lines
7.7 KiB
263 lines
7.7 KiB
|
|
/* eslint-disable */
|
|
// @ts-ignore
|
|
function getLen(v) {
|
|
return Math.sqrt(v.x * v.x + v.y * v.y)
|
|
}
|
|
function dot(v1, v2) {
|
|
return v1.x * v2.x + v1.y * v2.y
|
|
}
|
|
function getAngle(v1, v2) {
|
|
var mr = getLen(v1) * getLen(v2)
|
|
if (mr === 0) return 0
|
|
var r = dot(v1, v2) / mr
|
|
if (r > 1) r = 1
|
|
return Math.acos(r)
|
|
}
|
|
function cross(v1, v2) {
|
|
return v1.x * v2.y - v2.x * v1.y
|
|
}
|
|
function getRotateAngle(v1, v2) {
|
|
var angle = getAngle(v1, v2)
|
|
if (cross(v1, v2) > 0) {
|
|
angle *= -1
|
|
}
|
|
return angle * 180 / Math.PI
|
|
}
|
|
function _swipeDirection(x1, x2, y1, y2) {
|
|
if (Math.abs(x1 - x2) >= Math.abs(y1 - y2)) {
|
|
return x1 - x2 > 0 ? 'Left' : 'Right'
|
|
} else {
|
|
return y1 - y2 > 0 ? 'Up' : 'Down'
|
|
}
|
|
}
|
|
// 实现setTimeout功能
|
|
var setTimeout = function(callback, interval, instance) {
|
|
var now = Date.now
|
|
var stime = now()
|
|
var loop = function() {
|
|
if (now() - stime >= interval) {
|
|
callback()
|
|
} else {
|
|
instance.requestAnimationFrame(loop)
|
|
}
|
|
}
|
|
instance.requestAnimationFrame(loop)
|
|
}
|
|
var start = function(event, ownerInstance) {
|
|
var instance = event.instance;
|
|
var State = instance.getState()
|
|
if(!State._init) {
|
|
State.preV = {x: null, y: null}
|
|
State.pinchStartLen = null
|
|
State.zoom = 1
|
|
State.isDoubleTap = false
|
|
State.delta = null
|
|
State.last = null
|
|
State.now = null
|
|
State.x1 = State.x2 = State.y1 = State.y2 = null
|
|
State.preTapPosition = {x: null, y: null}
|
|
// 控制定时器
|
|
State._cancelLongTap = function() {
|
|
State.longTapTimeout = false
|
|
}
|
|
State._cancelSingleTap = function() {
|
|
State.singleTapTimeout = false
|
|
}
|
|
State._tapTimeout = function() {
|
|
State.tapTimeout = false
|
|
}
|
|
State._swipeTimeout = function() {
|
|
State.swipeTimeout = false
|
|
}
|
|
State._init = true // 表示已经初始化完成
|
|
}
|
|
State.tapTimeout = true
|
|
State.singleTapTimeout = true
|
|
State.longTapTimeout = true
|
|
State.swipeTimeout = true
|
|
State.now = Date.now()
|
|
State.x1 = event.touches[0].pageX
|
|
State.y1 = event.touches[0].pageY
|
|
State.delta = State.now - (State.last || State.now)
|
|
// 触发 touchStart 事件
|
|
ownerInstance.triggerEvent('touchStart', event)
|
|
if (State.preTapPosition.x !== null) {
|
|
State.isDoubleTap = (State.delta > 0 &&
|
|
State.delta <= 250 &&
|
|
Math.abs(State.preTapPosition.x - State.x1) < 30 &&
|
|
Math.abs(State.preTapPosition.y - State.y1) < 30)
|
|
if (State.isDoubleTap) {
|
|
State._cancelSingleTap()
|
|
}
|
|
}
|
|
State.preTapPosition.x = State.x1
|
|
State.preTapPosition.y = State.y1
|
|
State.last = State.now
|
|
var preV = State.preV
|
|
var len = event.touches.length
|
|
if (len > 1) {
|
|
State._cancelLongTap()
|
|
State._cancelSingleTap()
|
|
var v = {x: event.touches[1].pageX - State.x1, y: event.touches[1].pageY - State.y1}
|
|
preV.x = v.x
|
|
preV.y = v.y
|
|
State.pinchStartLen = getLen(preV)
|
|
// 触发 multipointStart 多指点按 事件
|
|
ownerInstance.triggerEvent('multipointStart', event)
|
|
}
|
|
State._preventTap = false
|
|
setTimeout(function () {
|
|
// 触发 longTap(长按) 事件
|
|
if(State.longTapTimeout) {
|
|
ownerInstance.triggerEvent('longTap', event)
|
|
State._preventTap = true
|
|
State.longTapTimeout = true
|
|
}
|
|
}, 750, instance)
|
|
|
|
if (!instance.getDataset()['propagation']) return false
|
|
}
|
|
var move = function(event, ownerInstance) {
|
|
var instance = event.instance;
|
|
var State = instance.getState()
|
|
var preV = State.preV
|
|
var len = event.touches.length
|
|
var currentX = event.touches[0].pageX
|
|
var currentY = event.touches[0].pageY
|
|
State.isDoubleTap = false
|
|
if (len > 1) {
|
|
var sCurrentX = event.touches[1].pageX
|
|
var sCurrentY = event.touches[1].pageY
|
|
var v = {x: event.touches[1].pageX - currentX, y: event.touches[1].pageY - currentY}
|
|
if (preV.x !== null) {
|
|
if (State.pinchStartLen > 0) {
|
|
event.zoom = getLen(v) / State.pinchStartLen
|
|
// 触发 pinch 事件
|
|
ownerInstance.triggerEvent('pinch', event)
|
|
}
|
|
event.angle = getRotateAngle(v, preV)
|
|
// 触发 rotate 事件
|
|
ownerInstance.triggerEvent('rotate', event)
|
|
}
|
|
preV.x = v.x
|
|
preV.y = v.y
|
|
if (State.x2 !== null && State.sx2 !== null) {
|
|
event.deltaX = (currentX - State.x2 + sCurrentX - State.sx2) / 2
|
|
event.deltaY = (currentY - State.y2 + sCurrentY - State.sy2) / 2
|
|
} else {
|
|
event.deltaX = 0
|
|
event.deltaY = 0
|
|
}
|
|
// 触发 twoFingerPressMove 事件
|
|
ownerInstance.triggerEvent('twoFingerPressMove', event)
|
|
State.sx2 = sCurrentX
|
|
State.sy2 = sCurrentY
|
|
} else {
|
|
if (State.x2 !== null) {
|
|
event.deltaX = currentX - State.x2
|
|
event.deltaY = currentY - State.y2
|
|
// move事件中添加对当前触摸点到初始触摸点的判断,
|
|
// 如果曾经大于过某个距离(比如10),就认为是移动到某个地方又移回来,应该不再触发tap事件才对。
|
|
var movedX = Math.abs(State.x1 - State.x2)
|
|
var movedY = Math.abs(State.y1 - State.y2)
|
|
if (movedX > 10 || movedY > 10) {
|
|
State._preventTap = true
|
|
}
|
|
} else {
|
|
event.deltaX = 0
|
|
event.deltaY = 0
|
|
}
|
|
// 触发 pressMove 单指点按移动 事件
|
|
ownerInstance.triggerEvent('pressMove', event)
|
|
}
|
|
// 触发 touchMove 移动事件
|
|
ownerInstance.triggerEvent('touchMove', event)
|
|
State._cancelLongTap()
|
|
State.x2 = currentX
|
|
State.y2 = currentY
|
|
// if (len > 1) {
|
|
// // event.preventDefault()
|
|
// }
|
|
if (!instance.getDataset()['propagation']) return false
|
|
}
|
|
var end = function(event, ownerInstance) {
|
|
var instance = event.instance;
|
|
var State = instance.getState()
|
|
State._cancelLongTap()
|
|
if (event.touches.length < 2) {
|
|
// 触发 multipointEnd 多指点按结束 事件
|
|
ownerInstance.triggerEvent('multipointEnd', event)
|
|
State.sx2 = State.sy2 = null
|
|
}
|
|
// swipe
|
|
if ((State.x2 && Math.abs(State.x1 - State.x2) > 30) ||
|
|
(State.y2 && Math.abs(State.y1 - State.y2) > 30)) {
|
|
event.direction = _swipeDirection(State.x1, State.x2, State.y1, State.y2)
|
|
setTimeout(function () {
|
|
if(State.swipeTimeout) {
|
|
// 触发 swipe 滑动 上下左右 事件
|
|
ownerInstance.triggerEvent('swipe', event)
|
|
State.swipeTimeout = true
|
|
}
|
|
}, 0, instance)
|
|
} else {
|
|
setTimeout(function () {
|
|
if(State.tapTimeout) {
|
|
if (!State._preventTap) {
|
|
// 触发 tap 事件
|
|
ownerInstance.triggerEvent('tap', event)
|
|
}
|
|
// trigger double tap immediately
|
|
if (State.isDoubleTap) {
|
|
// 触发 doubleTap 事件
|
|
ownerInstance.triggerEvent('doubleTap', event)
|
|
State.isDoubleTap = false
|
|
}
|
|
State.tapTimeout = true
|
|
}
|
|
}, 0, instance)
|
|
if (!State.isDoubleTap) {
|
|
if (instance.getDataset()['requirefailure']) { // requireFailure
|
|
setTimeout(function () {
|
|
if(State.singleTapTimeout) {
|
|
// 触发 singleTap 事件
|
|
ownerInstance.triggerEvent('singleTap', event)
|
|
State.singleTapTimeout = true
|
|
}
|
|
}, 250, instance)
|
|
} else {
|
|
ownerInstance.triggerEvent('singleTap', event)
|
|
State.singleTapTimeout = true
|
|
}
|
|
}
|
|
}
|
|
// 触发 touchEnd 事件
|
|
ownerInstance.triggerEvent('touchEnd', event)
|
|
State.preV.x = 0
|
|
State.preV.y = 0
|
|
State.zoom = 1
|
|
State.pinchStartLen = null
|
|
State.x1 = State.x2 = null
|
|
State.y1 = State.y2 = null
|
|
|
|
if (!instance.getDataset()['propagation']) return false
|
|
}
|
|
var cancel = function(event, ownerInstance) {
|
|
var instance = event.instance;
|
|
var State = instance.getState()
|
|
State._cancelLongTap()
|
|
State._cancelSingleTap()
|
|
State._tapTimeout()
|
|
State._swipeTimeout()
|
|
// 触发 touchCancel 事件
|
|
ownerInstance.triggerEvent('touchCancel', event)
|
|
|
|
if (!instance.getDataset()['propagation']) return false
|
|
}
|
|
module.exports = {
|
|
start: start,
|
|
move: move,
|
|
end: end,
|
|
cancel: cancel
|
|
}
|
|
|