TASK:#109167 (feature)(bugfix)(improve)allow setOption dynamically & fix swipe trigger & optimize functional code
This commit is contained in:
parent
b3631c7965
commit
f64ace31c3
|
@ -138,6 +138,7 @@ export interface PinchEvent {
|
|||
* Event: holdstart/holdmove/holdend
|
||||
*/
|
||||
export interface HoldEvent {
|
||||
readonly touches?: TouchList // holdmove maybe needs
|
||||
readonly absolute?: {
|
||||
readonly dx: number
|
||||
readonly dy: number
|
||||
|
@ -270,15 +271,16 @@ type EmbededGestureHTMLElement = HTMLElement & {
|
|||
}
|
||||
|
||||
type GestureOptions = {
|
||||
panThreshold: number
|
||||
velocityThreshold: number
|
||||
get holdThreshold(): number
|
||||
set holdThreshold(t: number)
|
||||
get panThreshold(): number
|
||||
set panThreshold(t: number)
|
||||
get velocityThreshold(): number
|
||||
set velocityThreshold(t: number)
|
||||
}
|
||||
|
||||
const DEBUG = 0
|
||||
|
||||
const debug = (...args: any[]) => {
|
||||
DEBUG && console.log.call(null, ...args)
|
||||
}
|
||||
const debugInfo = (...args: any[]) => {
|
||||
DEBUG && console.info.call(null, ...args)
|
||||
}
|
||||
|
@ -321,6 +323,64 @@ const generateMidCoordinate = <T extends Touch>(
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 判定是否构成 swipe 行为
|
||||
*
|
||||
* 当手指抬起时发出 swipe 事件,报告以下内容:
|
||||
* 起点、重点、dx、dy、dt、vc 和 direction
|
||||
*
|
||||
* 轻扫行为的判定:
|
||||
* 1.常规向右滑动(判定存在向右 swipe 轻扫行为)
|
||||
* 条件:结束时方向同初始时方向一致
|
||||
* !------>
|
||||
* 2.向右滑动又折返一小段(判定不存在 swipe 轻扫行为)
|
||||
* 条件:结束时方向同初始时方向不一致,且折返距离小于在初始方向上移动的距离
|
||||
* !-------
|
||||
* <---|
|
||||
* 3.向右滑动又折返一大段(判定存在向左 swipe 轻扫行为)
|
||||
* 条件:结束时方向同初始时方向不一致,且折返距离大于在初始方向上移动的距离
|
||||
* !----
|
||||
* <------|
|
||||
* 4.其他方向(向左、向上、向下)同样按照1~3步推理
|
||||
* 5.向某个方向来回移动,只根据开始那一段和结束那一段进行判定,按照1~3步推理
|
||||
*/
|
||||
const checkIsSwipeAction = <D extends PanOrSwipeDirection, N extends number>(
|
||||
firstDirec: D,
|
||||
lastDirec: D,
|
||||
dx: N,
|
||||
dy: N
|
||||
): boolean => {
|
||||
if (lastDirec === firstDirec) return true
|
||||
else {
|
||||
switch (lastDirec) {
|
||||
case 'left':
|
||||
return dx < 0
|
||||
case 'right':
|
||||
return dx > 0
|
||||
case 'down':
|
||||
return dy > 0
|
||||
case 'up':
|
||||
return dy < 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否超出阈值
|
||||
*/
|
||||
const checkIfOverThreshold = (
|
||||
t1: Touch,
|
||||
g2: GestureCoordinate,
|
||||
threshold: number
|
||||
): boolean => {
|
||||
return (
|
||||
Math.abs(t1.screenX - g2.screenX) > threshold ||
|
||||
Math.abs(t1.screenY - g2.screenY) > threshold
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 距离计算函数
|
||||
*
|
||||
|
@ -332,6 +392,22 @@ const computeDistance = <T extends Touch>(t1: T, t2: T): number => {
|
|||
return Math.sqrt(deltaX * deltaX + deltaY * deltaY)
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算坐标点与原点间的方向夹角,返回夹角区间:[-180°,180°]。
|
||||
* 如:
|
||||
* 传入 (1,0),返回 0°
|
||||
* 传入 (1,1),返回 45°
|
||||
* 传入 (0,1),返回 90°
|
||||
* 传入 (1,-1),返回 135°
|
||||
* 传入 (0,-1),返回 180°
|
||||
* 传入 (-1,1),返回 -45°
|
||||
* 传入 (-1,0),返回 -90°
|
||||
* 传入 (-1,-1),返回 -135°
|
||||
* 传入 (-0,-1),返回 -180°
|
||||
*/
|
||||
const computeDirectionAngle = <T extends number>(dx: T, dy: T) =>
|
||||
(Math.atan2(dy, dx) * 180) / Math.PI
|
||||
|
||||
/**
|
||||
* 方向角计算函数
|
||||
*
|
||||
|
@ -340,10 +416,9 @@ const computeDistance = <T extends Touch>(t1: T, t2: T): number => {
|
|||
* 平面角区间: (-180, 180]
|
||||
*/
|
||||
const computeDirection = <T extends Touch>(t1: T, t2: T): number => {
|
||||
return (
|
||||
(Math.atan2(t2.screenY - t1.screenY, t2.screenX - t1.screenX) * 180) /
|
||||
Math.PI
|
||||
)
|
||||
const dx = t2.screenX - t1.screenX
|
||||
const dy = t2.screenY - t1.screenY
|
||||
return computeDirectionAngle(dx, dy)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -373,15 +448,20 @@ const computeDirectionFromAngle = (angle: number): PanOrSwipeDirection => {
|
|||
}
|
||||
}
|
||||
|
||||
const computeDirectionFromDxDy = (
|
||||
dx: number,
|
||||
dy: number
|
||||
): [number, PanOrSwipeDirection] => {
|
||||
// angle 是一个正的角度数,从x轴正方向开始,顺时针递增
|
||||
let angle = (Math.atan2(dy, dx) * 180) / Math.PI
|
||||
/**
|
||||
* 计算触摸点的运动方向
|
||||
*/
|
||||
const computeTouchDirection = <T extends GestureCoordinate>(
|
||||
g1: T,
|
||||
g2: T
|
||||
): [PanOrSwipeDirection, number, number, number] => {
|
||||
const dx = g2.screenX - g1.screenX
|
||||
const dy = g2.screenY - g1.screenY
|
||||
|
||||
let angle = computeDirectionAngle(dx, dy)
|
||||
if (angle < 0) angle += 360
|
||||
|
||||
return [angle, computeDirectionFromAngle(angle)]
|
||||
return [computeDirectionFromAngle(angle), angle, dx, dy]
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -397,19 +477,14 @@ const getTouchFromTouches = (
|
|||
})[0]
|
||||
}
|
||||
|
||||
/**
|
||||
* 思路:传入要监听的元素,要监听的事件,
|
||||
*
|
||||
* 用法:
|
||||
* const myel = document.body;
|
||||
* const myGestureFrame = new GestureDector(myel);
|
||||
* myel.addEventListener('tap', (e) => debug(e))
|
||||
*
|
||||
*/
|
||||
export default class GestureDector {
|
||||
// 进入长按状态的阈值
|
||||
static HOLD_THRESHOLD = 500
|
||||
|
||||
// 进入滑动状态的阈值
|
||||
static PAN_THRESHOLD = 20
|
||||
|
||||
// 识别swipe事件所需的最小速度,单位为px/ms
|
||||
// 判定是swipe事件的速度阈值,单位: px/ms
|
||||
static VELOCITY_THRESHOLD = 0.3
|
||||
|
||||
static THRESHOLD_SMOOTHING = 0.9
|
||||
|
@ -418,42 +493,61 @@ export default class GestureDector {
|
|||
|
||||
// 连续两次点触(双击或三击)允许的x和y坐标的最大偏移量
|
||||
static DOUBLE_TAP_DISTANCE = 50
|
||||
// 连续两次点触(双击或三击)允许的最大间隔时间
|
||||
static DOUBLE_TAP_TIME = 500
|
||||
|
||||
// 进入长按状态的阈值
|
||||
static HOLD_INTERVAL = 1000
|
||||
// 连续两次点触(双击或三击)允许的最大间隔时间
|
||||
static DOUBLE_TAP_TIME = 300
|
||||
|
||||
// scale 触发阈值, 单位: px
|
||||
static SCALE_THRESHOLD = 20
|
||||
|
||||
// rotate 触发阈值, 单位: 度°
|
||||
static ROTATE_THRESHOLD = 22.5
|
||||
|
||||
// _options 是 option 的备份,用于重置
|
||||
_options!: GestureOptions | null
|
||||
|
||||
options!: GestureOptions
|
||||
|
||||
target!: HTMLElement
|
||||
element: HTMLElement
|
||||
state: FSMGestureState
|
||||
|
||||
/* 触摸坐标 */
|
||||
// 开始触摸点
|
||||
start!: GestureCoordinate
|
||||
|
||||
// 最后一次触摸点,注意:最后一次的touchmove和touchend的触摸点相同
|
||||
last!: GestureCoordinate
|
||||
|
||||
// 最后一次的上一次触摸点,用于实时计算临近坐标点的方向夹角
|
||||
lastlast!: GestureCoordinate
|
||||
|
||||
// 开始 pan 的触摸点,用于区分第1指和第2指的 start
|
||||
panstart!: GestureCoordinate
|
||||
|
||||
// 结束 pan 的触摸点,用于区分第1指和第2指的 last
|
||||
panlast!: GestureCoordinate
|
||||
|
||||
// 用于 doubletap
|
||||
lastTap: GestureCoordinate | null = null
|
||||
|
||||
firstTapTouches: TouchList | null = null
|
||||
|
||||
// 用于 tripletap
|
||||
lastlastTap: GestureCoordinate | null = null
|
||||
|
||||
secondTapTouches: TouchList | null = null
|
||||
|
||||
// x轴、y轴方向上的速度及合成速度
|
||||
// 单位: px/ms
|
||||
// x轴、y轴方向上的速度及合成速度,单位: px/ms
|
||||
vx!: number
|
||||
vy!: number
|
||||
vc!: number
|
||||
|
||||
// 刚进入 hold 状态的指示值
|
||||
justEnteredHoldState = false
|
||||
|
||||
// 已进入 pan 状态的指示值
|
||||
hasEnteredPanState = false
|
||||
|
||||
private touch1ID: Touch['identifier'] = -1
|
||||
private touch2ID: Touch['identifier'] = -1
|
||||
private lastPanTouchID: Touch['identifier'] = -1
|
||||
|
@ -480,16 +574,21 @@ export default class GestureDector {
|
|||
|
||||
angle!: number
|
||||
|
||||
// 当前 pan/swipe 状态下事件的方向指向
|
||||
direction!: PanOrSwipeDirection
|
||||
// 当前 pan/swipe 状态下首次出现的方向指向
|
||||
firstDirection: PanOrSwipeDirection | null = null
|
||||
|
||||
constructor(el: HTMLElement, options?: GestureOptions) {
|
||||
debug(el)
|
||||
constructor(el: HTMLElement, options?: Partial<GestureOptions>) {
|
||||
this.element = el
|
||||
this.options = options || {
|
||||
panThreshold: GestureDector.PAN_THRESHOLD,
|
||||
velocityThreshold: GestureDector.VELOCITY_THRESHOLD,
|
||||
this.options = {
|
||||
...{
|
||||
holdThreshold: GestureDector.HOLD_THRESHOLD,
|
||||
panThreshold: GestureDector.PAN_THRESHOLD,
|
||||
velocityThreshold: GestureDector.VELOCITY_THRESHOLD,
|
||||
},
|
||||
...options,
|
||||
}
|
||||
|
||||
this.state = this.initialState
|
||||
}
|
||||
|
||||
|
@ -551,7 +650,7 @@ export default class GestureDector {
|
|||
this.start = this.last = generateCoordinate(evt.timeStamp, touch)
|
||||
|
||||
if (this.getSeriesEvent('hold').length > 0) {
|
||||
this.startTimer('holdtimeout', GestureDector.HOLD_INTERVAL)
|
||||
this.startTimer('holdtimeout', this.options.holdThreshold)
|
||||
}
|
||||
},
|
||||
touchstart: (evt, touch) => {
|
||||
|
@ -880,9 +979,6 @@ export default class GestureDector {
|
|||
*
|
||||
* TODO: 考虑运动偏移量
|
||||
*/
|
||||
justEnteredHoldState = false
|
||||
hasEnteredPanState = false
|
||||
|
||||
private holdState: FSMGestureState = {
|
||||
name: 'holdState',
|
||||
init: () => {
|
||||
|
@ -915,12 +1011,12 @@ export default class GestureDector {
|
|||
this.getSeriesEvent('swipe').length ||
|
||||
this.getSeriesEvent('pan').length
|
||||
) {
|
||||
const touch = evt.touches[1]
|
||||
if (
|
||||
Math.abs(touch.screenX - this.start.screenX) >
|
||||
this.options.panThreshold ||
|
||||
Math.abs(touch.screenY - this.start.screenY) >
|
||||
checkIfOverThreshold(
|
||||
evt.touches[1],
|
||||
this.start,
|
||||
this.options.panThreshold
|
||||
)
|
||||
) {
|
||||
this.panState.touchmove?.(evt, evt.touches[1])
|
||||
}
|
||||
|
@ -935,6 +1031,7 @@ export default class GestureDector {
|
|||
this.emitEvent(
|
||||
'holdmove',
|
||||
Object.freeze({
|
||||
touches: evt.changedTouches,
|
||||
absolute: {
|
||||
dx: current.screenX - this.start.screenX,
|
||||
dy: current.screenY - this.start.screenY,
|
||||
|
@ -1040,11 +1137,15 @@ export default class GestureDector {
|
|||
if (touch?.identifier !== this.lastPanTouchID) return
|
||||
|
||||
const current = generateCoordinate(evt.timeStamp, touch)
|
||||
if (this.listenEvents.has('panmove')) {
|
||||
const dx = current.screenX - this.panstart.screenX
|
||||
const dy = current.screenY - this.panstart.screenY
|
||||
const [_, direction] = computeDirectionFromDxDy(dx, dy)
|
||||
const [direction] = computeTouchDirection(this.panstart, current)
|
||||
|
||||
// 更新 lastlast 值,用于触摸点间实时比对
|
||||
this.lastlast = this.last
|
||||
if (this.firstDirection === null) {
|
||||
this.firstDirection = direction
|
||||
}
|
||||
|
||||
if (this.listenEvents.has('panmove')) {
|
||||
this.emitEvent(
|
||||
'panmove',
|
||||
Object.freeze({
|
||||
|
@ -1100,12 +1201,11 @@ export default class GestureDector {
|
|||
// 检测是否是第二指
|
||||
const isSecondFinger = touch.identifier === 1
|
||||
|
||||
// 当手指抬起时发出 swipe 事件
|
||||
// 事件中报告 起点、重点、dx、dy、dt、速度和方向
|
||||
const current = generateCoordinate(evt.timeStamp, touch)
|
||||
const dx = current.screenX - this.panstart.screenX
|
||||
const dy = current.screenY - this.panstart.screenY
|
||||
const [angle, direction] = computeDirectionFromDxDy(dx, dy)
|
||||
// touchend 中传入的 touch 和最后一次 touchmove 的 touch 触摸点是相同的
|
||||
const [direction, angle, dx, dy] = computeTouchDirection(
|
||||
this.panstart,
|
||||
this.last
|
||||
)
|
||||
|
||||
if (this.listenEvents.has('panend')) {
|
||||
this.emitEvent(
|
||||
|
@ -1144,8 +1244,11 @@ export default class GestureDector {
|
|||
}
|
||||
})
|
||||
|
||||
// 作用域暂存
|
||||
const firstDirection = this.firstDirection
|
||||
// 清理资源
|
||||
this.lastPanTouchID = -1
|
||||
this.firstDirection = null
|
||||
|
||||
// 如果检测到是第2指,提前退出
|
||||
if (isSecondFinger) {
|
||||
|
@ -1165,12 +1268,23 @@ export default class GestureDector {
|
|||
this.getSeriesEvent('swipe').length &&
|
||||
this.vc > this.options.velocityThreshold
|
||||
) {
|
||||
this.angle = angle
|
||||
this.direction = direction
|
||||
this.switchTo(this.swipeState, evt, touch)
|
||||
} else {
|
||||
this.switchTo(this.initialState)
|
||||
// currentDirection 代表触摸点间的实时运动方向
|
||||
const [currentDirection] = computeTouchDirection(
|
||||
this.lastlast,
|
||||
this.last
|
||||
)
|
||||
if (
|
||||
firstDirection &&
|
||||
checkIsSwipeAction(firstDirection, currentDirection, dx, dy)
|
||||
) {
|
||||
this.angle = angle
|
||||
this.direction = direction
|
||||
this.switchTo(this.swipeState, evt, touch)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
this.switchTo(this.initialState)
|
||||
},
|
||||
touchcancel: null,
|
||||
}
|
||||
|
@ -1360,12 +1474,10 @@ export default class GestureDector {
|
|||
private emitEvent(
|
||||
type: GestureEventType,
|
||||
detail?: GestureEventTypeDetail<GestureEventType>
|
||||
): void {
|
||||
if (this.target === undefined) {
|
||||
console.error('Attempt to emit event with no target')
|
||||
return
|
||||
}
|
||||
// debug(type, this.target)
|
||||
) {
|
||||
if (this.target === undefined)
|
||||
throw new Error('Attempt to emit event with no target')
|
||||
|
||||
this.target.dispatchEvent(
|
||||
new CustomEvent(type, {
|
||||
bubbles: true,
|
||||
|
@ -1427,6 +1539,33 @@ export default class GestureDector {
|
|||
// 使用 weakmap 默认的引用计数来清理
|
||||
}
|
||||
|
||||
/**
|
||||
* 在 GestureDector 运行时可传入可选项参数,即动态修改一些手势状态的阈值
|
||||
*
|
||||
* 设置新的 option 时,会转存当前运行初始设置的 options,用于未来重置
|
||||
*/
|
||||
public setOption(option: keyof GestureOptions, value: number) {
|
||||
if (!this.options.hasOwnProperty(option)) throw new Error('禁止设置该参数')
|
||||
this._options = this._options || this.options
|
||||
this.options = {...this.options, ...{[option]: value}}
|
||||
}
|
||||
|
||||
/**
|
||||
* 与上方 setOption 相对应,取消动态传入的参数,使用运行时初始设定的参数
|
||||
*
|
||||
* 传入 option 时,可重置单个 option
|
||||
* 未传入 option,则重置所有 options
|
||||
*/
|
||||
public unsetOption(option?: keyof GestureOptions) {
|
||||
if (this._options === null) throw new Error('不存在该参数')
|
||||
if (option) {
|
||||
this.options[option] = this._options[option]
|
||||
} else {
|
||||
this.options = this._options || this.options
|
||||
this._options = null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory Function
|
||||
*
|
||||
|
|
|
@ -11,51 +11,56 @@ export class PanelTestMultiTouches extends StarBaseElement {
|
|||
super()
|
||||
this.startGestureDetector()
|
||||
this.updateComplete.then(() => {
|
||||
const log = (e: Event) => console.log(e.type)
|
||||
const preventContextMenu = (e: Event) => {
|
||||
e.stopImmediatePropagation()
|
||||
if (navigator.vendor === 'Google Inc.') {
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
|
||||
this.holdtapButton.startGestureDetector()
|
||||
this.holdpanButton.startGestureDetector()
|
||||
this.holdswipeButton.startGestureDetector()
|
||||
this.holdallButton.startGestureDetector()
|
||||
|
||||
this.holdtapButton.addEventListener('contextmenu', preventContextMenu)
|
||||
this.holdpanButton.addEventListener('contextmenu', preventContextMenu)
|
||||
this.holdswipeButton.addEventListener('contextmenu', preventContextMenu)
|
||||
this.holdallButton.addEventListener('contextmenu', preventContextMenu)
|
||||
this.holdtapButton.addEventListener('contextmenu', this)
|
||||
this.holdpanButton.addEventListener('contextmenu', this)
|
||||
this.holdswipeButton.addEventListener('contextmenu', this)
|
||||
this.holdallButton.addEventListener('contextmenu', this)
|
||||
|
||||
this.holdtapButton.addEventListener('holdstart', log)
|
||||
this.holdtapButton.addEventListener('holdmove', log)
|
||||
this.holdtapButton.addEventListener('holdend', log)
|
||||
this.holdtapButton.addEventListener('tap', log)
|
||||
this.holdtapButton.addEventListener('holdstart', this)
|
||||
this.holdtapButton.addEventListener('holdmove', this)
|
||||
this.holdtapButton.addEventListener('holdend', this)
|
||||
this.holdtapButton.addEventListener('tap', this)
|
||||
|
||||
this.holdpanButton.addEventListener('holdstart', log)
|
||||
this.holdpanButton.addEventListener('holdmove', log)
|
||||
this.holdpanButton.addEventListener('holdend', log)
|
||||
this.holdpanButton.addEventListener('panleft', log)
|
||||
this.holdpanButton.addEventListener('panright', log)
|
||||
this.holdpanButton.addEventListener('holdstart', this)
|
||||
this.holdpanButton.addEventListener('holdmove', this)
|
||||
this.holdpanButton.addEventListener('holdend', this)
|
||||
this.holdpanButton.addEventListener('panleft', this)
|
||||
this.holdpanButton.addEventListener('panright', this)
|
||||
|
||||
this.holdswipeButton.addEventListener('holdstart', log)
|
||||
this.holdswipeButton.addEventListener('holdmove', log)
|
||||
this.holdswipeButton.addEventListener('holdend', log)
|
||||
this.holdswipeButton.addEventListener('swipeleft', log)
|
||||
this.holdswipeButton.addEventListener('swiperight', log)
|
||||
this.holdswipeButton.addEventListener('holdstart', this)
|
||||
this.holdswipeButton.addEventListener('holdmove', this)
|
||||
this.holdswipeButton.addEventListener('holdend', this)
|
||||
this.holdswipeButton.addEventListener('swipeleft', this)
|
||||
this.holdswipeButton.addEventListener('swiperight', this)
|
||||
|
||||
this.holdallButton.addEventListener('holdstart', log)
|
||||
this.holdallButton.addEventListener('holdmove', log)
|
||||
this.holdallButton.addEventListener('holdend', log)
|
||||
this.holdallButton.addEventListener('panleft', log)
|
||||
this.holdallButton.addEventListener('panright', log)
|
||||
this.holdallButton.addEventListener('swipeleft', log)
|
||||
this.holdallButton.addEventListener('swiperight', log)
|
||||
this.holdallButton.addEventListener('holdstart', this)
|
||||
this.holdallButton.addEventListener('holdmove', this)
|
||||
this.holdallButton.addEventListener('holdend', this)
|
||||
this.holdallButton.addEventListener('panleft', this)
|
||||
this.holdallButton.addEventListener('panright', this)
|
||||
this.holdallButton.addEventListener('swipeleft', this)
|
||||
this.holdallButton.addEventListener('swiperight', this)
|
||||
})
|
||||
}
|
||||
|
||||
handleEvent(e: Event) {
|
||||
switch (e.type) {
|
||||
case 'contextmenu':
|
||||
e.stopImmediatePropagation()
|
||||
if (navigator.vendor === 'Google Inc.') {
|
||||
e.preventDefault()
|
||||
}
|
||||
break
|
||||
default:
|
||||
console.log(e.type)
|
||||
}
|
||||
}
|
||||
|
||||
@query('#holdtap') holdtapButton!: StarButton
|
||||
@query('#holdpan') holdpanButton!: StarButton
|
||||
@query('#holdswipe') holdswipeButton!: StarButton
|
||||
|
|
|
@ -11,24 +11,20 @@ export class PanelTestPan extends StarBaseElement {
|
|||
super()
|
||||
this.startGestureDetector()
|
||||
this.updateComplete.then(() => {
|
||||
const log = (e: Event) => console.log(e.type)
|
||||
|
||||
this.panlifecycleButton.startGestureDetector()
|
||||
this.panalldirectionButton.startGestureDetector()
|
||||
this.pansingledirectionButton.startGestureDetector()
|
||||
|
||||
this.panlifecycleButton.addEventListener('panstart', log)
|
||||
this.panlifecycleButton.addEventListener('panmove', log)
|
||||
this.panlifecycleButton.addEventListener('panend', log)
|
||||
this.panlifecycleButton.addEventListener('panstart', this)
|
||||
this.panlifecycleButton.addEventListener('panmove', this)
|
||||
this.panlifecycleButton.addEventListener('panend', this)
|
||||
|
||||
this.panalldirectionButton.addEventListener('pan', (e: Event) =>
|
||||
console.log(e)
|
||||
)
|
||||
this.panalldirectionButton.addEventListener('pan', this)
|
||||
|
||||
this.pansingledirectionButton.addEventListener('panleft', log)
|
||||
this.pansingledirectionButton.addEventListener('panright', log)
|
||||
this.pansingledirectionButton.addEventListener('pandown', log)
|
||||
this.pansingledirectionButton.addEventListener('panup', log)
|
||||
this.pansingledirectionButton.addEventListener('panleft', this)
|
||||
this.pansingledirectionButton.addEventListener('panright', this)
|
||||
this.pansingledirectionButton.addEventListener('pandown', this)
|
||||
this.pansingledirectionButton.addEventListener('panup', this)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -37,7 +33,7 @@ export class PanelTestPan extends StarBaseElement {
|
|||
@query('#pansingledirection') pansingledirectionButton!: StarButton
|
||||
|
||||
handleEvent(e: Event) {
|
||||
console.log(e)
|
||||
console.log(e.type)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
import {html, css, CSSResultArray} from 'lit'
|
||||
import {customElement, query} from 'lit/decorators.js'
|
||||
import {sharedStyles} from './shared-styles'
|
||||
import {StarBaseElement} from '../../../../components/base/star-base-element'
|
||||
import {StarButton} from '../../../../components/button/button'
|
||||
import {UlType} from '../../../../components/ul/ul'
|
||||
|
||||
@customElement('panel-test-swipe')
|
||||
export class PanelTestSwipe extends StarBaseElement {
|
||||
constructor() {
|
||||
super()
|
||||
this.startGestureDetector()
|
||||
|
||||
this.updateComplete.then(() => {
|
||||
this.swipeLeftRightButton.startGestureDetector()
|
||||
this.swipeUpDownButton.startGestureDetector()
|
||||
this.swipeAllButton.startGestureDetector()
|
||||
this.swipeTestButton.startGestureDetector()
|
||||
|
||||
this.swipeLeftRightButton.addEventListener('swipeleft', this)
|
||||
this.swipeLeftRightButton.addEventListener('swiperight', this)
|
||||
|
||||
this.swipeUpDownButton.addEventListener('swipeup', this)
|
||||
this.swipeUpDownButton.addEventListener('swipedown', this)
|
||||
|
||||
this.swipeAllButton.addEventListener('swipeleft', this)
|
||||
this.swipeAllButton.addEventListener('swiperight', this)
|
||||
this.swipeAllButton.addEventListener('swipeup', this)
|
||||
this.swipeAllButton.addEventListener('swipedown', this)
|
||||
|
||||
this.swipeTestButton.addEventListener('swipeleft', this)
|
||||
this.swipeTestButton.addEventListener('swiperight', this)
|
||||
this.swipeTestButton.addEventListener('swipeup', this)
|
||||
this.swipeTestButton.addEventListener('swipedown', this)
|
||||
})
|
||||
}
|
||||
|
||||
@query('#swipeLeftRight') swipeLeftRightButton!: StarButton
|
||||
@query('#swipeUpDown') swipeUpDownButton!: StarButton
|
||||
@query('#swipeAll') swipeAllButton!: StarButton
|
||||
@query('#swipeTest') swipeTestButton!: StarButton
|
||||
|
||||
handleEvent(e: Event) {
|
||||
console.log(e.type)
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<star-ul type=${UlType.BASE}>
|
||||
<star-button id="swipeLeftRight" label="左右轻扫"></star-button>
|
||||
<hr />
|
||||
<star-button id="swipeUpDown" label="上下轻扫"></star-button>
|
||||
<hr />
|
||||
<star-button id="swipeAll" label="上下左右轻扫"></star-button>
|
||||
<hr />
|
||||
<star-button
|
||||
id="swipeTest"
|
||||
label="向右轻扫再折返一小段/一大段, 观察this)"
|
||||
></star-button>
|
||||
</star-ul>
|
||||
`
|
||||
}
|
||||
|
||||
public static override get styles(): CSSResultArray {
|
||||
return [
|
||||
sharedStyles,
|
||||
css`
|
||||
star-button {
|
||||
height: 20vh;
|
||||
}
|
||||
`,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'panel-test-swipe': PanelTestSwipe
|
||||
}
|
||||
}
|
|
@ -16,9 +16,9 @@ export class PanelTestTap extends StarBaseElement {
|
|||
this.doubletapButton.startGestureDetector()
|
||||
this.tripletapButton.startGestureDetector()
|
||||
|
||||
this.tapButton.addEventListener('tap', (e) => alert(e.type))
|
||||
this.doubletapButton.addEventListener('doubletap', (e) => alert(e.type))
|
||||
this.tripletapButton.addEventListener('tripletap', (e) => alert(e.type))
|
||||
this.tapButton.addEventListener('tap', this)
|
||||
this.doubletapButton.addEventListener('doubletap', this)
|
||||
this.tripletapButton.addEventListener('tripletap', this)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ export class PanelTestTap extends StarBaseElement {
|
|||
|
||||
handleEvent(e: Event) {
|
||||
console.log(e.type, (e as GestureEvent<'tap'>).detail.start)
|
||||
alert(e.type)
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
|
@ -6,6 +6,7 @@ import {sharedStyles} from '../shared-styles'
|
|||
|
||||
import './examples/test-tap'
|
||||
import './examples/test-pan'
|
||||
import './examples/test-swipe'
|
||||
import './examples/test-multitouches'
|
||||
|
||||
@customElement('panel-gesture')
|
||||
|
@ -25,6 +26,12 @@ export class PanelGesture extends LitElement {
|
|||
href="#test-pan"
|
||||
></star-li>
|
||||
<hr />
|
||||
<star-li
|
||||
type=${LiType.ONLY_LABEL}
|
||||
label="swipe轻扫"
|
||||
href="#test-swipe"
|
||||
></star-li>
|
||||
<hr />
|
||||
<star-li
|
||||
type=${LiType.ONLY_LABEL}
|
||||
label="手指组合"
|
||||
|
|
Loading…
Reference in New Issue