kopia lustrzana https://github.com/Tldraw/Tldraw
[improvement] better comma control for pointer (#2568)
This PR fixes a few bugs with the "comma as pointer" feature. In tldraw, the `,` key can be used as a replacement for "pointer down" and "pointer up". This is most useful on laptops with trackpads that make dragging inconvenient. (See https://github.com/tldraw/tldraw/issues/2550). Previously, the canvas had to be focused in order for the comma key to work. If you clicked on a menu item and then pressed comma, it would not product a pointer event until you first clicked on the canvas. This is now fixed by moving the listener out of the `useDocumentEvents` and into `useKeyboardShortcuts`. ### Change Type - [x] `minor` — New feature ### Test Plan 1. Click the canvas. 2. Use the comma key to control pointer down / up. 3. Click a shape tool on the toolbar. 4. Move your mouse over the canvas. 5. Press the comma key. It should produce a dot / shape / etc ### Release Notes - Improve comma key as a replacement for pointer down / pointer up.pull/2569/head
rodzic
e848768e18
commit
6fde34fafd
|
@ -1,6 +1,6 @@
|
|||
import { useValue } from '@tldraw/state'
|
||||
import { useEffect } from 'react'
|
||||
import { TLKeyboardEventInfo, TLPointerEventInfo } from '../editor/types/event-types'
|
||||
import { TLKeyboardEventInfo } from '../editor/types/event-types'
|
||||
import { preventDefault } from '../utils/dom'
|
||||
import { useContainer } from './useContainer'
|
||||
import { useEditor } from './useEditor'
|
||||
|
@ -93,33 +93,12 @@ export function useDocumentEvents() {
|
|||
break
|
||||
}
|
||||
case ',': {
|
||||
// todo: extract to extension
|
||||
// This seems very fragile; the comma key here is used to send pointer events,
|
||||
// but that means it also needs to know about pen mode, hovered ids, etc.
|
||||
if (!isFocusingInput()) {
|
||||
preventDefault(e)
|
||||
if (!editor.inputs.keys.has('Comma')) {
|
||||
const { x, y, z } = editor.inputs.currentScreenPoint
|
||||
editor.inputs.keys.add('Comma')
|
||||
|
||||
const info: TLPointerEventInfo = {
|
||||
type: 'pointer',
|
||||
name: 'pointer_down',
|
||||
point: { x, y, z },
|
||||
shiftKey: e.shiftKey,
|
||||
altKey: e.altKey,
|
||||
ctrlKey: e.metaKey || e.ctrlKey,
|
||||
pointerId: 0,
|
||||
button: 0,
|
||||
isPen: editor.getInstanceState().isPenMode,
|
||||
target: 'canvas',
|
||||
}
|
||||
|
||||
editor.dispatch(info)
|
||||
return
|
||||
}
|
||||
}
|
||||
break
|
||||
// this was moved to useKeyBoardShortcuts; it's possible
|
||||
// that the comma key is pressed when the container is not
|
||||
// focused, for example when the user has just interacted
|
||||
// with the toolbar. We need to handle it on the window
|
||||
// (ofc ensuring it's a correct time for a shortcut)
|
||||
return
|
||||
}
|
||||
case 'Escape': {
|
||||
// In certain browsers, pressing escape while in full screen mode
|
||||
|
@ -178,29 +157,8 @@ export function useDocumentEvents() {
|
|||
return
|
||||
}
|
||||
|
||||
// Use the , key to send pointer events
|
||||
if (e.key === ',') {
|
||||
if (document.activeElement?.ELEMENT_NODE) preventDefault(e)
|
||||
if (editor.inputs.keys.has(e.code)) {
|
||||
const { x, y, z } = editor.inputs.currentScreenPoint
|
||||
|
||||
editor.inputs.keys.delete(e.code)
|
||||
|
||||
const info: TLPointerEventInfo = {
|
||||
type: 'pointer',
|
||||
name: 'pointer_up',
|
||||
point: { x, y, z },
|
||||
shiftKey: e.shiftKey,
|
||||
altKey: e.altKey,
|
||||
ctrlKey: e.metaKey || e.ctrlKey,
|
||||
pointerId: 0,
|
||||
button: 0,
|
||||
isPen: editor.getInstanceState().isPenMode,
|
||||
target: 'canvas',
|
||||
}
|
||||
editor.dispatch(info)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
const info: TLKeyboardEventInfo = {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { preventDefault, useEditor, useValue } from '@tldraw/editor'
|
||||
import { TLPointerEventInfo, preventDefault, useEditor, useValue } from '@tldraw/editor'
|
||||
import hotkeys from 'hotkeys-js'
|
||||
import { useEffect } from 'react'
|
||||
import { useActions } from './useActions'
|
||||
|
@ -34,6 +34,14 @@ export function useKeyboardShortcuts() {
|
|||
hotkeys(keys, { element: container, scope: editor.store.id }, callback)
|
||||
}
|
||||
|
||||
const hotUp = (keys: string, callback: (event: KeyboardEvent) => void) => {
|
||||
hotkeys(
|
||||
keys,
|
||||
{ element: container, keyup: true, keydown: false, scope: editor.store.id },
|
||||
callback
|
||||
)
|
||||
}
|
||||
|
||||
// Add hotkeys for actions and tools.
|
||||
// Except those that in SKIP_KBDS!
|
||||
const areShortcutsDisabled = () =>
|
||||
|
@ -65,6 +73,58 @@ export function useKeyboardShortcuts() {
|
|||
})
|
||||
}
|
||||
|
||||
hot(',', (e) => {
|
||||
// Skip if shortcuts are disabled
|
||||
if (areShortcutsDisabled()) return
|
||||
|
||||
// Don't press again if already pressed
|
||||
if (editor.inputs.keys.has('Comma')) return
|
||||
|
||||
preventDefault(e) // prevent whatever would normally happen
|
||||
container.focus() // Focus if not already focused
|
||||
|
||||
editor.inputs.keys.add('Comma')
|
||||
|
||||
const { x, y, z } = editor.inputs.currentScreenPoint
|
||||
const info: TLPointerEventInfo = {
|
||||
type: 'pointer',
|
||||
name: 'pointer_down',
|
||||
point: { x, y, z },
|
||||
shiftKey: e.shiftKey,
|
||||
altKey: e.altKey,
|
||||
ctrlKey: e.metaKey || e.ctrlKey,
|
||||
pointerId: 0,
|
||||
button: 0,
|
||||
isPen: editor.getInstanceState().isPenMode,
|
||||
target: 'canvas',
|
||||
}
|
||||
|
||||
editor.dispatch(info)
|
||||
})
|
||||
|
||||
hotUp(',', (e) => {
|
||||
if (areShortcutsDisabled()) return
|
||||
if (!editor.inputs.keys.has('Comma')) return
|
||||
|
||||
editor.inputs.keys.delete('Comma')
|
||||
|
||||
const { x, y, z } = editor.inputs.currentScreenPoint
|
||||
const info: TLPointerEventInfo = {
|
||||
type: 'pointer',
|
||||
name: 'pointer_up',
|
||||
point: { x, y, z },
|
||||
shiftKey: e.shiftKey,
|
||||
altKey: e.altKey,
|
||||
ctrlKey: e.metaKey || e.ctrlKey,
|
||||
pointerId: 0,
|
||||
button: 0,
|
||||
isPen: editor.getInstanceState().isPenMode,
|
||||
target: 'canvas',
|
||||
}
|
||||
|
||||
editor.dispatch(info)
|
||||
})
|
||||
|
||||
return () => {
|
||||
hotkeys.deleteScope(editor.store.id)
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue