kopia lustrzana https://github.com/Tldraw/Tldraw
Update useCoarsePointer.ts
rodzic
02404227d6
commit
daca65d159
|
@ -5,44 +5,68 @@ import { useEditor } from './useEditor'
|
|||
export function useCoarsePointer() {
|
||||
const previousCursor = useRef<boolean | undefined>(undefined)
|
||||
const editor = useEditor()
|
||||
|
||||
useEffect(() => {
|
||||
// We'll track our own state for the pointer type
|
||||
let isCoarse = editor.getInstanceState().isCoarsePointer
|
||||
|
||||
// 1.
|
||||
// We'll use touch events / mouse events to detect coarse pointer.
|
||||
|
||||
// When the user touches the screen, we assume they have a coarse pointer
|
||||
const handleTouchStart = () => {
|
||||
if (isCoarse) return
|
||||
isCoarse = true
|
||||
editor.updateInstanceState({ isCoarsePointer: true })
|
||||
}
|
||||
|
||||
// When the user moves the mouse, we assume they have a fine pointer
|
||||
const handleMouseMove = () => {
|
||||
if (!isCoarse) return
|
||||
isCoarse = false
|
||||
editor.updateInstanceState({ isCoarsePointer: false })
|
||||
}
|
||||
|
||||
// Set up the listeners for touch and mouse events
|
||||
window.addEventListener('touchstart', handleTouchStart)
|
||||
window.addEventListener('mousemove', handleMouseMove)
|
||||
|
||||
// 2.
|
||||
// We can also use the media query to detect / set the initial pointer type
|
||||
// and update the state if the pointer type changes.
|
||||
|
||||
// We want the touch / mouse events to run even if the browser does not
|
||||
// support matchMedia. We'll have to handle the media query changes
|
||||
// conditionally in the code below.
|
||||
const mql = window.matchMedia && window.matchMedia('(any-pointer: coarse)')
|
||||
|
||||
// This is a workaround for a Firefox bug where we don't correctly
|
||||
// detect coarse VS fine pointer. For now, let's assume that you have a fine
|
||||
// pointer if you're on Firefox on desktop.
|
||||
if (
|
||||
editor.environment.isFirefox &&
|
||||
!editor.environment.isAndroid &&
|
||||
!editor.environment.isIos
|
||||
) {
|
||||
editor.updateInstanceState({ isCoarsePointer: false })
|
||||
return
|
||||
const isForcedFinePointer =
|
||||
editor.environment.isFirefox && !editor.environment.isAndroid && !editor.environment.isIos
|
||||
|
||||
const handleMediaQueryChange = () => {
|
||||
const next = isForcedFinePointer ? false : mql.matches // get the value from the media query
|
||||
if (isCoarse !== next) return // bail if the value hasn't changed
|
||||
isCoarse = next // update the local value
|
||||
editor.updateInstanceState({ isCoarsePointer: next }) // update the value in state
|
||||
}
|
||||
if (window.matchMedia) {
|
||||
// Some devices have a touch screen but also a fine pointer (e.g. a mouse).
|
||||
// If any pointer is coarse, we consider the device to have a coarse pointer.
|
||||
// This is dynamically updated as the user switches between input devices.
|
||||
const mql = window.matchMedia('(any-pointer: coarse)')
|
||||
|
||||
const handler = (coarse?: boolean) => {
|
||||
const isCoarsePointer = coarse ?? !!mql.matches
|
||||
if (isCoarsePointer === previousCursor.current) return
|
||||
editor.updateInstanceState({ isCoarsePointer: coarse ?? !!mql.matches })
|
||||
previousCursor.current = isCoarsePointer
|
||||
}
|
||||
if (mql) {
|
||||
// set up the listener
|
||||
mql.addEventListener('change', handleMediaQueryChange)
|
||||
|
||||
const touchStartHandler = () => handler(true)
|
||||
const mouseMoveHandler = () => handler(false)
|
||||
// and run the handler once to set the initial value
|
||||
handleMediaQueryChange()
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('touchstart', handleTouchStart)
|
||||
window.removeEventListener('mousemove', handleMouseMove)
|
||||
|
||||
handler()
|
||||
if (mql) {
|
||||
mql.addEventListener('change', () => handler())
|
||||
window.addEventListener('touchstart', touchStartHandler)
|
||||
window.addEventListener('mousemove', mouseMoveHandler)
|
||||
return () => {
|
||||
mql.removeEventListener('change', () => handler())
|
||||
window.removeEventListener('touchstart', touchStartHandler)
|
||||
window.removeEventListener('mousemove', mouseMoveHandler)
|
||||
}
|
||||
mql.removeEventListener('change', handleMediaQueryChange)
|
||||
}
|
||||
}
|
||||
}, [editor])
|
||||
|
|
Ładowanie…
Reference in New Issue