element-plus
Version:
A Component Library for Vue3.0
75 lines (52 loc) • 1.48 kB
text/typescript
import { rAF, cAF } from '@element-plus/utils/raf'
import { isFF } from '../utils'
import { HORIZONTAL, VERTICAL } from '../defaults'
import type { ComputedRef } from 'vue'
import type { LayoutDirection } from '../types'
const LayoutKeys = {
[HORIZONTAL]: 'deltaX',
[VERTICAL]: 'deltaY',
}
interface IWheelState {
atStartEdge: ComputedRef<boolean> // exclusive to reachEnd
atEndEdge: ComputedRef<boolean>
layout: ComputedRef<LayoutDirection>
}
type IWheelHandler = (offset: number) => void
const useWheel = ({
atEndEdge,
atStartEdge,
layout,
}: IWheelState, onWheelDelta: IWheelHandler) => {
let frameHandle: number | null = null
let offset = 0
// let scrollLock = false
// let lockHandle = null
// const lockScroll = () => {
// clearTimeout(lockHandle)
// scrollLock = true
// lockHandle = setTimeout(() => scrollLock = false, 50)
// }
const hasReachedEdge = (offset: number) => {
const edgeReached = (offset < 0 && atStartEdge.value) || (offset > 0 && atEndEdge.value)
return edgeReached
}
const onWheel = (e: WheelEvent) => {
cAF(frameHandle)
const newOffset = e[LayoutKeys[layout.value]]
if (hasReachedEdge(offset) && hasReachedEdge(offset + newOffset)) return
offset += newOffset
if (!isFF) {
e.preventDefault()
}
frameHandle = rAF(() => {
onWheelDelta(offset)
offset = 0
})
}
return {
hasReachedEdge,
onWheel,
}
}
export default useWheel