Memulai
Siklus Hidup
Peramban
Pengembangan
Paket Luar
useMouse
Posisi penunjuk, dengan dukungan sentuh.
0 × 0
Sumber: belum ada · koordinat relatif jendela
type menentukan sistem koordinat yang dipakai, dan pilihannya berpengaruh:
page— relatif terhadap dokumen, ikut bergeser saat halaman digulungclient— relatif terhadap jendela, tidak terpengaruh gulunganscreen— relatif terhadap layar fisikmovement— selisih dari peristiwa sebelumnya, untuk pointer lock
sourceType menyebut dari mana angkanya datang. Itu yang membedakan "penunjuk di pojok kiri atas" dari "belum ada penunjuk sama sekali", yang kalau tidak dibedakan akan membuat efek ikut-kursor melompat ke sudut saat halaman baru dibuka.
Pemasangan
npx shadcn-vue@latest add @kliping/use-mouse Perlu @kliping terdaftar di components.json project Anda. Lihat cara menyiapkannya.
Ikut terpasang sendiri: use-event-listener.
Salin dulu is-browser, target, use-event-listener — masing-masing memuat sumbernya di halamannya sendiri — lalu tempel berkas ini.
ts
import { ref, toValue } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { useEventListener } from '@/composables/use-event-listener'
export type JenisKoordinat = 'page' | 'client' | 'screen' | 'movement'
export type SumberPenunjuk = 'mouse' | 'touch' | null
export interface UseMouseOptions {
/** Sistem koordinat. Bawaan: `page`. */
type?: JenisKoordinat
/** Ikuti peristiwa sentuh. Bawaan: true. */
touch?: MaybeRefOrGetter<boolean>
/** Kembalikan ke nilai awal saat sentuhan diangkat. Bawaan: false. */
resetOnTouchEnds?: boolean
initialValue?: { x: number, y: number }
}
const KUNCI_X = { page: 'pageX', client: 'clientX', screen: 'screenX', movement: 'movementX' } as const
const KUNCI_Y = { page: 'pageY', client: 'clientY', screen: 'screenY', movement: 'movementY' } as const
export function useMouse(options: UseMouseOptions = {}) {
const {
type = 'page',
touch = true,
resetOnTouchEnds = false,
initialValue = { x: 0, y: 0 },
} = options
const x = ref(initialValue.x)
const y = ref(initialValue.y)
const sourceType = ref<SumberPenunjuk>(null)
const dariTetikus = (peristiwa: MouseEvent) => {
x.value = peristiwa[KUNCI_X[type]]
y.value = peristiwa[KUNCI_Y[type]]
sourceType.value = 'mouse'
}
const dariSentuhan = (peristiwa: TouchEvent) => {
const titik = peristiwa.touches[0] ?? peristiwa.changedTouches[0]
if (!titik)
return
// Sentuhan tidak punya `movementX`/`movementY`. Yang paling mendekati
// maksudnya adalah koordinat jendela, jadi itu yang dipakai.
if (type === 'movement') {
x.value = titik.clientX
y.value = titik.clientY
}
else {
x.value = titik[KUNCI_X[type] as 'pageX' | 'clientX' | 'screenX']
y.value = titik[KUNCI_Y[type] as 'pageY' | 'clientY' | 'screenY']
}
sourceType.value = 'touch'
}
const aktifSentuh = () => toValue(touch)
useEventListener('mousemove', dariTetikus, { passive: true })
useEventListener('dragover', dariTetikus, { passive: true })
useEventListener('touchstart', dariSentuhan, { passive: true, enable: aktifSentuh })
useEventListener('touchmove', dariSentuhan, { passive: true, enable: aktifSentuh })
useEventListener('touchend', (peristiwa: TouchEvent) => {
if (resetOnTouchEnds) {
x.value = initialValue.x
y.value = initialValue.y
return
}
dariSentuhan(peristiwa)
}, { passive: true, enable: aktifSentuh })
return { x, y, sourceType }
}API
ts
export type JenisKoordinat = 'page' | 'client' | 'screen' | 'movement'
export type SumberPenunjuk = 'mouse' | 'touch' | null
export interface UseMouseOptions {
/** Sistem koordinat. Bawaan: `page`. */
type?: JenisKoordinat
/** Ikuti peristiwa sentuh. Bawaan: true. */
touch?: MaybeRefOrGetter<boolean>
/** Kembalikan ke nilai awal saat sentuhan diangkat. Bawaan: false. */
resetOnTouchEnds?: boolean
initialValue?: { x: number, y: number }
}
export function useMouse(options: UseMouseOptions = {})