@any-touch/tap
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -1,3 +0,2 @@ | ||
import { Point, Input } from '@any-touch/shared'; | ||
import Recognizer from '@any-touch/recognizer'; | ||
import type { RecognizerOptions, RecognizerFunction } from '@any-touch/shared'; | ||
declare const DEFAULT_OPTIONS: { | ||
@@ -12,78 +11,3 @@ name: string; | ||
}; | ||
export default class extends Recognizer { | ||
tapCount: number; | ||
prevTapPoint?: Point; | ||
prevTapTime?: number; | ||
isValidDistanceFromPrevTap?: boolean; | ||
private _countDownToFailTimer?; | ||
constructor(options: Partial<typeof DEFAULT_OPTIONS>); | ||
/** | ||
* 判断前后2次点击的距离是否超过阈值 | ||
* @param {Point} 当前触点中心坐标 | ||
* @return {Boolean} 前后2次点击的距离是否超过阈值 | ||
*/ | ||
private _isValidDistanceFromPrevTap; | ||
/** | ||
* 校验2次tap的时间间隔是否满足 | ||
* @return {Boolean} 是否满足 | ||
*/ | ||
private _isValidInterval; | ||
/** | ||
* 识别后执行, 流程如下: | ||
* 开始 | ||
* | | ||
* <是否end阶段> - 否 - 结束 | ||
* | | ||
* 关闭定时器c1和c2 | ||
* | | ||
* 清除等待状态 | ||
* | | ||
* 是 | ||
* | | ||
* 重置状态为"可能是" | ||
* | | ||
* <是否满足单击条件> - 否 - 结束 | ||
* | | ||
* 是 | ||
* | | ||
* <是否正确连击:是否上次点击信息为空 或 与上次点击的位移/时间是否满足约束> - 否 - 点击次数=1 - 继续(<是否到达点击数要求>) | ||
* | | ||
* 是 | ||
* | | ||
* 点击次数+1 | ||
* | | ||
* <是否到达点击数要求> - 否 - 设置定时器c1(t1毫秒后状态设置为"失败") - 结束 | ||
* | | ||
* 是 | ||
* | | ||
* <是否需要其他手势失败> - 否 - 触发事件, 状态设置为"已识别",重置(点击次数,位置) - 结束 | ||
* | | ||
* 是 | ||
* | | ||
* 进入等待状态 | ||
* | | ||
* <设置定时器c2(t1毫秒后检查"需要失败"的手势是否是"失败"状态, 重置(点击次数,位置, 等待状态)> - 否 - 设置状态为"失败" - 结束 | ||
* | | ||
* 是 | ||
* | | ||
* 触发, 状态设置为"已识别", 重置(点击次数,位置) | ||
* | | ||
* 结束 | ||
* | ||
* @param {Input} 计算数据 | ||
*/ | ||
recognize(input: Input, emit: (type: string, ...payload: any[]) => void): void; | ||
/** | ||
* 指定时候后, 状态变为"失败" | ||
*/ | ||
countDownToFail(): void; | ||
cancelCountDownToFail(): void; | ||
reset(): void; | ||
/** | ||
* 识别条件 | ||
* @param {Input} 输入记录 | ||
* @return {Boolean} 是否验证成功 | ||
*/ | ||
test(input: Input): boolean; | ||
} | ||
export default function Tap(options?: RecognizerOptions<typeof DEFAULT_OPTIONS>): ReturnType<RecognizerFunction>; | ||
export {}; |
@@ -1,6 +0,6 @@ | ||
import { __extends, __assign } from 'tslib'; | ||
import { INPUT_END, STATUS_POSSIBLE, STATUS_RECOGNIZED, STATUS_FAILED } from '@any-touch/shared'; | ||
import Recognizer from '@any-touch/recognizer'; | ||
import { __assign } from 'tslib'; | ||
import { RECOGNIZER_STATUS, STAGE } from '@any-touch/shared'; | ||
import { getVLength } from '@any-touch/vector'; | ||
import { ComputeMaxLength, ComputeDistance } from '@any-touch/compute'; | ||
import { ComputeDistance, ComputeMaxLength } from '@any-touch/compute'; | ||
import createContext from '@any-touch/recognizer'; | ||
@@ -16,86 +16,84 @@ var DEFAULT_OPTIONS = { | ||
}; | ||
var default_1 = (function (_super) { | ||
__extends(default_1, _super); | ||
function default_1(options) { | ||
var _this = _super.call(this, __assign(__assign({}, DEFAULT_OPTIONS), options)) || this; | ||
_this.tapCount = 0; | ||
return _this; | ||
function Tap(options) { | ||
var _context = createContext(DEFAULT_OPTIONS, options); | ||
var _tapCount = 0; | ||
var _prevTapPoint; | ||
var _prevTapTime; | ||
var _countDownToFailTimer; | ||
function _test(computed) { | ||
var startInput = computed.startInput, pointLength = computed.pointLength; | ||
var deltaTime = computed.timestamp - startInput.timestamp; | ||
var maxPointLength = computed.maxPointLength, distance = computed.distance; | ||
return maxPointLength === _context.pointLength && | ||
0 === pointLength && | ||
_context.maxDistance >= distance && | ||
_context.maxPressTime > deltaTime; | ||
} | ||
default_1.prototype._isValidDistanceFromPrevTap = function (center) { | ||
if (void 0 !== this.prevTapPoint) { | ||
var distanceFromPreviousTap = getVLength({ x: center.x - this.prevTapPoint.x, y: center.y - this.prevTapPoint.y }); | ||
this.prevTapPoint = center; | ||
return this.options.maxDistanceFromPrevTap >= distanceFromPreviousTap; | ||
function _isValidInterval() { | ||
var now = performance.now(); | ||
if (void 0 === _prevTapTime) { | ||
_prevTapTime = now; | ||
return true; | ||
} | ||
else { | ||
this.prevTapPoint = center; | ||
return true; | ||
var interval = now - _prevTapTime; | ||
_prevTapTime = now; | ||
return interval < _context.waitNextTapTime; | ||
} | ||
}; | ||
default_1.prototype._isValidInterval = function () { | ||
var now = performance.now(); | ||
if (void 0 === this.prevTapTime) { | ||
this.prevTapTime = now; | ||
return true; | ||
} | ||
function _countDownToFail() { | ||
_countDownToFailTimer = setTimeout(function () { | ||
_context.status = RECOGNIZER_STATUS.FAILED; | ||
_reset(); | ||
}, _context.waitNextTapTime); | ||
} | ||
function _cancelCountDownToFail() { | ||
clearTimeout(_countDownToFailTimer); | ||
} | ||
function _reset() { | ||
_tapCount = 0; | ||
_prevTapPoint = void 0; | ||
_prevTapTime = void 0; | ||
} | ||
function _isValidDistanceFromPrevTap(center) { | ||
if (void 0 !== _prevTapPoint) { | ||
var distanceFromPreviousTap = getVLength({ x: center.x - _prevTapPoint.x, y: center.y - _prevTapPoint.y }); | ||
_prevTapPoint = center; | ||
return _context.maxDistanceFromPrevTap >= distanceFromPreviousTap; | ||
} | ||
else { | ||
var interval = now - this.prevTapTime; | ||
this.prevTapTime = now; | ||
return interval < this.options.waitNextTapTime; | ||
_prevTapPoint = center; | ||
return true; | ||
} | ||
}; | ||
default_1.prototype.recognize = function (input, emit) { | ||
var inputType = input.inputType, x = input.x, y = input.y; | ||
this.computed = this.compute([ComputeMaxLength, ComputeDistance], input); | ||
if (INPUT_END !== inputType) | ||
} | ||
function _recognize(computed, emit) { | ||
var stage = computed.stage, x = computed.x, y = computed.y; | ||
_context.status = RECOGNIZER_STATUS.POSSIBLE; | ||
if (STAGE.END !== stage) | ||
return; | ||
this.status = STATUS_POSSIBLE; | ||
if (this.test(input)) { | ||
this.cancelCountDownToFail(); | ||
if (this._isValidDistanceFromPrevTap({ x: x, y: y }) && this._isValidInterval()) { | ||
this.tapCount++; | ||
if (_test(computed)) { | ||
_cancelCountDownToFail(); | ||
if (_isValidDistanceFromPrevTap({ x: x, y: y }) && _isValidInterval()) { | ||
_tapCount++; | ||
} | ||
else { | ||
this.tapCount = 1; | ||
_tapCount = 1; | ||
} | ||
if (0 === this.tapCount % this.options.tapTimes) { | ||
this.status = STATUS_RECOGNIZED; | ||
emit(this.options.name, __assign(__assign({}, this.computed), { tapCount: this.tapCount })); | ||
this.reset(); | ||
if (0 === _tapCount % _context.tapTimes) { | ||
_context.status = RECOGNIZER_STATUS.RECOGNIZED; | ||
emit(_context.name, __assign(__assign({}, computed), { tapCount: _tapCount })); | ||
_reset(); | ||
} | ||
else { | ||
this.countDownToFail(); | ||
_countDownToFail(); | ||
} | ||
} | ||
else { | ||
this.reset(); | ||
this.status = STATUS_FAILED; | ||
_reset(); | ||
_context.status = RECOGNIZER_STATUS.FAILED; | ||
} | ||
}; | ||
default_1.prototype.countDownToFail = function () { | ||
var _this = this; | ||
this._countDownToFailTimer = setTimeout(function () { | ||
_this.status = STATUS_FAILED; | ||
_this.reset(); | ||
}, this.options.waitNextTapTime); | ||
}; | ||
default_1.prototype.cancelCountDownToFail = function () { | ||
clearTimeout(this._countDownToFailTimer); | ||
}; | ||
default_1.prototype.reset = function () { | ||
this.tapCount = 0; | ||
this.prevTapPoint = void 0; | ||
this.prevTapTime = void 0; | ||
}; | ||
default_1.prototype.test = function (input) { | ||
var startInput = input.startInput; | ||
var deltaTime = input.timestamp - startInput.timestamp; | ||
var _a = this.computed, maxPointLength = _a.maxPointLength, distance = _a.distance; | ||
return maxPointLength === this.options.pointLength && | ||
this.options.maxDistance >= distance && | ||
this.options.maxPressTime > deltaTime; | ||
}; | ||
return default_1; | ||
}(Recognizer)); | ||
} | ||
return [_context, _recognize, [ComputeDistance, ComputeMaxLength]]; | ||
} | ||
export default default_1; | ||
export default Tap; |
@@ -1,1 +0,1 @@ | ||
if (process.env.NODE_ENV === 'development') {module.exports = require('./index.dev.js');} else {module.exports = require('./index.prod.js');} | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var t,e=require("tslib"),a=require("@any-touch/shared"),n=require("@any-touch/vector"),i=require("@any-touch/compute"),r=(t=require("@any-touch/recognizer"))&&"object"==typeof t&&"default"in t?t.default:t,u={name:"tap",pointLength:1,tapTimes:1,waitNextTapTime:300,maxDistance:2,maxDistanceFromPrevTap:9,maxPressTime:250};exports.default=function(t){var o,s,m,c=r(u,t),p=0;function T(){p=0,o=void 0,s=void 0}return[c,function(t,i){var r=t.stage,u=t.x,x=t.y;c.status=a.RECOGNIZER_STATUS.POSSIBLE,a.STAGE.END===r&&(!function(t){var e=t.startInput,a=t.pointLength,n=t.timestamp-e.timestamp,i=t.maxPointLength,r=t.distance;return i===c.pointLength&&0===a&&c.maxDistance>=r&&c.maxPressTime>n}(t)?(T(),c.status=a.RECOGNIZER_STATUS.FAILED):(clearTimeout(m),function(t){if(void 0!==o){var e=n.getVLength({x:t.x-o.x,y:t.y-o.y});return o=t,c.maxDistanceFromPrevTap>=e}return o=t,!0}({x:u,y:x})&&function(){var t=performance.now();if(void 0===s)return s=t,!0;var e=t-s;return s=t,e<c.waitNextTapTime}()?p++:p=1,0==p%c.tapTimes?(c.status=a.RECOGNIZER_STATUS.RECOGNIZED,i(c.name,e.__assign(e.__assign({},t),{tapCount:p})),T()):m=setTimeout((function(){c.status=a.RECOGNIZER_STATUS.FAILED,T()}),c.waitNextTapTime)))},[i.ComputeDistance,i.ComputeMaxLength]]}; |
{ | ||
"name": "@any-touch/tap", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "any-touch的识别器, 用来识别点击手势.", | ||
@@ -14,6 +14,6 @@ "main": "./dist/index", | ||
"dependencies": { | ||
"@any-touch/compute": "^1.0.1", | ||
"@any-touch/recognizer": "^1.0.1", | ||
"@any-touch/shared": "^1.0.1", | ||
"@any-touch/vector": "^1.0.1" | ||
"@any-touch/compute": "^1.0.2", | ||
"@any-touch/recognizer": "^1.0.2", | ||
"@any-touch/shared": "^1.0.2", | ||
"@any-touch/vector": "^1.0.2" | ||
}, | ||
@@ -27,3 +27,3 @@ "files": [ | ||
"sideEffects": false, | ||
"gitHead": "daec688784b1b67c7e427a0b474deae8773f54e6" | ||
"gitHead": "a11a02a110bf20b6163b5b716b60b87de3b967da" | ||
} |
@@ -0,0 +0,0 @@ # @any-touch/tap |
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
1
7934
6
114
1
Updated@any-touch/compute@^1.0.2
Updated@any-touch/recognizer@^1.0.2
Updated@any-touch/shared@^1.0.2
Updated@any-touch/vector@^1.0.2