element-plus
Version:
A Component Library for Vue 3
62 lines (49 loc) • 1.33 kB
text/typescript
import { rAF, cAF } from '@element-plus/utils/raf'
import { isFF } from '../utils'
import type { ComputedRef } from 'vue'
interface GridWheelState {
atXStartEdge: ComputedRef<boolean>
atXEndEdge: ComputedRef<boolean>
atYStartEdge: ComputedRef<boolean>
atYEndEdge: ComputedRef<boolean>
}
type GridWheelHandler = (x: number, y: number) => void
export const useGridWheel = (
{ atXEndEdge, atXStartEdge, atYEndEdge, atYStartEdge }: GridWheelState,
onWheelDelta: GridWheelHandler
) => {
let frameHandle: number | null = null
let xOffset = 0
let yOffset = 0
const hasReachedEdge = (x: number, y: number) => {
const xEdgeReached =
(x < 0 && atXStartEdge.value) || (x > 0 && atXEndEdge.value)
const yEdgeReached =
(y < 0 && atYStartEdge.value) || (y > 0 && atYEndEdge.value)
return xEdgeReached && yEdgeReached
}
const onWheel = (e: WheelEvent) => {
cAF(frameHandle!)
const x = e.deltaX
const y = e.deltaY
if (
hasReachedEdge(xOffset, yOffset) &&
hasReachedEdge(xOffset + x, yOffset + y)
)
return
xOffset += x
yOffset += y
if (!isFF) {
e.preventDefault()
}
frameHandle = rAF(() => {
onWheelDelta(xOffset, yOffset)
xOffset = 0
yOffset = 0
})
}
return {
hasReachedEdge,
onWheel,
}
}