any-touch
Advanced tools
Comparing version 0.0.25 to 0.0.26
@@ -270,3 +270,3 @@ 'use strict'; | ||
if (x === y) { | ||
return undefined; | ||
return 'none'; | ||
} | ||
@@ -311,7 +311,7 @@ else if (Math.abs(x) > Math.abs(y)) { | ||
var prevPointers = undefined; | ||
var prevPointers; | ||
var isPressed = false; | ||
var mouseAdapter = (function (event) { | ||
var clientX = event.clientX, clientY = event.clientY, type = event.type; | ||
var changedPointers = prevPointers; | ||
var changedPointers = prevPointers || [{ clientX: clientX, clientY: clientY }]; | ||
var pointers = [{ clientX: clientX, clientY: clientY }]; | ||
@@ -352,3 +352,3 @@ prevPointers = [{ clientX: clientX, clientY: clientY }]; | ||
var input = {}; | ||
if (IS_MOBILE) { | ||
if (SUPPORT_TOUCH) { | ||
input = touchAdapter(event); | ||
@@ -539,27 +539,3 @@ } | ||
var abs = Math.abs, max = Math.max; | ||
var computed = { | ||
pointerLength: input.pointerLength, | ||
changedPointerLength: input.changedPointerLength, | ||
displacementX: 0, | ||
displacementY: 0, | ||
distanceX: 0, | ||
distanceY: 0, | ||
distance: 0, | ||
direction: undefined, | ||
lastDirection: undefined, | ||
deltaX: undefined, | ||
deltaY: undefined, | ||
velocityX: 0, | ||
velocityY: 0, | ||
maxVelocity: 0, | ||
duration: 0, | ||
timestamp: Date.now(), | ||
angle: 0, | ||
deltaAngle: 0, | ||
scale: undefined, | ||
deltaScale: 1, | ||
lastVelocity: undefined, | ||
lastVelocityY: undefined, | ||
lastVelocityX: undefined, | ||
}; | ||
var computed = {}; | ||
var _b = computeDistance({ | ||
@@ -571,3 +547,3 @@ startInput: startInput, | ||
computed.direction = getDirection(displacementX, displacementY); | ||
computed.duration = input.timestamp - startInput.timestamp; | ||
computed.deltaTime = input.timestamp - startInput.timestamp; | ||
var lastComputed = computeLast(input); | ||
@@ -588,4 +564,4 @@ computed.lastVelocityX = lastComputed.velocityX; | ||
} | ||
computed.velocityX = abs(computed.distanceX / computed.duration) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.duration) || 0; | ||
computed.velocityX = abs(computed.distanceX / computed.deltaTime) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.deltaTime) || 0; | ||
computed.maxVelocity = max(computed.velocityX, computed.velocityY); | ||
@@ -606,3 +582,4 @@ if (undefined !== prevInput && 1 < prevInput.pointers.length && 1 < input.pointers.length) { | ||
var maxPointerLength = computeMaxLength(input); | ||
return __assign({}, input, { maxPointerLength: maxPointerLength }, computed); | ||
computed = __assign({}, computed, input, { maxPointerLength: maxPointerLength }); | ||
return computed; | ||
} | ||
@@ -660,4 +637,3 @@ | ||
function Recognizer(options) { | ||
if (options === void 0) { options = { disabled: false }; } | ||
this.options = __assign({}, this.default, options); | ||
this.options = __assign({}, this.constructor.DEFAULT_OPTIONS, { disabled: false }, options); | ||
this.name = this.options.name; | ||
@@ -670,21 +646,20 @@ this.disabled = this.options.disabled; | ||
Recognizer.prototype.set = function (options) { | ||
if (options === void 0) { options = {}; } | ||
this.options = __assign({}, this.options, options); | ||
this.$root.update(); | ||
}; | ||
Recognizer.prototype.$injectRoot = function ($root) { | ||
this.$root = $root; | ||
return this; | ||
}; | ||
Recognizer.prototype.emit = function (type, payload) { | ||
payload.type = type; | ||
this.eventBus.emit(type, payload); | ||
if (this.hasDomEvents) { | ||
this.$root.eventBus.emit(type, payload); | ||
if (this.$root.options.hasDomEvents) { | ||
var target = payload.target, currentTarget = payload.currentTarget, type_1 = payload.type, data = __rest(payload, ["target", "currentTarget", "type"]); | ||
var event = new Event(type_1, payload); | ||
Object.assign(event, data); | ||
this.el.dispatchEvent(event); | ||
this.$root.el.dispatchEvent(event); | ||
} | ||
}; | ||
Recognizer.prototype.on = function (type, listener) { | ||
this.eventBus.on(type, listener); | ||
}; | ||
Recognizer.prototype.off = function (type, listener) { | ||
this.eventBus.off(type, listener); | ||
}; | ||
Recognizer.prototype.requireFailure = function (recognizer) { | ||
@@ -754,3 +729,3 @@ if (!this.requireFailureRecognizers.includes(recognizer)) { | ||
Recognizer.prototype.isVaildDirection = function (direction) { | ||
return -1 < this.options.directions.indexOf(direction); | ||
return -1 !== this.options.directions.indexOf(direction) || 'none' === direction; | ||
}; | ||
@@ -760,3 +735,3 @@ Recognizer.prototype.recognize = function (computed) { | ||
var isVaild = this.test(computed); | ||
if (-1 < [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
if (-1 !== [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
@@ -805,3 +780,2 @@ } | ||
var _this = _super.call(this, options) || this; | ||
_this.tapTimeoutId = null; | ||
_this.tapCount = 0; | ||
@@ -815,52 +789,76 @@ return _this; | ||
var _this = this; | ||
this.status = STATUS_POSSIBLE; | ||
if (this.test(computed)) { | ||
this.tapCount++; | ||
var isValidTapCount_1 = this.options.taps === this.tapCount; | ||
if (this.hasRequireFailure()) { | ||
this.cancel(); | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (isValidTapCount_1 && _this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
_this.tapCount = 0; | ||
}, this.options.interval); | ||
if (INPUT_END !== computed.inputStatus) | ||
return; | ||
if (-1 < [STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
} | ||
var isValidEachTap = this.test(computed); | ||
var max = Math.max, pow = Math.pow, sqrt = Math.sqrt; | ||
var x = computed.x, y = computed.y; | ||
if (undefined === this.prevTapX || undefined === this.prevTapY) { | ||
this.isValidMovementFromPrevTap = true; | ||
} | ||
else { | ||
this.isValidMovementFromPrevTap = 10 > sqrt(max(pow(x - this.prevTapX, 2), pow(y - this.prevTapY, 2))); | ||
} | ||
this.prevTapX = x; | ||
this.prevTapY = y; | ||
if (isValidEachTap) { | ||
clearTimeout$1(this.tapTimeout2Id); | ||
if (this.isValidMovementFromPrevTap) { | ||
this.tapCount++; | ||
} | ||
else { | ||
this.cancel(); | ||
if (isValidTapCount_1) { | ||
if (this.options.taps === this.tapCount) { | ||
this.status = STATUS_START; | ||
if (this.hasRequireFailure()) { | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (_this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
else { | ||
_this.status = STATUS_FAILED; | ||
} | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
else { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, __assign({}, computed, { tapCount: this.tapCount })); | ||
this.tapCount = 0; | ||
this.reset(); | ||
} | ||
this.tapTimeoutId = setTimeout(function () { | ||
_this.status = STATUS_FAILED; | ||
_this.tapCount = 0; | ||
} | ||
else { | ||
this.tapTimeout2Id = setTimeout(function () { | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
} | ||
else { | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
} | ||
}; | ||
TapRecognizer.prototype.cancel = function () { | ||
clearTimeout$1(this.tapTimeoutId); | ||
TapRecognizer.prototype.reset = function () { | ||
this.tapCount = 0; | ||
this.prevTapX = undefined; | ||
this.prevTapY = undefined; | ||
}; | ||
TapRecognizer.prototype.test = function (computed) { | ||
var abs = Math.abs, max = Math.max; | ||
var inputStatus = computed.inputStatus, distance = computed.distance, duration = computed.duration, maxPointerLength = computed.maxPointerLength, centerX = computed.centerX, centerY = computed.centerY; | ||
this._prevX = centerX; | ||
this._prevY = centerY; | ||
var offsetX = abs(centerX - this._prevX); | ||
var offsetY = abs(centerY - this._prevY); | ||
var hasMove = 2 < max(offsetX, offsetY); | ||
return INPUT_END === inputStatus && 1 === maxPointerLength && 2 > distance && 250 > duration && !hasMove; | ||
var distance = computed.distance, deltaTime = computed.deltaTime, maxPointerLength = computed.maxPointerLength; | ||
var isValidMovementTap = 2 >= distance; | ||
var isValidDeltaTime = 250 > deltaTime; | ||
return maxPointerLength === this.options.pointer && | ||
isValidDeltaTime && isValidMovementTap; | ||
}; | ||
TapRecognizer.prototype.afterEmit = function (computed) { }; | ||
TapRecognizer.DEFAULT_OPTIONS = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
return TapRecognizer; | ||
}(Recognizer)); | ||
TapRecognizer.prototype.default = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
@@ -871,5 +869,3 @@ var PressRecognizer = (function (_super) { | ||
if (options === void 0) { options = {}; } | ||
var _this = _super.call(this, options) || this; | ||
_this._timeoutId = null; | ||
return _this; | ||
return _super.call(this, options) || this; | ||
} | ||
@@ -919,11 +915,11 @@ PressRecognizer.prototype.getTouchAction = function () { | ||
PressRecognizer.prototype.afterEmit = function () { }; | ||
PressRecognizer.DEFAULT_OPTIONS = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
return PressRecognizer; | ||
}(Recognizer)); | ||
PressRecognizer.prototype.default = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
@@ -990,3 +986,5 @@ var getHV = (function (directions) { | ||
PanRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1019,10 +1017,10 @@ PanRecognizer.prototype.afterRecognized = function (computed) { | ||
}; | ||
PanRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return PanRecognizer; | ||
}(Recognizer)); | ||
PanRecognizer.prototype.default = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1039,3 +1037,5 @@ var SwipeRecognizer = (function (_super) { | ||
SwipeRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1059,11 +1059,11 @@ SwipeRecognizer.prototype.test = function (computed) { | ||
}; | ||
SwipeRecognizer.DEFAULT_OPTIONS = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return SwipeRecognizer; | ||
}(Recognizer)); | ||
SwipeRecognizer.prototype.default = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1093,9 +1093,9 @@ var PinchRecognizer = (function (_super) { | ||
}; | ||
PinchRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return PinchRecognizer; | ||
}(Recognizer)); | ||
PinchRecognizer.prototype.default = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
@@ -1116,33 +1116,31 @@ var RotateRecognizer = (function (_super) { | ||
}; | ||
RotateRecognizer.DEFAULT_OPTIONS = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return RotateRecognizer; | ||
}(Recognizer)); | ||
RotateRecognizer.prototype.default = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
var pkg = require('../package.json'); | ||
var AnyTouch = (function () { | ||
function AnyTouch(el, options) { | ||
var _this = this; | ||
this.version = '0.0.25'; | ||
this.version = pkg.version; | ||
this.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
this.el = el; | ||
this.isMobile = IS_MOBILE; | ||
this.inputType = SUPPORT_TOUCH ? 'touch' : 'mouse'; | ||
this.options = __assign({}, this.default, options); | ||
this.eventBus = new EventEmitter(); | ||
this.recognizers = [ | ||
new TapRecognizer(), | ||
new PressRecognizer(), | ||
new PanRecognizer(), | ||
new SwipeRecognizer(), | ||
new PinchRecognizer(), | ||
new RotateRecognizer(), | ||
new TapRecognizer().$injectRoot(this), | ||
new PressRecognizer().$injectRoot(this), | ||
new PanRecognizer().$injectRoot(this), | ||
new SwipeRecognizer().$injectRoot(this), | ||
new PinchRecognizer().$injectRoot(this), | ||
new RotateRecognizer().$injectRoot(this), | ||
]; | ||
this.recognizers.forEach(function (recognizer) { | ||
recognizer.eventBus = _this.eventBus; | ||
recognizer.el = el; | ||
recognizer.$root = _this; | ||
recognizer.hasDomEvents = _this.options.hasDomEvents; | ||
}); | ||
this.update(); | ||
this.unbinders = this._bindRecognizers(this.el); | ||
@@ -1170,3 +1168,3 @@ } | ||
else { | ||
el.style.touchAction = this.options.touchAction; | ||
el.style.touchAction = this.options.touchAction || 'auto'; | ||
} | ||
@@ -1179,3 +1177,3 @@ }; | ||
var boundFn = this.handler.bind(this); | ||
if (this.isMobile) { | ||
if ('touch' === this.inputType) { | ||
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].map(function (eventName) { | ||
@@ -1206,6 +1204,3 @@ el.addEventListener(eventName, boundFn, { passive: false }); | ||
AnyTouch.prototype.add = function (recognizer) { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = this.el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
recognizer.$injectRoot(this); | ||
this.recognizers.push(recognizer); | ||
@@ -1288,8 +1283,3 @@ this.update(); | ||
}()); | ||
AnyTouch.prototype.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
module.exports = AnyTouch; |
@@ -268,3 +268,3 @@ /*! ***************************************************************************** | ||
if (x === y) { | ||
return undefined; | ||
return 'none'; | ||
} | ||
@@ -309,7 +309,7 @@ else if (Math.abs(x) > Math.abs(y)) { | ||
var prevPointers = undefined; | ||
var prevPointers; | ||
var isPressed = false; | ||
var mouseAdapter = (function (event) { | ||
var clientX = event.clientX, clientY = event.clientY, type = event.type; | ||
var changedPointers = prevPointers; | ||
var changedPointers = prevPointers || [{ clientX: clientX, clientY: clientY }]; | ||
var pointers = [{ clientX: clientX, clientY: clientY }]; | ||
@@ -350,3 +350,3 @@ prevPointers = [{ clientX: clientX, clientY: clientY }]; | ||
var input = {}; | ||
if (IS_MOBILE) { | ||
if (SUPPORT_TOUCH) { | ||
input = touchAdapter(event); | ||
@@ -537,27 +537,3 @@ } | ||
var abs = Math.abs, max = Math.max; | ||
var computed = { | ||
pointerLength: input.pointerLength, | ||
changedPointerLength: input.changedPointerLength, | ||
displacementX: 0, | ||
displacementY: 0, | ||
distanceX: 0, | ||
distanceY: 0, | ||
distance: 0, | ||
direction: undefined, | ||
lastDirection: undefined, | ||
deltaX: undefined, | ||
deltaY: undefined, | ||
velocityX: 0, | ||
velocityY: 0, | ||
maxVelocity: 0, | ||
duration: 0, | ||
timestamp: Date.now(), | ||
angle: 0, | ||
deltaAngle: 0, | ||
scale: undefined, | ||
deltaScale: 1, | ||
lastVelocity: undefined, | ||
lastVelocityY: undefined, | ||
lastVelocityX: undefined, | ||
}; | ||
var computed = {}; | ||
var _b = computeDistance({ | ||
@@ -569,3 +545,3 @@ startInput: startInput, | ||
computed.direction = getDirection(displacementX, displacementY); | ||
computed.duration = input.timestamp - startInput.timestamp; | ||
computed.deltaTime = input.timestamp - startInput.timestamp; | ||
var lastComputed = computeLast(input); | ||
@@ -586,4 +562,4 @@ computed.lastVelocityX = lastComputed.velocityX; | ||
} | ||
computed.velocityX = abs(computed.distanceX / computed.duration) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.duration) || 0; | ||
computed.velocityX = abs(computed.distanceX / computed.deltaTime) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.deltaTime) || 0; | ||
computed.maxVelocity = max(computed.velocityX, computed.velocityY); | ||
@@ -604,3 +580,4 @@ if (undefined !== prevInput && 1 < prevInput.pointers.length && 1 < input.pointers.length) { | ||
var maxPointerLength = computeMaxLength(input); | ||
return __assign({}, input, { maxPointerLength: maxPointerLength }, computed); | ||
computed = __assign({}, computed, input, { maxPointerLength: maxPointerLength }); | ||
return computed; | ||
} | ||
@@ -658,4 +635,3 @@ | ||
function Recognizer(options) { | ||
if (options === void 0) { options = { disabled: false }; } | ||
this.options = __assign({}, this.default, options); | ||
this.options = __assign({}, this.constructor.DEFAULT_OPTIONS, { disabled: false }, options); | ||
this.name = this.options.name; | ||
@@ -668,21 +644,20 @@ this.disabled = this.options.disabled; | ||
Recognizer.prototype.set = function (options) { | ||
if (options === void 0) { options = {}; } | ||
this.options = __assign({}, this.options, options); | ||
this.$root.update(); | ||
}; | ||
Recognizer.prototype.$injectRoot = function ($root) { | ||
this.$root = $root; | ||
return this; | ||
}; | ||
Recognizer.prototype.emit = function (type, payload) { | ||
payload.type = type; | ||
this.eventBus.emit(type, payload); | ||
if (this.hasDomEvents) { | ||
this.$root.eventBus.emit(type, payload); | ||
if (this.$root.options.hasDomEvents) { | ||
var target = payload.target, currentTarget = payload.currentTarget, type_1 = payload.type, data = __rest(payload, ["target", "currentTarget", "type"]); | ||
var event = new Event(type_1, payload); | ||
Object.assign(event, data); | ||
this.el.dispatchEvent(event); | ||
this.$root.el.dispatchEvent(event); | ||
} | ||
}; | ||
Recognizer.prototype.on = function (type, listener) { | ||
this.eventBus.on(type, listener); | ||
}; | ||
Recognizer.prototype.off = function (type, listener) { | ||
this.eventBus.off(type, listener); | ||
}; | ||
Recognizer.prototype.requireFailure = function (recognizer) { | ||
@@ -752,3 +727,3 @@ if (!this.requireFailureRecognizers.includes(recognizer)) { | ||
Recognizer.prototype.isVaildDirection = function (direction) { | ||
return -1 < this.options.directions.indexOf(direction); | ||
return -1 !== this.options.directions.indexOf(direction) || 'none' === direction; | ||
}; | ||
@@ -758,3 +733,3 @@ Recognizer.prototype.recognize = function (computed) { | ||
var isVaild = this.test(computed); | ||
if (-1 < [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
if (-1 !== [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
@@ -803,3 +778,2 @@ } | ||
var _this = _super.call(this, options) || this; | ||
_this.tapTimeoutId = null; | ||
_this.tapCount = 0; | ||
@@ -813,52 +787,76 @@ return _this; | ||
var _this = this; | ||
this.status = STATUS_POSSIBLE; | ||
if (this.test(computed)) { | ||
this.tapCount++; | ||
var isValidTapCount_1 = this.options.taps === this.tapCount; | ||
if (this.hasRequireFailure()) { | ||
this.cancel(); | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (isValidTapCount_1 && _this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
_this.tapCount = 0; | ||
}, this.options.interval); | ||
if (INPUT_END !== computed.inputStatus) | ||
return; | ||
if (-1 < [STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
} | ||
var isValidEachTap = this.test(computed); | ||
var max = Math.max, pow = Math.pow, sqrt = Math.sqrt; | ||
var x = computed.x, y = computed.y; | ||
if (undefined === this.prevTapX || undefined === this.prevTapY) { | ||
this.isValidMovementFromPrevTap = true; | ||
} | ||
else { | ||
this.isValidMovementFromPrevTap = 10 > sqrt(max(pow(x - this.prevTapX, 2), pow(y - this.prevTapY, 2))); | ||
} | ||
this.prevTapX = x; | ||
this.prevTapY = y; | ||
if (isValidEachTap) { | ||
clearTimeout$1(this.tapTimeout2Id); | ||
if (this.isValidMovementFromPrevTap) { | ||
this.tapCount++; | ||
} | ||
else { | ||
this.cancel(); | ||
if (isValidTapCount_1) { | ||
if (this.options.taps === this.tapCount) { | ||
this.status = STATUS_START; | ||
if (this.hasRequireFailure()) { | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (_this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
else { | ||
_this.status = STATUS_FAILED; | ||
} | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
else { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, __assign({}, computed, { tapCount: this.tapCount })); | ||
this.tapCount = 0; | ||
this.reset(); | ||
} | ||
this.tapTimeoutId = setTimeout(function () { | ||
_this.status = STATUS_FAILED; | ||
_this.tapCount = 0; | ||
} | ||
else { | ||
this.tapTimeout2Id = setTimeout(function () { | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
} | ||
else { | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
} | ||
}; | ||
TapRecognizer.prototype.cancel = function () { | ||
clearTimeout$1(this.tapTimeoutId); | ||
TapRecognizer.prototype.reset = function () { | ||
this.tapCount = 0; | ||
this.prevTapX = undefined; | ||
this.prevTapY = undefined; | ||
}; | ||
TapRecognizer.prototype.test = function (computed) { | ||
var abs = Math.abs, max = Math.max; | ||
var inputStatus = computed.inputStatus, distance = computed.distance, duration = computed.duration, maxPointerLength = computed.maxPointerLength, centerX = computed.centerX, centerY = computed.centerY; | ||
this._prevX = centerX; | ||
this._prevY = centerY; | ||
var offsetX = abs(centerX - this._prevX); | ||
var offsetY = abs(centerY - this._prevY); | ||
var hasMove = 2 < max(offsetX, offsetY); | ||
return INPUT_END === inputStatus && 1 === maxPointerLength && 2 > distance && 250 > duration && !hasMove; | ||
var distance = computed.distance, deltaTime = computed.deltaTime, maxPointerLength = computed.maxPointerLength; | ||
var isValidMovementTap = 2 >= distance; | ||
var isValidDeltaTime = 250 > deltaTime; | ||
return maxPointerLength === this.options.pointer && | ||
isValidDeltaTime && isValidMovementTap; | ||
}; | ||
TapRecognizer.prototype.afterEmit = function (computed) { }; | ||
TapRecognizer.DEFAULT_OPTIONS = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
return TapRecognizer; | ||
}(Recognizer)); | ||
TapRecognizer.prototype.default = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
@@ -869,5 +867,3 @@ var PressRecognizer = (function (_super) { | ||
if (options === void 0) { options = {}; } | ||
var _this = _super.call(this, options) || this; | ||
_this._timeoutId = null; | ||
return _this; | ||
return _super.call(this, options) || this; | ||
} | ||
@@ -917,11 +913,11 @@ PressRecognizer.prototype.getTouchAction = function () { | ||
PressRecognizer.prototype.afterEmit = function () { }; | ||
PressRecognizer.DEFAULT_OPTIONS = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
return PressRecognizer; | ||
}(Recognizer)); | ||
PressRecognizer.prototype.default = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
@@ -988,3 +984,5 @@ var getHV = (function (directions) { | ||
PanRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1017,10 +1015,10 @@ PanRecognizer.prototype.afterRecognized = function (computed) { | ||
}; | ||
PanRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return PanRecognizer; | ||
}(Recognizer)); | ||
PanRecognizer.prototype.default = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1037,3 +1035,5 @@ var SwipeRecognizer = (function (_super) { | ||
SwipeRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1057,11 +1057,11 @@ SwipeRecognizer.prototype.test = function (computed) { | ||
}; | ||
SwipeRecognizer.DEFAULT_OPTIONS = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return SwipeRecognizer; | ||
}(Recognizer)); | ||
SwipeRecognizer.prototype.default = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1091,9 +1091,9 @@ var PinchRecognizer = (function (_super) { | ||
}; | ||
PinchRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return PinchRecognizer; | ||
}(Recognizer)); | ||
PinchRecognizer.prototype.default = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
@@ -1114,33 +1114,31 @@ var RotateRecognizer = (function (_super) { | ||
}; | ||
RotateRecognizer.DEFAULT_OPTIONS = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return RotateRecognizer; | ||
}(Recognizer)); | ||
RotateRecognizer.prototype.default = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
var pkg = require('../package.json'); | ||
var AnyTouch = (function () { | ||
function AnyTouch(el, options) { | ||
var _this = this; | ||
this.version = '0.0.25'; | ||
this.version = pkg.version; | ||
this.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
this.el = el; | ||
this.isMobile = IS_MOBILE; | ||
this.inputType = SUPPORT_TOUCH ? 'touch' : 'mouse'; | ||
this.options = __assign({}, this.default, options); | ||
this.eventBus = new EventEmitter(); | ||
this.recognizers = [ | ||
new TapRecognizer(), | ||
new PressRecognizer(), | ||
new PanRecognizer(), | ||
new SwipeRecognizer(), | ||
new PinchRecognizer(), | ||
new RotateRecognizer(), | ||
new TapRecognizer().$injectRoot(this), | ||
new PressRecognizer().$injectRoot(this), | ||
new PanRecognizer().$injectRoot(this), | ||
new SwipeRecognizer().$injectRoot(this), | ||
new PinchRecognizer().$injectRoot(this), | ||
new RotateRecognizer().$injectRoot(this), | ||
]; | ||
this.recognizers.forEach(function (recognizer) { | ||
recognizer.eventBus = _this.eventBus; | ||
recognizer.el = el; | ||
recognizer.$root = _this; | ||
recognizer.hasDomEvents = _this.options.hasDomEvents; | ||
}); | ||
this.update(); | ||
this.unbinders = this._bindRecognizers(this.el); | ||
@@ -1168,3 +1166,3 @@ } | ||
else { | ||
el.style.touchAction = this.options.touchAction; | ||
el.style.touchAction = this.options.touchAction || 'auto'; | ||
} | ||
@@ -1177,3 +1175,3 @@ }; | ||
var boundFn = this.handler.bind(this); | ||
if (this.isMobile) { | ||
if ('touch' === this.inputType) { | ||
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].map(function (eventName) { | ||
@@ -1204,6 +1202,3 @@ el.addEventListener(eventName, boundFn, { passive: false }); | ||
AnyTouch.prototype.add = function (recognizer) { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = this.el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
recognizer.$injectRoot(this); | ||
this.recognizers.push(recognizer); | ||
@@ -1286,8 +1281,3 @@ this.update(); | ||
}()); | ||
AnyTouch.prototype.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
export default AnyTouch; |
@@ -274,3 +274,3 @@ (function (global, factory) { | ||
if (x === y) { | ||
return undefined; | ||
return 'none'; | ||
} | ||
@@ -315,7 +315,7 @@ else if (Math.abs(x) > Math.abs(y)) { | ||
var prevPointers = undefined; | ||
var prevPointers; | ||
var isPressed = false; | ||
var mouseAdapter = (function (event) { | ||
var clientX = event.clientX, clientY = event.clientY, type = event.type; | ||
var changedPointers = prevPointers; | ||
var changedPointers = prevPointers || [{ clientX: clientX, clientY: clientY }]; | ||
var pointers = [{ clientX: clientX, clientY: clientY }]; | ||
@@ -356,3 +356,3 @@ prevPointers = [{ clientX: clientX, clientY: clientY }]; | ||
var input = {}; | ||
if (IS_MOBILE) { | ||
if (SUPPORT_TOUCH) { | ||
input = touchAdapter(event); | ||
@@ -543,27 +543,3 @@ } | ||
var abs = Math.abs, max = Math.max; | ||
var computed = { | ||
pointerLength: input.pointerLength, | ||
changedPointerLength: input.changedPointerLength, | ||
displacementX: 0, | ||
displacementY: 0, | ||
distanceX: 0, | ||
distanceY: 0, | ||
distance: 0, | ||
direction: undefined, | ||
lastDirection: undefined, | ||
deltaX: undefined, | ||
deltaY: undefined, | ||
velocityX: 0, | ||
velocityY: 0, | ||
maxVelocity: 0, | ||
duration: 0, | ||
timestamp: Date.now(), | ||
angle: 0, | ||
deltaAngle: 0, | ||
scale: undefined, | ||
deltaScale: 1, | ||
lastVelocity: undefined, | ||
lastVelocityY: undefined, | ||
lastVelocityX: undefined, | ||
}; | ||
var computed = {}; | ||
var _b = computeDistance({ | ||
@@ -575,3 +551,3 @@ startInput: startInput, | ||
computed.direction = getDirection(displacementX, displacementY); | ||
computed.duration = input.timestamp - startInput.timestamp; | ||
computed.deltaTime = input.timestamp - startInput.timestamp; | ||
var lastComputed = computeLast(input); | ||
@@ -592,4 +568,4 @@ computed.lastVelocityX = lastComputed.velocityX; | ||
} | ||
computed.velocityX = abs(computed.distanceX / computed.duration) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.duration) || 0; | ||
computed.velocityX = abs(computed.distanceX / computed.deltaTime) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.deltaTime) || 0; | ||
computed.maxVelocity = max(computed.velocityX, computed.velocityY); | ||
@@ -610,3 +586,4 @@ if (undefined !== prevInput && 1 < prevInput.pointers.length && 1 < input.pointers.length) { | ||
var maxPointerLength = computeMaxLength(input); | ||
return __assign({}, input, { maxPointerLength: maxPointerLength }, computed); | ||
computed = __assign({}, computed, input, { maxPointerLength: maxPointerLength }); | ||
return computed; | ||
} | ||
@@ -664,4 +641,3 @@ | ||
function Recognizer(options) { | ||
if (options === void 0) { options = { disabled: false }; } | ||
this.options = __assign({}, this.default, options); | ||
this.options = __assign({}, this.constructor.DEFAULT_OPTIONS, { disabled: false }, options); | ||
this.name = this.options.name; | ||
@@ -674,21 +650,20 @@ this.disabled = this.options.disabled; | ||
Recognizer.prototype.set = function (options) { | ||
if (options === void 0) { options = {}; } | ||
this.options = __assign({}, this.options, options); | ||
this.$root.update(); | ||
}; | ||
Recognizer.prototype.$injectRoot = function ($root) { | ||
this.$root = $root; | ||
return this; | ||
}; | ||
Recognizer.prototype.emit = function (type, payload) { | ||
payload.type = type; | ||
this.eventBus.emit(type, payload); | ||
if (this.hasDomEvents) { | ||
this.$root.eventBus.emit(type, payload); | ||
if (this.$root.options.hasDomEvents) { | ||
var target = payload.target, currentTarget = payload.currentTarget, type_1 = payload.type, data = __rest(payload, ["target", "currentTarget", "type"]); | ||
var event = new Event(type_1, payload); | ||
Object.assign(event, data); | ||
this.el.dispatchEvent(event); | ||
this.$root.el.dispatchEvent(event); | ||
} | ||
}; | ||
Recognizer.prototype.on = function (type, listener) { | ||
this.eventBus.on(type, listener); | ||
}; | ||
Recognizer.prototype.off = function (type, listener) { | ||
this.eventBus.off(type, listener); | ||
}; | ||
Recognizer.prototype.requireFailure = function (recognizer) { | ||
@@ -758,3 +733,3 @@ if (!this.requireFailureRecognizers.includes(recognizer)) { | ||
Recognizer.prototype.isVaildDirection = function (direction) { | ||
return -1 < this.options.directions.indexOf(direction); | ||
return -1 !== this.options.directions.indexOf(direction) || 'none' === direction; | ||
}; | ||
@@ -764,3 +739,3 @@ Recognizer.prototype.recognize = function (computed) { | ||
var isVaild = this.test(computed); | ||
if (-1 < [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
if (-1 !== [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
@@ -809,3 +784,2 @@ } | ||
var _this = _super.call(this, options) || this; | ||
_this.tapTimeoutId = null; | ||
_this.tapCount = 0; | ||
@@ -819,52 +793,76 @@ return _this; | ||
var _this = this; | ||
this.status = STATUS_POSSIBLE; | ||
if (this.test(computed)) { | ||
this.tapCount++; | ||
var isValidTapCount_1 = this.options.taps === this.tapCount; | ||
if (this.hasRequireFailure()) { | ||
this.cancel(); | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (isValidTapCount_1 && _this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
_this.tapCount = 0; | ||
}, this.options.interval); | ||
if (INPUT_END !== computed.inputStatus) | ||
return; | ||
if (-1 < [STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
} | ||
var isValidEachTap = this.test(computed); | ||
var max = Math.max, pow = Math.pow, sqrt = Math.sqrt; | ||
var x = computed.x, y = computed.y; | ||
if (undefined === this.prevTapX || undefined === this.prevTapY) { | ||
this.isValidMovementFromPrevTap = true; | ||
} | ||
else { | ||
this.isValidMovementFromPrevTap = 10 > sqrt(max(pow(x - this.prevTapX, 2), pow(y - this.prevTapY, 2))); | ||
} | ||
this.prevTapX = x; | ||
this.prevTapY = y; | ||
if (isValidEachTap) { | ||
clearTimeout$1(this.tapTimeout2Id); | ||
if (this.isValidMovementFromPrevTap) { | ||
this.tapCount++; | ||
} | ||
else { | ||
this.cancel(); | ||
if (isValidTapCount_1) { | ||
if (this.options.taps === this.tapCount) { | ||
this.status = STATUS_START; | ||
if (this.hasRequireFailure()) { | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (_this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
else { | ||
_this.status = STATUS_FAILED; | ||
} | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
else { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, __assign({}, computed, { tapCount: this.tapCount })); | ||
this.tapCount = 0; | ||
this.reset(); | ||
} | ||
this.tapTimeoutId = setTimeout(function () { | ||
_this.status = STATUS_FAILED; | ||
_this.tapCount = 0; | ||
} | ||
else { | ||
this.tapTimeout2Id = setTimeout(function () { | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
} | ||
else { | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
} | ||
}; | ||
TapRecognizer.prototype.cancel = function () { | ||
clearTimeout$1(this.tapTimeoutId); | ||
TapRecognizer.prototype.reset = function () { | ||
this.tapCount = 0; | ||
this.prevTapX = undefined; | ||
this.prevTapY = undefined; | ||
}; | ||
TapRecognizer.prototype.test = function (computed) { | ||
var abs = Math.abs, max = Math.max; | ||
var inputStatus = computed.inputStatus, distance = computed.distance, duration = computed.duration, maxPointerLength = computed.maxPointerLength, centerX = computed.centerX, centerY = computed.centerY; | ||
this._prevX = centerX; | ||
this._prevY = centerY; | ||
var offsetX = abs(centerX - this._prevX); | ||
var offsetY = abs(centerY - this._prevY); | ||
var hasMove = 2 < max(offsetX, offsetY); | ||
return INPUT_END === inputStatus && 1 === maxPointerLength && 2 > distance && 250 > duration && !hasMove; | ||
var distance = computed.distance, deltaTime = computed.deltaTime, maxPointerLength = computed.maxPointerLength; | ||
var isValidMovementTap = 2 >= distance; | ||
var isValidDeltaTime = 250 > deltaTime; | ||
return maxPointerLength === this.options.pointer && | ||
isValidDeltaTime && isValidMovementTap; | ||
}; | ||
TapRecognizer.prototype.afterEmit = function (computed) { }; | ||
TapRecognizer.DEFAULT_OPTIONS = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
return TapRecognizer; | ||
}(Recognizer)); | ||
TapRecognizer.prototype.default = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
@@ -875,5 +873,3 @@ var PressRecognizer = (function (_super) { | ||
if (options === void 0) { options = {}; } | ||
var _this = _super.call(this, options) || this; | ||
_this._timeoutId = null; | ||
return _this; | ||
return _super.call(this, options) || this; | ||
} | ||
@@ -923,11 +919,11 @@ PressRecognizer.prototype.getTouchAction = function () { | ||
PressRecognizer.prototype.afterEmit = function () { }; | ||
PressRecognizer.DEFAULT_OPTIONS = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
return PressRecognizer; | ||
}(Recognizer)); | ||
PressRecognizer.prototype.default = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
@@ -994,3 +990,5 @@ var getHV = (function (directions) { | ||
PanRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1023,10 +1021,10 @@ PanRecognizer.prototype.afterRecognized = function (computed) { | ||
}; | ||
PanRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return PanRecognizer; | ||
}(Recognizer)); | ||
PanRecognizer.prototype.default = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1043,3 +1041,5 @@ var SwipeRecognizer = (function (_super) { | ||
SwipeRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -1063,11 +1063,11 @@ SwipeRecognizer.prototype.test = function (computed) { | ||
}; | ||
SwipeRecognizer.DEFAULT_OPTIONS = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return SwipeRecognizer; | ||
}(Recognizer)); | ||
SwipeRecognizer.prototype.default = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
@@ -1097,9 +1097,9 @@ var PinchRecognizer = (function (_super) { | ||
}; | ||
PinchRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return PinchRecognizer; | ||
}(Recognizer)); | ||
PinchRecognizer.prototype.default = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
@@ -1120,33 +1120,31 @@ var RotateRecognizer = (function (_super) { | ||
}; | ||
RotateRecognizer.DEFAULT_OPTIONS = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return RotateRecognizer; | ||
}(Recognizer)); | ||
RotateRecognizer.prototype.default = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
var pkg = require('../package.json'); | ||
var AnyTouch = (function () { | ||
function AnyTouch(el, options) { | ||
var _this = this; | ||
this.version = '0.0.25'; | ||
this.version = pkg.version; | ||
this.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
this.el = el; | ||
this.isMobile = IS_MOBILE; | ||
this.inputType = SUPPORT_TOUCH ? 'touch' : 'mouse'; | ||
this.options = __assign({}, this.default, options); | ||
this.eventBus = new EventEmitter(); | ||
this.recognizers = [ | ||
new TapRecognizer(), | ||
new PressRecognizer(), | ||
new PanRecognizer(), | ||
new SwipeRecognizer(), | ||
new PinchRecognizer(), | ||
new RotateRecognizer(), | ||
new TapRecognizer().$injectRoot(this), | ||
new PressRecognizer().$injectRoot(this), | ||
new PanRecognizer().$injectRoot(this), | ||
new SwipeRecognizer().$injectRoot(this), | ||
new PinchRecognizer().$injectRoot(this), | ||
new RotateRecognizer().$injectRoot(this), | ||
]; | ||
this.recognizers.forEach(function (recognizer) { | ||
recognizer.eventBus = _this.eventBus; | ||
recognizer.el = el; | ||
recognizer.$root = _this; | ||
recognizer.hasDomEvents = _this.options.hasDomEvents; | ||
}); | ||
this.update(); | ||
this.unbinders = this._bindRecognizers(this.el); | ||
@@ -1174,3 +1172,3 @@ } | ||
else { | ||
el.style.touchAction = this.options.touchAction; | ||
el.style.touchAction = this.options.touchAction || 'auto'; | ||
} | ||
@@ -1183,3 +1181,3 @@ }; | ||
var boundFn = this.handler.bind(this); | ||
if (this.isMobile) { | ||
if ('touch' === this.inputType) { | ||
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].map(function (eventName) { | ||
@@ -1210,6 +1208,3 @@ el.addEventListener(eventName, boundFn, { passive: false }); | ||
AnyTouch.prototype.add = function (recognizer) { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = this.el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
recognizer.$injectRoot(this); | ||
this.recognizers.push(recognizer); | ||
@@ -1292,7 +1287,2 @@ this.update(); | ||
}()); | ||
AnyTouch.prototype.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
@@ -1299,0 +1289,0 @@ return AnyTouch; |
@@ -6,4 +6,4 @@ import { Input } from '../interface'; | ||
velocityY: number; | ||
direction: string; | ||
direction?: string | undefined; | ||
}; | ||
export default _default; |
import { Computed } from '../interface'; | ||
export default function ({ startInput, prevInput, startMutliInput, input }: any): Computed; | ||
export default function ({ startInput, prevInput, startMutliInput, input }: any): Computed | void; |
@@ -25,27 +25,3 @@ var __assign = (this && this.__assign) || function () { | ||
var abs = Math.abs, max = Math.max; | ||
var computed = { | ||
pointerLength: input.pointerLength, | ||
changedPointerLength: input.changedPointerLength, | ||
displacementX: 0, | ||
displacementY: 0, | ||
distanceX: 0, | ||
distanceY: 0, | ||
distance: 0, | ||
direction: undefined, | ||
lastDirection: undefined, | ||
deltaX: undefined, | ||
deltaY: undefined, | ||
velocityX: 0, | ||
velocityY: 0, | ||
maxVelocity: 0, | ||
duration: 0, | ||
timestamp: Date.now(), | ||
angle: 0, | ||
deltaAngle: 0, | ||
scale: undefined, | ||
deltaScale: 1, | ||
lastVelocity: undefined, | ||
lastVelocityY: undefined, | ||
lastVelocityX: undefined, | ||
}; | ||
var computed = {}; | ||
var _b = computeDistance({ | ||
@@ -57,3 +33,3 @@ startInput: startInput, | ||
computed.direction = getDirection(displacementX, displacementY); | ||
computed.duration = input.timestamp - startInput.timestamp; | ||
computed.deltaTime = input.timestamp - startInput.timestamp; | ||
var lastComputed = computeLast(input); | ||
@@ -74,4 +50,4 @@ computed.lastVelocityX = lastComputed.velocityX; | ||
} | ||
computed.velocityX = abs(computed.distanceX / computed.duration) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.duration) || 0; | ||
computed.velocityX = abs(computed.distanceX / computed.deltaTime) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.deltaTime) || 0; | ||
computed.maxVelocity = max(computed.velocityX, computed.velocityY); | ||
@@ -92,5 +68,6 @@ if (undefined !== prevInput && 1 < prevInput.pointers.length && 1 < input.pointers.length) { | ||
var maxPointerLength = computeMaxLength(input); | ||
return __assign({}, input, { maxPointerLength: maxPointerLength }, computed); | ||
computed = __assign({}, computed, input, { maxPointerLength: maxPointerLength }); | ||
return computed; | ||
} | ||
; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,13 @@ | ||
declare const _default: (event: MouseEvent) => any; | ||
declare const _default: (event: MouseEvent) => void | { | ||
inputStatus: string; | ||
changedPointers: { | ||
clientX: number; | ||
clientY: number; | ||
}[]; | ||
pointers: { | ||
clientX: number; | ||
clientY: number; | ||
}[]; | ||
nativeEvent: Event; | ||
}; | ||
export default _default; |
@@ -1,6 +0,6 @@ | ||
var prevPointers = undefined; | ||
var prevPointers; | ||
var isPressed = false; | ||
export default (function (event) { | ||
var clientX = event.clientX, clientY = event.clientY, type = event.type; | ||
var changedPointers = prevPointers; | ||
var changedPointers = prevPointers || [{ clientX: clientX, clientY: clientY }]; | ||
var pointers = [{ clientX: clientX, clientY: clientY }]; | ||
@@ -7,0 +7,0 @@ prevPointers = [{ clientX: clientX, clientY: clientY }]; |
import { Input } from '../interface'; | ||
declare const _default: (event: MouseEvent | TouchEvent) => Input; | ||
declare const _default: (event: Event) => Input | undefined; | ||
export default _default; |
@@ -12,3 +12,3 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
import { IS_MOBILE, INPUT_END, INPUT_START } from '../const'; | ||
import { SUPPORT_TOUCH, INPUT_END, INPUT_START } from '../const'; | ||
import { getCenter } from '../vector'; | ||
@@ -21,3 +21,3 @@ import touchAdapter from './adapters/touch'; | ||
var input = {}; | ||
if (IS_MOBILE) { | ||
if (SUPPORT_TOUCH) { | ||
input = touchAdapter(event); | ||
@@ -24,0 +24,0 @@ } |
@@ -1,2 +0,2 @@ | ||
declare const _default: (event: MouseEvent | TouchEvent) => any; | ||
declare const _default: (event: Event) => any; | ||
export default _default; |
@@ -1,2 +0,2 @@ | ||
import { EventHandler } from './interface'; | ||
import { Computed } from './interface'; | ||
import TapRecognizer from './recognitions/Tap'; | ||
@@ -24,2 +24,3 @@ import PressRecognizer from './recognitions/Press'; | ||
default: Options; | ||
inputType: string; | ||
recognizers: { | ||
@@ -31,3 +32,2 @@ [propName: string]: any; | ||
version: string; | ||
isMobile: boolean; | ||
options: Options; | ||
@@ -43,7 +43,7 @@ eventBus: any; | ||
remove(recognizerName: string): void; | ||
handler(event: TouchEvent | MouseEvent): void; | ||
on(type: string, listener: EventHandler): void; | ||
off(type: string, listener?: EventHandler): void; | ||
handler(event: Event): void; | ||
on(type: string, listener: (event: Computed) => void): void; | ||
off(type: string, listener?: (event: Computed) => void): void; | ||
destroy(): void; | ||
} | ||
export {}; |
@@ -43,3 +43,3 @@ var __assign = (this && this.__assign) || function () { | ||
import AnyEvent from 'any-event'; | ||
import { IS_MOBILE, } from './const'; | ||
import { SUPPORT_TOUCH, } from './const'; | ||
import inputManage from './inputManage'; | ||
@@ -55,26 +55,24 @@ import compute from './compute/index'; | ||
import * as Vector from './vector'; | ||
var pkg = require('../package.json'); | ||
; | ||
var AnyTouch = (function () { | ||
function AnyTouch(el, options) { | ||
var _this = this; | ||
this.version = '0.0.25'; | ||
this.version = pkg.version; | ||
this.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
this.el = el; | ||
this.isMobile = IS_MOBILE; | ||
this.inputType = SUPPORT_TOUCH ? 'touch' : 'mouse'; | ||
this.options = __assign({}, this.default, options); | ||
this.eventBus = new AnyEvent(); | ||
this.recognizers = [ | ||
new TapRecognizer(), | ||
new PressRecognizer(), | ||
new PanRecognizer(), | ||
new SwipeRecognizer(), | ||
new PinchRecognizer(), | ||
new RotateRecognizer(), | ||
new TapRecognizer().$injectRoot(this), | ||
new PressRecognizer().$injectRoot(this), | ||
new PanRecognizer().$injectRoot(this), | ||
new SwipeRecognizer().$injectRoot(this), | ||
new PinchRecognizer().$injectRoot(this), | ||
new RotateRecognizer().$injectRoot(this), | ||
]; | ||
this.recognizers.forEach(function (recognizer) { | ||
recognizer.eventBus = _this.eventBus; | ||
recognizer.el = el; | ||
recognizer.$root = _this; | ||
recognizer.hasDomEvents = _this.options.hasDomEvents; | ||
}); | ||
this.update(); | ||
this.unbinders = this._bindRecognizers(this.el); | ||
@@ -104,3 +102,3 @@ } | ||
else { | ||
el.style.touchAction = this.options.touchAction; | ||
el.style.touchAction = this.options.touchAction || 'auto'; | ||
} | ||
@@ -115,3 +113,3 @@ }; | ||
var boundFn = this.handler.bind(this); | ||
if (this.isMobile) { | ||
if ('touch' === this.inputType) { | ||
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].map(function (eventName) { | ||
@@ -143,6 +141,3 @@ el.addEventListener(eventName, boundFn, { passive: false }); | ||
AnyTouch.prototype.add = function (recognizer) { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = this.el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
recognizer.$injectRoot(this); | ||
this.recognizers.push(recognizer); | ||
@@ -235,7 +230,2 @@ this.update(); | ||
; | ||
AnyTouch.prototype.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
//# sourceMappingURL=main.js.map |
@@ -1,6 +0,3 @@ | ||
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import { Computed, directionString } from '../interface'; | ||
export default abstract class Recognizer { | ||
el: HTMLElement | HTMLDocument | Window; | ||
hasDomEvents: boolean; | ||
name: string; | ||
@@ -15,9 +12,10 @@ disabled: boolean; | ||
$root: any; | ||
default: Options; | ||
eventBus: any; | ||
constructor(options?: Options); | ||
set(options: Options): void; | ||
constructor(options: { | ||
name?: string; | ||
[k: string]: any; | ||
}); | ||
set(options?: {}): void; | ||
$injectRoot($root: any): this; | ||
emit(type: string, payload: any): void; | ||
on(type: string, listener: ((data: any) => void)): void; | ||
off(type: string, listener: ((data: any) => void)): void; | ||
requireFailure(recognizer: any): void; | ||
@@ -29,3 +27,3 @@ hasRequireFailure(): boolean; | ||
isOnlyVertical(): boolean; | ||
isVaildDirection(direction: string): boolean; | ||
isVaildDirection(direction?: directionString): boolean; | ||
recognize(computed: Computed): void; | ||
@@ -32,0 +30,0 @@ abstract test(computed: Computed): boolean; |
@@ -35,4 +35,3 @@ var __assign = (this && this.__assign) || function () { | ||
function Recognizer(options) { | ||
if (options === void 0) { options = { disabled: false }; } | ||
this.options = __assign({}, this.default, options); | ||
this.options = __assign({}, this.constructor.DEFAULT_OPTIONS, { disabled: false }, options); | ||
this.name = this.options.name; | ||
@@ -46,2 +45,3 @@ this.disabled = this.options.disabled; | ||
Recognizer.prototype.set = function (options) { | ||
if (options === void 0) { options = {}; } | ||
this.options = __assign({}, this.options, options); | ||
@@ -51,21 +51,17 @@ this.$root.update(); | ||
; | ||
Recognizer.prototype.$injectRoot = function ($root) { | ||
this.$root = $root; | ||
return this; | ||
}; | ||
Recognizer.prototype.emit = function (type, payload) { | ||
payload.type = type; | ||
this.eventBus.emit(type, payload); | ||
if (this.hasDomEvents) { | ||
this.$root.eventBus.emit(type, payload); | ||
if (this.$root.options.hasDomEvents) { | ||
var target = payload.target, currentTarget = payload.currentTarget, type_1 = payload.type, data = __rest(payload, ["target", "currentTarget", "type"]); | ||
var event_1 = new Event(type_1, payload); | ||
Object.assign(event_1, data); | ||
this.el.dispatchEvent(event_1); | ||
this.$root.el.dispatchEvent(event_1); | ||
} | ||
}; | ||
; | ||
Recognizer.prototype.on = function (type, listener) { | ||
this.eventBus.on(type, listener); | ||
}; | ||
; | ||
Recognizer.prototype.off = function (type, listener) { | ||
this.eventBus.off(type, listener); | ||
}; | ||
; | ||
Recognizer.prototype.requireFailure = function (recognizer) { | ||
@@ -142,3 +138,3 @@ if (!this.requireFailureRecognizers.includes(recognizer)) { | ||
Recognizer.prototype.isVaildDirection = function (direction) { | ||
return -1 < this.options.directions.indexOf(direction); | ||
return -1 !== this.options.directions.indexOf(direction) || 'none' === direction; | ||
}; | ||
@@ -149,3 +145,3 @@ ; | ||
var isVaild = this.test(computed); | ||
if (-1 < [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
if (-1 !== [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
@@ -152,0 +148,0 @@ } |
@@ -1,13 +0,11 @@ | ||
import { Computed, directionString } from '../interface'; | ||
import { Computed } from '../interface'; | ||
import Recognizer from './Base'; | ||
interface Options { | ||
name?: string; | ||
threshold?: number; | ||
pointerLength?: number; | ||
directions?: [directionString?, directionString?, directionString?, directionString?]; | ||
} | ||
export default class PanRecognizer extends Recognizer { | ||
name: string; | ||
options: Options; | ||
constructor(options?: Options); | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
threshold: number; | ||
pointerLength: number; | ||
directions: string[]; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
@@ -19,2 +17,1 @@ test({ distance, lastDirection, inputStatus, pointerLength }: Computed): boolean; | ||
} | ||
export {}; |
@@ -17,3 +17,2 @@ var __extends = (this && this.__extends) || (function () { | ||
import getHV from '../untils/getHV'; | ||
; | ||
var PanRecognizer = (function (_super) { | ||
@@ -50,3 +49,5 @@ __extends(PanRecognizer, _super); | ||
PanRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -81,2 +82,8 @@ ; | ||
; | ||
PanRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return PanRecognizer; | ||
@@ -86,8 +93,2 @@ }(Recognizer)); | ||
; | ||
PanRecognizer.prototype.default = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
//# sourceMappingURL=Pan.js.map |
@@ -5,3 +5,8 @@ import { Computed } from '../interface'; | ||
private _prevScale; | ||
constructor(options?: any); | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
threshold: number; | ||
pointerLength: number; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
@@ -8,0 +13,0 @@ afterEmit(computed: Computed): void; |
@@ -42,2 +42,7 @@ var __extends = (this && this.__extends) || (function () { | ||
; | ||
PinchRecognizer.DEFAULT_OPTIONS = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return PinchRecognizer; | ||
@@ -47,7 +52,2 @@ }(Recognizer)); | ||
; | ||
PinchRecognizer.prototype.default = { | ||
name: 'pinch', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
//# sourceMappingURL=Pinch.js.map |
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import Recognizer from './Base'; | ||
export default class PressRecognizer extends Recognizer { | ||
protected _timeoutId: number; | ||
constructor(options?: Options); | ||
protected _timeoutId?: number; | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
pointerLength: number; | ||
threshold: number; | ||
minPressTime: number; | ||
disabled: boolean; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
@@ -8,0 +14,0 @@ recognize(computed: Computed): void; |
@@ -21,5 +21,3 @@ var __extends = (this && this.__extends) || (function () { | ||
if (options === void 0) { options = {}; } | ||
var _this = _super.call(this, options) || this; | ||
_this._timeoutId = null; | ||
return _this; | ||
return _super.call(this, options) || this; | ||
} | ||
@@ -73,2 +71,9 @@ ; | ||
PressRecognizer.prototype.afterEmit = function () { }; | ||
PressRecognizer.DEFAULT_OPTIONS = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
return PressRecognizer; | ||
@@ -78,9 +83,2 @@ }(Recognizer)); | ||
; | ||
PressRecognizer.prototype.default = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
//# sourceMappingURL=Press.js.map |
import Base from './Base'; | ||
import { Computed } from '../interface'; | ||
export default class RotateRecognizer extends Base { | ||
constructor(options?: any); | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
threshold: number; | ||
pointerLength: number; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
@@ -6,0 +11,0 @@ afterEmit(computed: Computed): void; |
@@ -33,2 +33,7 @@ var __extends = (this && this.__extends) || (function () { | ||
; | ||
RotateRecognizer.DEFAULT_OPTIONS = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
return RotateRecognizer; | ||
@@ -38,7 +43,2 @@ }(Base)); | ||
; | ||
RotateRecognizer.prototype.default = { | ||
name: 'rotate', | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
//# sourceMappingURL=Rotate.js.map |
import Recognizer from './Base'; | ||
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
export default class SwipeRecognizer extends Recognizer { | ||
constructor(options?: Options); | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
threshold: number; | ||
velocity: number; | ||
pointerLength: number; | ||
directions: string[]; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
@@ -7,0 +13,0 @@ afterEmit(computed: Computed): void; |
@@ -28,3 +28,5 @@ var __extends = (this && this.__extends) || (function () { | ||
SwipeRecognizer.prototype.afterEmit = function (computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if ('none' !== computed.lastDirection) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -50,2 +52,9 @@ ; | ||
; | ||
SwipeRecognizer.DEFAULT_OPTIONS = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
return SwipeRecognizer; | ||
@@ -55,9 +64,2 @@ }(Recognizer)); | ||
; | ||
SwipeRecognizer.prototype.default = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
//# sourceMappingURL=Swipe.js.map |
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import Recognizer from './Base'; | ||
export default class TapRecognizer extends Recognizer { | ||
tapCount: number; | ||
tapTimeoutId: number; | ||
private _prevX; | ||
private _prevY; | ||
options: Options; | ||
default: Options; | ||
constructor(options?: Options); | ||
tapTimeoutId?: number; | ||
tapTimeout2Id?: number; | ||
prevTapX?: number; | ||
prevTapY?: number; | ||
isValidMovementFromPrevTap?: boolean; | ||
static DEFAULT_OPTIONS: { | ||
name: string; | ||
pointer: number; | ||
taps: number; | ||
interval: number; | ||
disabled: boolean; | ||
}; | ||
constructor(options?: {}); | ||
getTouchAction(): string[]; | ||
recognize(computed: Computed): void; | ||
cancel(): void; | ||
reset(): void; | ||
test(computed: Computed): boolean; | ||
afterEmit(computed: Computed): void; | ||
} |
@@ -25,3 +25,3 @@ var __extends = (this && this.__extends) || (function () { | ||
}; | ||
import { STATUS_RECOGNIZED, STATUS_POSSIBLE, STATUS_FAILED } from '../const/recognizerStatus'; | ||
import { STATUS_RECOGNIZED, STATUS_POSSIBLE, STATUS_FAILED, STATUS_START } from '../const/recognizerStatus'; | ||
var setTimeout = window.setTimeout, clearTimeout = window.clearTimeout; | ||
@@ -35,3 +35,2 @@ import Recognizer from './Base'; | ||
var _this = _super.call(this, options) || this; | ||
_this.tapTimeoutId = null; | ||
_this.tapCount = 0; | ||
@@ -47,47 +46,78 @@ return _this; | ||
var _this = this; | ||
this.status = STATUS_POSSIBLE; | ||
if (this.test(computed)) { | ||
this.tapCount++; | ||
var isValidTapCount_1 = this.options.taps === this.tapCount; | ||
if (this.hasRequireFailure()) { | ||
this.cancel(); | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (isValidTapCount_1 && _this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
; | ||
_this.tapCount = 0; | ||
}, this.options.interval); | ||
if (INPUT_END !== computed.inputStatus) | ||
return; | ||
if (-1 < [STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
} | ||
; | ||
var isValidEachTap = this.test(computed); | ||
var max = Math.max, pow = Math.pow, sqrt = Math.sqrt; | ||
var x = computed.x, y = computed.y; | ||
if (undefined === this.prevTapX || undefined === this.prevTapY) { | ||
this.isValidMovementFromPrevTap = true; | ||
} | ||
else { | ||
this.isValidMovementFromPrevTap = 10 > sqrt(max(pow(x - this.prevTapX, 2), pow(y - this.prevTapY, 2))); | ||
} | ||
this.prevTapX = x; | ||
this.prevTapY = y; | ||
if (isValidEachTap) { | ||
clearTimeout(this.tapTimeout2Id); | ||
if (this.isValidMovementFromPrevTap) { | ||
this.tapCount++; | ||
} | ||
else { | ||
this.cancel(); | ||
if (isValidTapCount_1) { | ||
if (this.options.taps === this.tapCount) { | ||
this.status = STATUS_START; | ||
if (this.hasRequireFailure()) { | ||
this.tapTimeoutId = setTimeout(function () { | ||
if (_this.isTheOtherFail()) { | ||
_this.status = STATUS_RECOGNIZED; | ||
_this.emit(_this.options.name, __assign({}, computed, { tapCount: _this.tapCount })); | ||
} | ||
else { | ||
_this.status = STATUS_FAILED; | ||
} | ||
; | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
else { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, __assign({}, computed, { tapCount: this.tapCount })); | ||
this.tapCount = 0; | ||
this.reset(); | ||
} | ||
this.tapTimeoutId = setTimeout(function () { | ||
_this.status = STATUS_FAILED; | ||
_this.tapCount = 0; | ||
} | ||
else { | ||
this.tapTimeout2Id = setTimeout(function () { | ||
_this.reset(); | ||
}, this.options.interval); | ||
} | ||
} | ||
else { | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
} | ||
}; | ||
; | ||
TapRecognizer.prototype.cancel = function () { | ||
clearTimeout(this.tapTimeoutId); | ||
TapRecognizer.prototype.reset = function () { | ||
this.tapCount = 0; | ||
this.prevTapX = undefined; | ||
this.prevTapY = undefined; | ||
}; | ||
; | ||
TapRecognizer.prototype.test = function (computed) { | ||
var abs = Math.abs, max = Math.max; | ||
var inputStatus = computed.inputStatus, distance = computed.distance, duration = computed.duration, maxPointerLength = computed.maxPointerLength, centerX = computed.centerX, centerY = computed.centerY; | ||
this._prevX = centerX; | ||
this._prevY = centerY; | ||
var offsetX = abs(centerX - this._prevX); | ||
var offsetY = abs(centerY - this._prevY); | ||
var hasMove = 2 < max(offsetX, offsetY); | ||
return INPUT_END === inputStatus && 1 === maxPointerLength && 2 > distance && 250 > duration && !hasMove; | ||
var distance = computed.distance, deltaTime = computed.deltaTime, maxPointerLength = computed.maxPointerLength; | ||
var isValidMovementTap = 2 >= distance; | ||
var isValidDeltaTime = 250 > deltaTime; | ||
return maxPointerLength === this.options.pointer && | ||
isValidDeltaTime && isValidMovementTap; | ||
}; | ||
; | ||
TapRecognizer.prototype.afterEmit = function (computed) { }; | ||
TapRecognizer.DEFAULT_OPTIONS = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
return TapRecognizer; | ||
@@ -97,9 +127,2 @@ }(Recognizer)); | ||
; | ||
TapRecognizer.prototype.default = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
//# sourceMappingURL=Tap.js.map |
@@ -1,3 +0,2 @@ | ||
import { directionString } from '../interface'; | ||
declare const _default: (directions: [directionString?, directionString?, directionString?, directionString?]) => { | ||
declare const _default: (directions: [("left" | "right" | "none" | "up" | "down" | undefined)?, ("left" | "right" | "none" | "up" | "down" | undefined)?, ("left" | "right" | "none" | "up" | "down" | undefined)?, ("left" | "right" | "none" | "up" | "down" | undefined)?]) => { | ||
hasHorizontal: boolean; | ||
@@ -4,0 +3,0 @@ hasVertical: boolean; |
@@ -1,2 +0,5 @@ | ||
import { Vector } from './interface'; | ||
interface Vector { | ||
x: number; | ||
y: number; | ||
} | ||
export declare const getVLength: (v: Vector) => number; | ||
@@ -13,2 +16,3 @@ export declare const getDotProduct: (v1: Vector, v2: Vector) => number; | ||
}; | ||
export declare const getDirection: (x: number, y: number) => string; | ||
export declare const getDirection: (x: number, y: number) => string | void; | ||
export {}; |
@@ -52,3 +52,3 @@ import { propX, propY } from './const'; | ||
if (x === y) { | ||
return undefined; | ||
return 'none'; | ||
} | ||
@@ -55,0 +55,0 @@ else if (Math.abs(x) > Math.abs(y)) { |
{ | ||
"name": "any-touch", | ||
"version": "0.0.25", | ||
"version": "0.0.26", | ||
"description": "一个手势库", | ||
@@ -49,2 +49,3 @@ "unpkg": "dist/AnyTouch.umd.js", | ||
"rollup-plugin-commonjs": "^9.2.0", | ||
"rollup-plugin-json": "^3.1.0", | ||
"rollup-plugin-node-resolve": "^3.4.0", | ||
@@ -51,0 +52,0 @@ "rollup-plugin-typescript": "^1.0.0", |
@@ -16,3 +16,3 @@ // 返回最近一个时间段的计算结果 | ||
export default (input: Input): { velocity: number, velocityX: number, velocityY: number, direction: string } => { | ||
export default (input: Input): { velocity: number, velocityX: number, velocityY: number, direction?: string } => { | ||
// 速率 | ||
@@ -19,0 +19,0 @@ let velocityX: number; |
@@ -18,3 +18,3 @@ | ||
input | ||
}: any): Computed { | ||
}: any): Computed | void { | ||
// 如果输入为空, 那么就计算了, 鼠标模式下, 点击了非元素部分, mouseup阶段会初选input为undefined | ||
@@ -25,39 +25,4 @@ if (undefined === input) return; | ||
let computed = <Computed>{ | ||
// pointers: [], | ||
// changedPointers: [], | ||
pointerLength: input.pointerLength, | ||
changedPointerLength: input.changedPointerLength, | ||
// 起始到结束的偏移 | ||
displacementX: 0, | ||
displacementY: 0, | ||
distanceX: 0, | ||
distanceY: 0, | ||
distance: 0, | ||
let computed = <Computed>{}; | ||
// 方向 | ||
direction: undefined, | ||
lastDirection: undefined, | ||
// 位移变化量 | ||
deltaX: undefined, | ||
deltaY: undefined, | ||
// 速率 | ||
velocityX: 0, | ||
velocityY: 0, | ||
maxVelocity: 0, | ||
// 时间 | ||
duration: 0, | ||
timestamp: Date.now(), | ||
// 旋转和缩放 | ||
angle: 0, | ||
deltaAngle: 0, | ||
scale: undefined, | ||
deltaScale: 1, | ||
lastVelocity: undefined, | ||
lastVelocityY: undefined, | ||
lastVelocityX: undefined, | ||
}; | ||
// 滑动距离 | ||
@@ -74,3 +39,3 @@ const { displacementX, displacementY, distanceX, distanceY, distance } = computeDistance({ | ||
// 已消耗时间 | ||
computed.duration = input.timestamp - startInput.timestamp; | ||
computed.deltaTime = input.timestamp - startInput.timestamp; | ||
// 最近25ms内计算数据 | ||
@@ -83,3 +48,3 @@ const lastComputed = computeLast(input); | ||
// 中心点位移增量 | ||
let { deltaX, deltaY,deltaXYAngle } = computeDeltaXY({ input, prevInput }); | ||
let { deltaX, deltaY, deltaXYAngle } = computeDeltaXY({ input, prevInput }); | ||
computed.deltaX = deltaX; | ||
@@ -97,4 +62,4 @@ computed.deltaY = deltaY; | ||
// 速率 | ||
computed.velocityX = abs(computed.distanceX / computed.duration) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.duration) || 0; | ||
computed.velocityX = abs(computed.distanceX / computed.deltaTime) || 0; | ||
computed.velocityY = abs(computed.distanceY / computed.deltaTime) || 0; | ||
computed.maxVelocity = max(computed.velocityX, computed.velocityY); | ||
@@ -126,7 +91,4 @@ | ||
return { | ||
...input, | ||
maxPointerLength, | ||
...computed | ||
}; | ||
computed = { ...computed, ...input, maxPointerLength }; | ||
return computed; | ||
}; |
@@ -9,3 +9,2 @@ // 简单判断是否手机设备 | ||
export const SUPPORT_TOUCH = ('ontouchstart' in window); | ||
// 是否是移动设备 | ||
@@ -12,0 +11,0 @@ export const SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent); |
@@ -1,6 +0,18 @@ | ||
let prevPointers: any[] = undefined; | ||
let prevPointers: { clientX: number, clientY: number }[]; | ||
let isPressed = false; | ||
export default (event: MouseEvent): any => { | ||
// 默认MouseEvent中对type声明仅为string | ||
export default (event: MouseEvent): { | ||
inputStatus: string, | ||
changedPointers: { clientX: number, clientY: number }[], | ||
pointers: { clientX: number, clientY: number }[], | ||
nativeEvent: Event | ||
} | void => { | ||
const { clientX, clientY, type } = event; | ||
const changedPointers = prevPointers; | ||
// changedPointers = prevPointers其实并不能完全等于touch下的changedPointers | ||
// 但是由于鼠标没有多点输入的需求, | ||
// 所以暂时如此实现 | ||
const changedPointers = prevPointers || [{ clientX, clientY }]; | ||
// console.log(prevPointers, [{ clientX, clientY }],changedPointers); | ||
let pointers = [{ clientX, clientY }]; | ||
@@ -21,5 +33,3 @@ prevPointers = [{ clientX, clientY }]; | ||
const MAP: { | ||
[propName: string]: string; | ||
} = { | ||
const MAP = { | ||
mousedown: 'start', | ||
@@ -31,4 +41,3 @@ mousemove: 'move', | ||
return { | ||
// type: `input-${MAP[type]}`, | ||
inputStatus: MAP[type], | ||
inputStatus: MAP[<'mousedown' | 'mousemove' | 'mouseup'>type], | ||
changedPointers, | ||
@@ -35,0 +44,0 @@ pointers, |
@@ -5,3 +5,3 @@ /** | ||
import { Input } from '../interface'; | ||
import { SUPPORT_ONLY_TOUCH, IS_MOBILE, INPUT_CANCEL, INPUT_END, INPUT_MOVE, INPUT_START } from '../const'; | ||
import { SUPPORT_TOUCH, IS_MOBILE, INPUT_CANCEL, INPUT_END, INPUT_MOVE, INPUT_START } from '../const'; | ||
import { getCenter } from '../vector'; | ||
@@ -13,6 +13,6 @@ import touchAdapter from './adapters/touch' | ||
export default (event: TouchEvent | MouseEvent): Input => { | ||
export default (event: Event): Input|undefined => { | ||
let input: any = {}; | ||
// Touch | ||
if (IS_MOBILE) { | ||
if (SUPPORT_TOUCH) { | ||
input = touchAdapter(<TouchEvent>event); | ||
@@ -19,0 +19,0 @@ } |
import { Input } from './interface'; | ||
import createInput from './input/create'; | ||
// 起点(单点|多点) | ||
let startInput: Input; | ||
let startInput: Input | undefined; | ||
// 前一次的触电 | ||
let prevInput: Input; | ||
let prevInput: Input | undefined; | ||
// 当前触点 | ||
let activeInput: Input; | ||
let activeInput: Input | undefined; | ||
// 多点触碰的起点 | ||
let startMutliInput: Input; | ||
export default (event: TouchEvent | MouseEvent): any => { | ||
let startMutliInput: Input | undefined; | ||
export default (event: Event): any => { | ||
// 格式化不同设备输入数据 | ||
@@ -13,0 +13,0 @@ const input = createInput(event); |
export type directionString = 'up' | 'right' | 'down' | 'left' | 'none' | 'all'; | ||
export type inputStatus = 'start' | 'move' | 'end' | 'cancel'; | ||
export type directionString = 'up' | 'right' | 'down' | 'left' | 'none'; | ||
export type RecognizerStatus = 'possible' | 'recognized' | 'began' | 'changed' | 'ended' | 'failed' | 'cancelled'; | ||
export interface Input { | ||
// 新一轮手势识别的开始 | ||
isFirst: boolean; | ||
isFinal: boolean; | ||
inputStatus?: inputStatus; | ||
nativeEvent?: any; | ||
pointers: { clientX: number, clientY: number }[]; | ||
inputStatus: 'start' | 'move' | 'end' | 'cancel'; | ||
nativeEvent: Event; | ||
pointer: { clientX: number, clientY: number }[]; | ||
pointerLength: number; | ||
// 发生改变的触点数据 | ||
changedPointers: { clientX: number, clientY: number }[]; | ||
changedPointerLength: number; | ||
// 当前时间 | ||
timestamp: number; | ||
target?: EventTarget; | ||
target: EventTarget; | ||
currentTarget?: EventTarget; | ||
centerX?: number; | ||
centerY?: number; | ||
centerX: number; | ||
centerY: number; | ||
// functions?: { [k: string]: (...args: any[]) => any }; | ||
@@ -24,5 +27,5 @@ } | ||
export interface Computed extends Input { | ||
type?: string; | ||
inputStatus?: inputStatus; //start | move | end | cancel | ||
length?: number; | ||
// 手势类型名: pan/panstart/panleft... | ||
type: string; | ||
// 一次识别周期中出现的最大触点数 | ||
maxPointerLength?: number; | ||
@@ -39,7 +42,5 @@ lastVelocity: number; | ||
deltaAngle: number; | ||
centerX?: number; | ||
centerY?: number; | ||
deltaX: number; | ||
deltaY: number; | ||
deltaXYAngle:number; | ||
deltaXYAngle: number; | ||
displacementX: number; | ||
@@ -50,47 +51,10 @@ displacementY: number; | ||
distance: number; | ||
duration: number; | ||
direction: directionString; | ||
deltaTime: number; | ||
// 与起始点的偏移方向 | ||
direction?: directionString; | ||
// 最近的方向 | ||
lastDirection: directionString; | ||
// 2次input的时间差 | ||
deltaTime?: number; | ||
tapCount?: number; | ||
getRadian:(v1: Vector, v2: Vector)=>number; | ||
} | ||
// 识别器中recognize方法返回的数据格式 | ||
export interface RecognizerCallbackPaylod extends Computed { | ||
type: string; | ||
} | ||
export interface RecognizerCallback { | ||
(paylod: RecognizerCallbackPaylod): void | ||
} | ||
// 事件触发函数 | ||
export interface EventHandler { | ||
(event: Computed): void; | ||
} | ||
// 手势的触发函数 | ||
export interface EventBus { | ||
pinch?: EventHandler[]; | ||
tap?: EventHandler[]; | ||
doubletap?: EventHandler[]; | ||
press?: EventHandler[]; | ||
pan?: EventHandler[]; | ||
swipe?: EventHandler[]; | ||
touchStart?: EventHandler[]; | ||
touchMove?: EventHandler[]; | ||
touchEnd?: EventHandler[]; | ||
// [key:string]: any; | ||
[propsName: string]: EventHandler[]; | ||
} | ||
// 向量 | ||
export interface Vector { | ||
lastDirection?: directionString; | ||
// 同centerX/Y | ||
x: number; | ||
y: number; | ||
} |
@@ -20,5 +20,5 @@ /** | ||
import AnyEvent from 'any-event'; | ||
import { EventHandler, Computed } from './interface'; | ||
import { Computed } from './interface'; | ||
import { | ||
SUPPORT_ONLY_TOUCH, | ||
SUPPORT_ONLY_TOUCH, SUPPORT_TOUCH, | ||
IS_MOBILE, | ||
@@ -38,2 +38,3 @@ } from './const'; | ||
import * as Vector from './vector'; | ||
const pkg = require('../package.json'); | ||
interface Options { | ||
@@ -52,2 +53,3 @@ touchAction?: 'compute' | 'auto' | 'manipulation' | 'pan-x' | 'pan-y' | 'none'; | ||
static Vector = Vector; | ||
// 目标元素 | ||
@@ -58,2 +60,4 @@ el: HTMLElement; | ||
inputType: string; | ||
recognizers: { [propName: string]: any, name: string }[]; | ||
@@ -65,4 +69,2 @@ | ||
isMobile: boolean; | ||
options: Options; | ||
@@ -77,5 +79,10 @@ | ||
constructor(el: HTMLElement, options?: Options) { | ||
this.version = '0.0.25'; | ||
this.version = pkg.version; | ||
this.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; | ||
this.el = el; | ||
this.isMobile = IS_MOBILE; | ||
this.inputType = SUPPORT_TOUCH ? 'touch' : 'mouse'; | ||
this.options = { ...this.default, ...options }; | ||
@@ -86,21 +93,12 @@ // eventBus | ||
this.recognizers = [ | ||
new TapRecognizer(), | ||
new PressRecognizer(), | ||
new PanRecognizer(), | ||
new SwipeRecognizer(), | ||
new PinchRecognizer(), | ||
new RotateRecognizer(), | ||
new TapRecognizer().$injectRoot(this), | ||
new PressRecognizer().$injectRoot(this), | ||
new PanRecognizer().$injectRoot(this), | ||
new SwipeRecognizer().$injectRoot(this), | ||
new PinchRecognizer().$injectRoot(this), | ||
new RotateRecognizer().$injectRoot(this), | ||
]; | ||
// 注入el | ||
// 后面模拟浏览器时间需要用到el | ||
this.recognizers.forEach(recognizer => { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
}); | ||
// 应用设置 | ||
this.update(); | ||
// this.update(); | ||
@@ -124,3 +122,3 @@ // 绑定事件 | ||
} else { | ||
el.style.touchAction = this.options.touchAction; | ||
el.style.touchAction = this.options.touchAction || 'auto'; | ||
} | ||
@@ -139,3 +137,3 @@ }; | ||
const boundFn = this.handler.bind(this); | ||
if (this.isMobile) { | ||
if ('touch' === this.inputType) { | ||
return ['touchstart', 'touchmove', 'touchend', 'touchcancel'].map(eventName => { | ||
@@ -170,7 +168,3 @@ el.addEventListener(eventName, boundFn, { passive: false }); | ||
add(recognizer: any): void { | ||
recognizer.eventBus = this.eventBus; | ||
recognizer.el = this.el; | ||
recognizer.$root = this; | ||
recognizer.hasDomEvents = this.options.hasDomEvents; | ||
recognizer.$injectRoot(this); | ||
this.recognizers.push(recognizer); | ||
@@ -211,3 +205,3 @@ this.update(); | ||
handler(event: TouchEvent | MouseEvent): void { | ||
handler(event: Event): void { | ||
if (!event.cancelable) { | ||
@@ -223,9 +217,7 @@ this.eventBus.emit('error', { code: 0, message: '页面滚动的时候, 请暂时不要操作元素!' }); | ||
if (undefined !== inputs) { | ||
const computed: Computed = compute(inputs); | ||
const computed = compute(inputs); | ||
// 当是鼠标事件的时候, mouseup阶段的input和computed为空 | ||
for (let recognizer of this.recognizers) { | ||
// const isValidEvent = Recognizer.prototype.eventBus.has(recognizer.name); | ||
if (recognizer.disabled) continue; | ||
recognizer.recognize(computed); | ||
// recognizer.emit('input', { ...computed, type: 'input' }); | ||
} | ||
@@ -240,3 +232,3 @@ } | ||
*/ | ||
on(type: string, listener: EventHandler): void { | ||
on(type: string, listener: (event: Computed) => void): void { | ||
this.eventBus.on(type, listener); | ||
@@ -250,3 +242,3 @@ }; | ||
*/ | ||
off(type: string, listener?: EventHandler): void { | ||
off(type: string, listener?: (event: Computed) => void): void { | ||
this.eventBus.off(type, listener); | ||
@@ -264,8 +256,2 @@ }; | ||
}; | ||
}; | ||
AnyTouch.prototype.default = { | ||
touchAction: 'compute', | ||
hasDomEvents: true, | ||
isPreventDefault: true | ||
}; |
@@ -6,4 +6,3 @@ /* | ||
* */ | ||
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import { Computed, directionString } from '../interface'; | ||
import { INPUT_CANCEL, INPUT_END, INPUT_MOVE, INPUT_START } from '../const'; | ||
@@ -20,10 +19,6 @@ import { | ||
export default abstract class Recognizer { | ||
// 关联元素 | ||
public el: HTMLElement | HTMLDocument | Window; | ||
// 是否构造原生事件(new Event()) | ||
public hasDomEvents: boolean; | ||
// 手势名 | ||
public name: string; | ||
// 是否禁止 | ||
public disabled:boolean; | ||
public disabled: boolean; | ||
// 识别状态 | ||
@@ -38,12 +33,8 @@ public status: string; | ||
// 存储外部注入方法的容器 | ||
// public $root: { [k: string]: (...args: any[]) => void }; | ||
public $root: any; | ||
// 默认参数 | ||
public default: Options; | ||
public eventBus: any; | ||
constructor(options: Options = { disabled: false }) { | ||
this.options = { ...this.default, ...options }; | ||
constructor(options: { name?: string, [k: string]: any }) { | ||
this.options = { ...(<any>this.constructor).DEFAULT_OPTIONS, disabled: false, ...options }; | ||
this.name = this.options.name; | ||
@@ -63,3 +54,3 @@ this.disabled = this.options.disabled; | ||
*/ | ||
public set(options: Options) { | ||
public set(options = {}) { | ||
this.options = { ...this.options, ...options }; | ||
@@ -70,2 +61,7 @@ // 刷新anyTouch | ||
public $injectRoot($root: any) { | ||
this.$root = $root; | ||
return this; | ||
} | ||
/** | ||
@@ -78,4 +74,4 @@ * 对eventBus进行封装 | ||
payload.type = type; | ||
this.eventBus.emit(type, payload); | ||
if (this.hasDomEvents) { | ||
this.$root.eventBus.emit(type, payload); | ||
if (this.$root.options.hasDomEvents) { | ||
// 过滤掉几个Event上保留的字段 | ||
@@ -85,23 +81,23 @@ let { target, currentTarget, type, ...data } = payload; | ||
Object.assign(event, data); | ||
this.el.dispatchEvent(event); | ||
this.$root.el.dispatchEvent(event); | ||
} | ||
}; | ||
/** | ||
* 对$root.进行封装 | ||
* @param type | ||
* @param payload | ||
*/ | ||
public on(type: string, listener: ((data: any) => void)) { | ||
this.eventBus.on(type, listener); | ||
}; | ||
// /** | ||
// * 对$root.进行封装 | ||
// * @param type | ||
// * @param payload | ||
// */ | ||
// public on(type: string, listener: ((data: any) => void)) { | ||
// this.eventBus.on(type, listener); | ||
// }; | ||
/** | ||
* 对eventBus进行封装 | ||
* @param type | ||
* @param payload | ||
*/ | ||
public off(type: string, listener: ((data: any) => void)) { | ||
this.eventBus.off(type, listener); | ||
}; | ||
// /** | ||
// * 对eventBus进行封装 | ||
// * @param type | ||
// * @param payload | ||
// */ | ||
// public off(type: string, listener: ((data: any) => void)) { | ||
// this.eventBus.off(type, listener); | ||
// }; | ||
@@ -176,5 +172,4 @@ /** | ||
*/ | ||
public isVaildDirection(direction: string) { | ||
// if('pan' === this.options.name) console.log(this.options.directions, direction, -1 < this.options.directions.indexOf(direction)); | ||
return -1 < this.options.directions.indexOf(direction); | ||
public isVaildDirection(direction?: directionString) { | ||
return -1 !== this.options.directions.indexOf(direction) || 'none' === direction; | ||
}; | ||
@@ -197,3 +192,3 @@ | ||
recognize(computed: Computed) { | ||
// this.beforeRecognize(computed); | ||
// if(this.name === 'pan') console.log(this.name,this.status); | ||
let { inputStatus } = computed; | ||
@@ -203,3 +198,3 @@ // 是否识别成功 | ||
// 如果识别结束, 那么重置状态 | ||
if (-1 < [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
if (-1 !== [STATUS_END, STATUS_CANCELLED, STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
@@ -220,8 +215,6 @@ }; | ||
this.status = STATUS_CANCELLED; | ||
this.emit(this.options.name+'cancel', computed); | ||
this.emit(this.options.name + 'cancel', computed); | ||
return; | ||
} | ||
// console.log( | ||
@@ -237,8 +230,7 @@ // `%c ${this.options.name} `, 'background-color:#66c;color:#fff;', | ||
this.afterRecognized(computed); | ||
// computed = this.lockDirection(computed); | ||
// computed = this.lockDirection(computed);d | ||
this.emit(this.options.name, computed); | ||
if (-1 < [STATUS_START, STATUS_MOVE, STATUS_END, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
// panstart | panmove | panend | ||
// panstart | panmove | panend等 | ||
this.emit(this.options.name + this.status, computed); | ||
@@ -245,0 +237,0 @@ this.afterEmit(computed); |
@@ -5,14 +5,11 @@ import { Computed, directionString } from '../interface'; | ||
import getHV from '../untils/getHV'; | ||
interface Options { | ||
name?: string; | ||
threshold?: number; | ||
pointerLength?: number; | ||
directions?: [directionString?, directionString?, directionString?, directionString?]; | ||
}; | ||
export default class PanRecognizer extends Recognizer { | ||
public name: string; | ||
public options: Options; | ||
constructor(options: Options={}) { | ||
static DEFAULT_OPTIONS = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
constructor(options = {}) { | ||
super(options); | ||
@@ -49,11 +46,12 @@ }; | ||
/** | ||
* 识别后发布panleft等事件g | ||
* 识别后发布panleft等事件 | ||
* @param {Computed} 计算数据 | ||
*/ | ||
afterEmit(computed: Computed) { | ||
// console.log(computed.lastDirection, computed); | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if('none' !== computed.lastDirection){ | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
afterRecognized(computed: Computed){ | ||
afterRecognized(computed: Computed) { | ||
this.lockDirection(computed); | ||
@@ -79,3 +77,2 @@ } | ||
deltaY = computed.deltaY; | ||
// console.log(321321312); | ||
} | ||
@@ -87,10 +84,2 @@ }); | ||
}; | ||
}; | ||
// 默认参数 | ||
PanRecognizer.prototype.default = { | ||
name: 'pan', | ||
threshold: 10, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; |
import { Computed } from '../interface'; | ||
import Recognizer from './Base'; | ||
export default class PinchRecognizer extends Recognizer { | ||
private _prevScale: number; | ||
constructor(options: any={}) { | ||
static DEFAULT_OPTIONS = { | ||
name: 'pinch', | ||
// 触发事件所需要的最小缩放比例 | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
constructor(options={}) { | ||
super(options); | ||
@@ -35,10 +43,2 @@ this._prevScale = 1; | ||
}; | ||
}; | ||
// 默认参数 | ||
PinchRecognizer.prototype.default = { | ||
name: 'pinch', | ||
// 触发事件所需要的最小缩放比例 | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; |
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import { | ||
@@ -11,6 +10,12 @@ STATUS_POSSIBLE, | ||
export default class PressRecognizer extends Recognizer { | ||
protected _timeoutId: number; | ||
constructor(options: Options = {}) { | ||
protected _timeoutId?: number; | ||
static DEFAULT_OPTIONS = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; | ||
constructor(options = {}) { | ||
super(options); | ||
this._timeoutId = null; | ||
}; | ||
@@ -28,3 +33,3 @@ | ||
if(STATUS_FAILED === this.status) return; | ||
if (STATUS_FAILED === this.status) return; | ||
@@ -37,18 +42,18 @@ | ||
// 那么延迟触发press | ||
const IS_VALID = this.test(computed) | ||
// console.log({IS_VALID}); | ||
if (IS_VALID) { | ||
// 延迟触发 | ||
this.cancel(); | ||
this._timeoutId = window.setTimeout(() => { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, computed); | ||
}, this.options.minPressTime); | ||
// console.log('_timeoutId', this._timeoutId); | ||
} else { | ||
this.cancel(); | ||
this.status = STATUS_FAILED; | ||
} | ||
const IS_VALID = this.test(computed) | ||
// console.log({IS_VALID}); | ||
if (IS_VALID) { | ||
// 延迟触发 | ||
this.cancel(); | ||
this._timeoutId = window.setTimeout(() => { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, computed); | ||
}, this.options.minPressTime); | ||
// console.log('_timeoutId', this._timeoutId); | ||
} else { | ||
this.cancel(); | ||
this.status = STATUS_FAILED; | ||
} | ||
if(INPUT_END === inputStatus) { | ||
if (INPUT_END === inputStatus) { | ||
this.status = STATUS_FAILED; | ||
@@ -59,3 +64,3 @@ // console.log(this.status); | ||
// 已识别 | ||
else{ | ||
else { | ||
// end阶段触发pressup | ||
@@ -82,11 +87,2 @@ if (INPUT_END === inputStatus) { | ||
afterEmit() { } | ||
}; | ||
// 默认参数 | ||
PressRecognizer.prototype.default = { | ||
name: 'press', | ||
pointerLength: 1, | ||
threshold: 9, | ||
minPressTime: 251, | ||
disabled: false | ||
}; |
import Base from './Base'; | ||
import { Computed } from '../interface'; | ||
export default class RotateRecognizer extends Base { | ||
constructor(options: any={}) { | ||
static DEFAULT_OPTIONS = { | ||
name: 'rotate', | ||
// 触发事件所需要的最小角度 | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; | ||
constructor(options = {}) { | ||
super(options); | ||
}; | ||
getTouchAction(){ | ||
getTouchAction() { | ||
return ['none']; | ||
}; | ||
/** | ||
@@ -27,10 +33,2 @@ * 无特殊事件要触发 | ||
}; | ||
}; | ||
// 默认参数 | ||
RotateRecognizer.prototype.default = { | ||
name: 'rotate', | ||
// 触发事件所需要的最小角度 | ||
threshold: 0, | ||
pointerLength: 2, | ||
}; |
import Recognizer from './Base'; | ||
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import {INPUT_END} from '../const'; | ||
import { INPUT_END } from '../const'; | ||
export default class SwipeRecognizer extends Recognizer { | ||
constructor(options: Options={}) { | ||
static DEFAULT_OPTIONS = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; | ||
constructor(options = {}) { | ||
super(options); | ||
}; | ||
getTouchAction(){ | ||
getTouchAction() { | ||
return ['none']; | ||
@@ -19,3 +25,5 @@ }; | ||
afterEmit(computed: Computed) { | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
if('none' !== computed.lastDirection){ | ||
this.emit(this.options.name + computed.lastDirection, computed); | ||
} | ||
}; | ||
@@ -47,11 +55,2 @@ | ||
}; | ||
}; | ||
// 默认参数 | ||
SwipeRecognizer.prototype.default = { | ||
name: 'swipe', | ||
threshold: 10, | ||
velocity: 0.3, | ||
pointerLength: 1, | ||
directions: ['up', 'right', 'down', 'left'] | ||
}; |
import { Computed } from '../interface'; | ||
import { Options } from '../../types/recognition'; | ||
import { | ||
STATUS_RECOGNIZED, | ||
STATUS_POSSIBLE, | ||
STATUS_FAILED | ||
STATUS_FAILED, | ||
STATUS_START | ||
} from '../const/recognizerStatus'; | ||
const { setTimeout, clearTimeout } = window; | ||
import Recognizer from './Base'; | ||
import { INPUT_END } from '../const'; | ||
import { INPUT_END, INPUT_START } from '../const'; | ||
export default class TapRecognizer extends Recognizer { | ||
tapCount: number; | ||
tapTimeoutId: number; | ||
// 上一次tap的点击坐标 | ||
private _prevX: number; | ||
private _prevY: number; | ||
public options: Options; | ||
public default: Options; | ||
constructor(options: Options = {}) { | ||
tapTimeoutId?: number; | ||
tapTimeout2Id?: number; | ||
// 记录每次单击完成时的坐标 | ||
prevTapX?: number; | ||
prevTapY?: number; | ||
// 多次tap之间的距离是否满足要求 | ||
isValidMovementFromPrevTap?: boolean; | ||
static DEFAULT_OPTIONS = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled: false | ||
}; | ||
constructor(options = {}) { | ||
super(options); | ||
this.tapTimeoutId = null; | ||
this.tapCount = 0; | ||
@@ -36,41 +44,81 @@ }; | ||
public recognize(computed: Computed): void { | ||
this.status = STATUS_POSSIBLE; | ||
// this.cancel(); | ||
if (this.test(computed)) { | ||
// 累加点击 | ||
this.tapCount++; | ||
const isValidTapCount = this.options.taps === this.tapCount; | ||
if (this.hasRequireFailure()) { | ||
// 如果是需要其他手势失败才能触发的手势, | ||
// 需要等待(300ms)其他手势失败才能触发 | ||
this.cancel(); | ||
this.tapTimeoutId = setTimeout(() => { | ||
if (isValidTapCount && this.isTheOtherFail()) { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, { ...computed, tapCount: this.tapCount }); | ||
}; | ||
this.tapCount = 0; | ||
}, this.options.interval); | ||
} else { | ||
// 只在end阶段去识别 | ||
if (INPUT_END !== computed.inputStatus) return; | ||
// 如果识别结束, 那么重置状态 | ||
if (-1 < [STATUS_FAILED, STATUS_RECOGNIZED].indexOf(this.status)) { | ||
this.status = STATUS_POSSIBLE; | ||
}; | ||
// 每一次点击是否符合要求 | ||
const isValidEachTap = this.test(computed); | ||
// 判断2次点击之间的距离是否过大 | ||
const { max, pow, sqrt } = Math; | ||
const { x, y } = computed; | ||
if (undefined === this.prevTapX || undefined === this.prevTapY) { | ||
this.isValidMovementFromPrevTap = true; | ||
} else { | ||
this.isValidMovementFromPrevTap = 10 > sqrt(max(pow(x - this.prevTapX, 2), pow(y - this.prevTapY, 2))); | ||
} | ||
this.prevTapX = x; | ||
this.prevTapY = y; | ||
// console.log(this.name, this.options.taps, this.isValidMovementFromPrevTap); | ||
if (isValidEachTap) { | ||
// 取消当前识别 | ||
clearTimeout(this.tapTimeout2Id); | ||
// 对符合要求的点击进行累加 | ||
if (this.isValidMovementFromPrevTap) { | ||
this.tapCount++; | ||
} | ||
// 是否满足点击次数要求 | ||
if (this.options.taps === this.tapCount) { | ||
this.status = STATUS_START; | ||
// 如果需要其他手势失败 | ||
// 等待(300ms)其他手势失败后触发 | ||
if (this.hasRequireFailure()) { | ||
this.tapTimeoutId = setTimeout(() => { | ||
// 检查指定手势是否识别为Fail | ||
if (this.isTheOtherFail()) { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, { ...computed, tapCount: this.tapCount }); | ||
} else { | ||
this.status = STATUS_FAILED; | ||
}; | ||
// 不论成功失败都要重置tap计数 | ||
this.reset(); | ||
}, this.options.interval); | ||
} | ||
// 如果不需要等待其他手势失败 | ||
// 那么立即执行 | ||
this.cancel(); | ||
if (isValidTapCount) { | ||
else { | ||
this.status = STATUS_RECOGNIZED; | ||
this.emit(this.options.name, { ...computed, tapCount: this.tapCount }); | ||
this.tapCount = 0; | ||
this.reset(); | ||
} | ||
this.tapTimeoutId = setTimeout(() => { | ||
this.status = STATUS_FAILED; | ||
this.tapCount = 0; | ||
} | ||
// 不满足次数要求(过多或者过少), | ||
// 间隔时间后都要重置计数, | ||
// 不然会出现如下: | ||
// 慢慢的点击n次, 会触发nTap | ||
else { | ||
this.tapTimeout2Id = setTimeout(() => { | ||
this.reset(); | ||
}, this.options.interval) | ||
} | ||
} else { | ||
// if (this.options.taps !== this.tapCount) { | ||
// clearTimeout(this.tapTimeoutId); | ||
// } | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
} | ||
}; | ||
/** | ||
* 取消等待识别的 | ||
*/ | ||
public cancel() { | ||
clearTimeout(this.tapTimeoutId); | ||
}; | ||
public reset() { | ||
this.tapCount = 0; | ||
this.prevTapX = undefined; | ||
this.prevTapY = undefined; | ||
} | ||
@@ -83,24 +131,16 @@ /** | ||
public test(computed: Computed): boolean { | ||
const { abs, max } = Math; | ||
// 判断是否发生大的位置变化 | ||
const { inputStatus, distance, duration, maxPointerLength, centerX, centerY } = computed; | ||
this._prevX = centerX; | ||
this._prevY = centerY; | ||
// 产生的位移 | ||
let offsetX = abs(centerX - this._prevX); | ||
let offsetY = abs(centerY - this._prevY); | ||
const hasMove = 2 < max(offsetX, offsetY); | ||
return INPUT_END === inputStatus && 1 === maxPointerLength && 2 > distance && 250 > duration && !hasMove | ||
const { distance, deltaTime, maxPointerLength } = computed; | ||
// 每次单击流程中, 是否没有发生大的移动 | ||
const isValidMovementTap = 2 >= distance; | ||
const isValidDeltaTime = 250 > deltaTime; | ||
// 与上一次点击的距离在合理范围内 | ||
return maxPointerLength === this.options.pointer && | ||
isValidDeltaTime && isValidMovementTap; | ||
}; | ||
afterEmit(computed: Computed): void { } | ||
}; | ||
// 默认参数 | ||
TapRecognizer.prototype.default = { | ||
name: 'tap', | ||
pointer: 1, | ||
taps: 1, | ||
interval: 300, | ||
disabled:false | ||
public afterEmit(computed: Computed): void { } | ||
}; |
@@ -11,6 +11,6 @@ /** | ||
for (let direction of directions) { | ||
if (-1 < ['left', 'right'].indexOf(direction)) { | ||
if (-1 < ['left', 'right'].indexOf(<string>direction)) { | ||
hasHorizontal = true; | ||
if (hasVertical) break; | ||
} else if (-1 < ['up', 'down'].indexOf(direction)) { | ||
} else if (-1 < ['up', 'down'].indexOf(<string>direction)) { | ||
hasVertical = true; | ||
@@ -17,0 +17,0 @@ if (hasHorizontal) break; |
@@ -1,3 +0,6 @@ | ||
import { Vector } from './interface'; | ||
import { propX, propY } from './const'; | ||
interface Vector { | ||
x: number; | ||
y: number; | ||
} | ||
const { round } = Math; | ||
@@ -97,5 +100,5 @@ /** | ||
*/ | ||
export const getDirection = (x: number, y: number): string => { | ||
export const getDirection = (x: number, y: number): string | void => { | ||
if (x === y) { | ||
return undefined; | ||
return 'none'; | ||
} else if (Math.abs(x) > Math.abs(y)) { | ||
@@ -102,0 +105,0 @@ return 0 < x ? 'right' : 'left'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
307311
19
112
6797