✨ Add swipe gesture on photo Viewer
This commit is contained in:
91
src/utils/interactions/swipe.ts
Normal file
91
src/utils/interactions/swipe.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Swipe action
|
||||
* @description Detects horizontal or vertical swipe on an element
|
||||
* @link Inspired by https://github.com/Rezi/svelte-gestures/blob/main/src/swipe.ts
|
||||
*/
|
||||
export const swipe = (
|
||||
node: HTMLElement,
|
||||
options: SwipeOptions = {
|
||||
travelX: 60,
|
||||
travelY: 30,
|
||||
timeframe: 1000,
|
||||
}
|
||||
) => {
|
||||
let startTime: number
|
||||
let startX: number
|
||||
let startY: number
|
||||
let endX: number
|
||||
let endY: number
|
||||
|
||||
if (!node) {
|
||||
throw new Error('No specified node')
|
||||
}
|
||||
|
||||
// Detect swipe direction from given values
|
||||
const detectDirection = (startX: number, startY: number, endX: number, endY: number) => {
|
||||
// If action has been made within the timeframe (after would return)
|
||||
if (Date.now() - startTime < options.timeframe) {
|
||||
const deltaX = endX - startX
|
||||
const deltaY = endY - startY
|
||||
const absX = Math.abs(deltaX)
|
||||
const absY = Math.abs(deltaY)
|
||||
|
||||
// Horizontal
|
||||
if (absX >= 2 * absY && absX > options.travelX) {
|
||||
return deltaX > 0 ? 'x' : '-x'
|
||||
}
|
||||
// Vertical
|
||||
else if (absY >= 2 * absX && absY > options.travelY) {
|
||||
return deltaY > 0 ? 'y' : '-y'
|
||||
}
|
||||
// Tap
|
||||
else return null
|
||||
}
|
||||
}
|
||||
|
||||
// Down event
|
||||
const onDown = ({ x, y }: PointerEvent) => {
|
||||
startX = x
|
||||
startY = y
|
||||
startTime = Date.now()
|
||||
}
|
||||
node.addEventListener('pointerdown', onDown, false)
|
||||
|
||||
|
||||
// Up event
|
||||
const onUp = ({ x, y }: PointerEvent) => {
|
||||
endX = x
|
||||
endY = y
|
||||
|
||||
// Get direction from values
|
||||
const direction = detectDirection(startX, startY, endX, endY)
|
||||
if (direction) {
|
||||
// Dispatch event if direction has been detected
|
||||
node.dispatchEvent(
|
||||
new CustomEvent('swipe', { detail: direction })
|
||||
)
|
||||
}
|
||||
}
|
||||
node.addEventListener('pointerup', onUp, false)
|
||||
|
||||
|
||||
return {
|
||||
/**
|
||||
* Destroy
|
||||
*/
|
||||
destroy () {
|
||||
node.removeEventListener('pointerdown', onDown)
|
||||
node.removeEventListener('pointerup', onUp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Types
|
||||
*/
|
||||
interface SwipeOptions {
|
||||
travelX?: number
|
||||
travelY?: number
|
||||
timeframe?: number
|
||||
}
|
||||
Reference in New Issue
Block a user