mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-20 20:21:20 -08:00
refactor(core): CORE-17 type input events and own interaction lifetimes
This commit is contained in:
1 parent
88aef830df
commit
a842058136
72 files changed
+31156
-1219
No files matched your search
@@ -0,0 +1,94 @@
|
||||
import type { Drag, GestureHost } from './gesture-types'
|
||||
import { setCurrentTime } from '../control/progress/position'
|
||||
import { getScope, isClosing } from '../lifecycle/instance'
|
||||
import { captureSource } from '../source/operation'
|
||||
import { clamp, secondToTime } from '../utils'
|
||||
import { slideDirection } from './gesture-direction'
|
||||
|
||||
export function gestureController(art: GestureHost) {
|
||||
let drag: Drag | undefined
|
||||
const cancel = () => {
|
||||
drag = undefined
|
||||
}
|
||||
const active = (current: Drag) => drag === current && !isClosing(art) && !art.isLock
|
||||
&& !art.option.isLive && art.isRotate === current.rotated && current.sourceActive()
|
||||
const onLock = (locked: boolean) => {
|
||||
if (locked)
|
||||
cancel()
|
||||
}
|
||||
art.on('document:touchend', cancel)
|
||||
art.on('document:touchcancel', cancel)
|
||||
art.on('lock', onLock)
|
||||
getScope(art).add(() => {
|
||||
cancel()
|
||||
art.off('document:touchend', cancel)
|
||||
art.off('document:touchcancel', cancel)
|
||||
art.off('lock', onLock)
|
||||
})
|
||||
|
||||
const start = (target: EventTarget, event: TouchEvent) => {
|
||||
cancel()
|
||||
const touch = event.touches[0]
|
||||
if (isClosing(art) || art.isLock || art.option.isLive || event.touches.length !== 1 || !touch)
|
||||
return
|
||||
if (![touch.pageX, touch.pageY, touch.clientX, touch.clientY, art.currentTime].every(Number.isFinite))
|
||||
return
|
||||
const current: Drag = {
|
||||
target,
|
||||
identifier: touch.identifier,
|
||||
x: touch.pageX,
|
||||
y: touch.pageY,
|
||||
time: art.currentTime,
|
||||
rotated: art.isRotate,
|
||||
sourceActive: captureSource(art),
|
||||
}
|
||||
drag = current
|
||||
if (target === art.template.$progress) {
|
||||
const size = art.isRotate ? art.height : art.template.$progress.clientWidth
|
||||
if (!Number.isFinite(size) || size <= 0 || !Number.isFinite(art.duration) || art.duration <= 0) {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
try {
|
||||
setCurrentTime(art, event, () => active(current))
|
||||
}
|
||||
catch (error) {
|
||||
if (drag === current)
|
||||
cancel()
|
||||
throw error
|
||||
}
|
||||
if (active(current))
|
||||
current.time = art.currentTime
|
||||
}
|
||||
}
|
||||
|
||||
const move = (event: TouchEvent) => {
|
||||
const current = drag
|
||||
const touch = event.touches[0]
|
||||
if (!current)
|
||||
return
|
||||
if (!active(current) || event.touches.length !== 1 || !touch || touch.identifier !== current.identifier) {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
const size = current.rotated ? art.height : art.width
|
||||
const multiplier = current.target === art.template.$video ? art.constructor.TOUCH_MOVE_RATIO : 1
|
||||
if (![touch.pageX, touch.pageY, size, art.duration, multiplier].every(Number.isFinite) || size <= 0 || art.duration <= 0) {
|
||||
cancel()
|
||||
return
|
||||
}
|
||||
const direction = slideDirection(current.x, current.y, touch.pageX, touch.pageY)
|
||||
if (!(current.rotated ? direction === 1 || direction === 2 : direction === 3 || direction === 4))
|
||||
return
|
||||
const distance = current.rotated ? touch.pageY - current.y : touch.pageX - current.x
|
||||
const ratio = clamp(distance / size, -1, 1)
|
||||
const time = clamp(current.time + art.duration * ratio * multiplier, 0, art.duration)
|
||||
art.seek = time
|
||||
if (!active(current))
|
||||
return
|
||||
art.emit('setBar', 'played', clamp(time / art.duration, 0, 1), event)
|
||||
if (active(current))
|
||||
art.notice.show = `${secondToTime(time)} / ${secondToTime(art.duration)}`
|
||||
}
|
||||
return { start, move, cancel }
|
||||
}
|
||||
Reference in new issue
Block a user