@ura-web-libs/gesture-detector
v0.1.1
Published
用途: 手势框架监听实例化时传入元素上的触摸事件,通过分析生成支持单指和双指
Downloads
2
Readme
手势检测库
用途: 手势框架监听实例化时传入元素上的触摸事件,通过分析生成支持单指和双指
支持的事件:
- 转换(transform) 双指捏合手势, 用于放缩和旋转
使用方法
1.在普通 HTMLElement 上使用 GestureDetector 的方法:
import GestureDetector from '@ura-web-libs/gesture-detector'
const myElement = document.querySelector('#myel')
GestureDetector.embedded(myElement)
myElement.addEventListener('tap', function () {})
myElement.addEventListener('doubletap', function () {}, {once: true})2.在 UraBaseElement 派生类上使用 GestureDetector 的方法:
class MyElement extends UraBaseElement {
constructor() {
super()
this.startGestureDetector()
this.addEventListener('tap', function () {})
this.addEventListener('doubletap', function () {}, {once: true})
}
}事件支持
| 事件名称 | 事件意义 | 输入类型 | 最少手指数 | 最多手指数 | 备注 | | ------------------- | ------------ | -------- | ---------- | ---------- | -------------------------- | | tap | 轻触 | 离散 | 1 | 2 | 类似单击事件(click) | | doubletap | 双指轻触 | 离散 | 2 | 3 | 类似双击事件(dbclick) | | tripletap | 三指轻触 | 离散 | 3 | 3 | 类似三击事件(triclick) | | holdstart | 长按开始 | 连续 | 1 | 2 | | holdmove | 长按移动 | 连续 | 1 | 2 | | holdend | 长按结束 | 连续 | 1 | 2 | | panstart | 平移开始 | 连续 | 1 | 2 | | panmove | 平移移动 | 连续 | 1 | 2 | | panend | 平移结束 | 连续 | 1 | 2 | | pan | 平移结束 | 连续 | 1 | 2 | | panleft | 平移结束向左 | 连续 | 1 | 2 | | panright | 平移结束向右 | 连续 | 1 | 2 | | pandown | 平移结束向下 | 连续 | 1 | 2 | | panup | 平移结束向上 | 连续 | 1 | 2 | | swipe | 轻扫 | 离散 | 1 | 1 | 在平移结束时释放手指那一刻 | | swipeleft | 向左轻扫 | 离散 | 1 | 1 | | swiperight | 向右轻扫 | 离散 | 1 | 1 | | swipedown | 向下轻扫 | 离散 | 1 | 1 | | swipeup | 向上轻扫 | 离散 | 1 | 1 | | (TODO)screenedgepan | 屏幕边缘平移 | 连续 | | (TODO)twopans | 双指平移 | 连续 | 2 | 2 | | (TODO)threepans | 三指平移 | 连续 | 2 | 2 | | (TODO)pinch | 捏合 | 连续 | 2 | 2 | | (TODO)rotate | 旋转 | 连续 | 2 | 2 |
| 第一指 | 第二指 | 组合事件场景 | | -------- | --------- | ------------------------------------------ | | holdmove | tap | 长按拖拽应用图标+点按进入文件夹/退出文件夹 | | holdmove | swipe/pan | 长按拖拽应用图标+翻页 |
| 参数名 | 类型 | 作用 | | ------- | ----------- | ----------------------------------------------------------------- | | once | boolean | 添加事件单次监听,在执行一次回调后删除监听 | | passive | boolean | 在监听回调调用 preventDefault() 时使其无效。(可用于改善滚屏性能) | | signal | AbortSignal | 在中止信号 AbortSignal 的 abort() 方法被调用时,移除监听器 | | capture | boolean | 监听器将在事件捕获阶段传播到该 EventTarget 时触发 |
手势检测状态机(Gesture Detector Finite State Machine)
| 当前状态 →条件 ↓ | initialState | touchStartedState | touchesStartedState | holdState | panState | swipeState | transformstate | | ---------------------------------- | ----------------- | ------------------- | ---------------------- | ------------ | ---------- | ------------ | -------------- | | 收到 touchstart | touchStartedState | | 收到 touchstart 且触摸点=1 | | initialState | | 收到 touchstart 且触摸点>1 | | touchesStartedState | | 收到 touchstart 且判定进行捏 | | | transformstate(pinch) | | 收到 touchstart 且判定进行旋转 | | | transformstate(rotate) | | 收到 touchstart 且判定进行平移 | | | panState | | 收到 touchmove 且移动差值>平移阈值 | | panState | | 收到 touchend | | initialState | | initialState | swipeState | initialState | initialState | | hold 超时完成 | | holdState |
手势事件(Gesture Events)
TapEvent
- definition: one or 2 fingers press, lift
- Usage: Select / Zoom in
- Event: tap
- Interface
Interface TapEvent {
readonly attribute TouchList touches;
readonly attribute long fingers; // only support 1 and 2
}PanEvent
- Definition: One or 2 fingers press, move, lift
- Usage: Dismiss, scroll, tilt / select multiple items, pan, tilt
- Event: panstart/panmove/panend
- Interface
Interface PanEvent {
readonly attribute TouchList startTouches;
readonly attribute TouchList endTouches;
readonly attribute TouchList movingTouches;
readonly attribute long fingers; // only support 1 and 2
}SwipeEvent
- Definition: One fingers press, move quickly, lift
- Usage: Dismiss, scroll, tilt / select multiple items, pan, tilt
- Event: swipestart/swipemove/swipeend
- Interface
Interface SwipeEvent {
readonly attribute Touch startTouch;
readonly attribute Touch endTouch;
readonly attribute double velocity;
Readonly attribute double direction;
}PinchEvent
- Definition: Two fingers press, move in/outwards, lift
- Usage: Zoom in/out
- Event: pinchstart/pinchmove/pinchend
- Interface
Interface Enum PinchZoom {
IN,
OUT
}
Interface PinchEvent {
readonly attribute TouchList startTouches;
readonly attribute TouchList endTouches;
readonly attribute double scale;
readonly attribute enum PinchZoom zoom;
}LongPressEvent
- Definition: One or 2 fingers press, wait, lift
- Usage: Select an element,
- Event: longpress
- Interface
Interface LongPressEvent {
readonly attribute TouchList pressTouches;
readonly attribute long fingers; // only support 1 and 2
}DoubleTapEvent
- Definition: One or 2 fingers press, lift, one or 2 fingers press, lift
- Usage: Selection / Context menu
- Event: doubletap
- Interface
Interface DoubleTapEvent {
readonly attribute TouchList firstTapTouches;
readonly attribute TouchList secondTapTouches;
readonly attribute long fingers; // only support 1 and 2
}RotateEvent
- Definition: 2 fingers press, simultaneously orbit both fingers around the center point, lift.
- Usage: Rotate content, a picture or a map.
- Event: rotatestart/rotatemove/rotateend
- Interface
Interface RotateEvent {
readonly attribute TouchList startTouches;
readonly attribute TouchList endTouches;
readonly attribute TouchList rotatingTouches;
readonly attribute double degree;
}/* Using the this keyword to access the element property of the current object. */
// this.element.addEventListener = new Proxy(this.element.addEventListener, {
// set(target: any, _: any, val: any) {
// debug(target, _, val)
// // if (typeof val == 'object') {
// // target.push(val)
// // if (target.length > 10) target.shift()
// // }
// return true
// },
// get(target, prop: any, _) {
// debug(target, _, prop)
// return target[prop]
// },
// })注意
/**
* Chrome 上调用 e.preventDedault() 可阻止右键菜单弹出,同时不会影响
* 正常 touch 事件的分发。
*
* Firefox 上调用 e.preventDedault() 可阻止右键菜单弹出,但会中断 touch 事件,
* 表现为:长按(touchstart),中断,手抬起再按(touchmove)
*****
* 测试长按事件时,请使用终端设备或Chrome
*/
this.addEventListener(
'contextmenu',
(e) => {
e.stopImmediatePropagation()
if (navigator.vendor === 'Google Inc.') {
e.preventDefault()
}
},
true
)