0.1.1 • Published 11 months ago
@ura-web-libs/gesture-detector v0.1.1
手势检测库
用途: 手势框架监听实例化时传入元素上的触摸事件,通过分析生成支持单指和双指
支持的事件:
- 转换(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
)
0.1.1
11 months ago