/
index.ts
118 lines (105 loc) · 3.01 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { ref } from 'vue-demi'
import type { ConfigurableEventFilter } from '@vueuse/shared'
import { useEventListener } from '../useEventListener'
import type { ConfigurableWindow } from '../_configurable'
import { defaultWindow } from '../_configurable'
import type { Position } from '../types'
export interface UseMouseOptions extends ConfigurableWindow, ConfigurableEventFilter {
/**
* Mouse position based by page, client, or relative to previous position
*
* @default 'page'
*/
type?: 'page' | 'client' | 'movement'
/**
* Listen to `touchmove` events
*
* @default true
*/
touch?: boolean
/**
* Reset to initial value when `touchend` event fired
*
* @default false
*/
resetOnTouchEnds?: boolean
/**
* Initial values
*/
initialValue?: Position
}
export type MouseSourceType = 'mouse' | 'touch' | null
/**
* Reactive mouse position.
*
* @see https://vueuse.org/useMouse
* @param options
*/
export function useMouse(options: UseMouseOptions = {}) {
const {
type = 'page',
touch = true,
resetOnTouchEnds = false,
initialValue = { x: 0, y: 0 },
window = defaultWindow,
eventFilter,
} = options
const x = ref(initialValue.x)
const y = ref(initialValue.y)
const sourceType = ref<MouseSourceType>(null)
const mouseHandler = (event: MouseEvent) => {
if (type === 'page') {
x.value = event.pageX
y.value = event.pageY
}
else if (type === 'client') {
x.value = event.clientX
y.value = event.clientY
}
else if (type === 'movement') {
x.value = event.movementX
y.value = event.movementY
}
sourceType.value = 'mouse'
}
const reset = () => {
x.value = initialValue.x
y.value = initialValue.y
}
const touchHandler = (event: TouchEvent) => {
if (event.touches.length > 0) {
const touch = event.touches[0]
if (type === 'page') {
x.value = touch.pageX
y.value = touch.pageY
}
else if (type === 'client') {
x.value = touch.clientX
y.value = touch.clientY
}
sourceType.value = 'touch'
}
}
const mouseHandlerWrapper = (event: MouseEvent) => {
return eventFilter === undefined ? mouseHandler(event) : eventFilter(() => mouseHandler(event), {} as any)
}
const touchHandlerWrapper = (event: TouchEvent) => {
return eventFilter === undefined ? touchHandler(event) : eventFilter(() => touchHandler(event), {} as any)
}
if (window) {
useEventListener(window, 'mousemove', mouseHandlerWrapper, { passive: true })
useEventListener(window, 'dragover', mouseHandlerWrapper, { passive: true })
if (touch && type !== 'movement') {
useEventListener(window, 'touchstart', touchHandlerWrapper, { passive: true })
useEventListener(window, 'touchmove', touchHandlerWrapper, { passive: true })
if (resetOnTouchEnds)
useEventListener(window, 'touchend', reset, { passive: true })
}
}
return {
x,
y,
sourceType,
}
}
export type UseMouseReturn = ReturnType<typeof useMouse>