Spaces:
Sleeping
Sleeping
File size: 4,289 Bytes
aeb61fc |
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 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
export function initializeSPen(canvasElement) {
let isPen = false
// S-Pen uses button ID 5
const SPEN_BUTTON_ID = 5
// Marker to identify synthetic events and prevent infinite loops
const SYNTHETIC_MARKER = '__spen_synthetic__'
const handlePointerDown = (e) => {
// Skip synthetic events we created
if (e[SYNTHETIC_MARKER]) return
// CRITICAL: Only process if the event target is the canvas or inside it
if (e.target !== canvasElement && !canvasElement.contains(e.target)) {
return
}
if (e.button === SPEN_BUTTON_ID) {
// STOP the original event from reaching canvas handlers
e.stopPropagation()
e.preventDefault()
isPen = true
// Dispatch S-Pen button event for tool switching
window.dispatchEvent(new CustomEvent('spen-button-down'))
// Dispatch a synthetic 'pointerdown' event with button 0
const newEvent = new PointerEvent('pointerdown', {
clientX: e.clientX,
clientY: e.clientY,
screenX: e.screenX,
screenY: e.screenY,
pointerId: e.pointerId,
pointerType: e.pointerType,
pressure: e.pressure,
width: e.width,
height: e.height,
tiltX: e.tiltX,
tiltY: e.tiltY,
button: 0, // Pretend it's a left-click/touch
buttons: 1,
isPrimary: true,
bubbles: true,
cancelable: true
})
newEvent[SYNTHETIC_MARKER] = true
canvasElement.dispatchEvent(newEvent)
}
}
const handlePointerMove = (e) => {
// Skip synthetic events we created
if (e[SYNTHETIC_MARKER]) return
if (!isPen) return
// Stop original event and dispatch synthetic one
e.stopPropagation()
e.preventDefault()
const newEvent = new PointerEvent('pointermove', {
clientX: e.clientX,
clientY: e.clientY,
screenX: e.screenX,
screenY: e.screenY,
pointerId: e.pointerId,
pointerType: e.pointerType,
pressure: e.pressure,
width: e.width,
height: e.height,
tiltX: e.tiltX,
tiltY: e.tiltY,
button: 0,
buttons: 1,
isPrimary: true,
bubbles: true,
cancelable: true
})
newEvent[SYNTHETIC_MARKER] = true
canvasElement.dispatchEvent(newEvent)
}
const handlePointerUp = (e) => {
// Skip synthetic events we created
if (e[SYNTHETIC_MARKER]) return
if (isPen) {
e.stopPropagation()
e.preventDefault()
isPen = false
// Dispatch S-Pen button up event for tool switching
window.dispatchEvent(new CustomEvent('spen-button-up'))
const newEvent = new PointerEvent('pointerup', {
clientX: e.clientX,
clientY: e.clientY,
screenX: e.screenX,
screenY: e.screenY,
pointerId: e.pointerId,
pointerType: e.pointerType,
pressure: e.pressure,
width: e.width,
height: e.height,
tiltX: e.tiltX,
tiltY: e.tiltY,
button: 0,
buttons: 0,
isPrimary: true,
bubbles: true,
cancelable: true
})
newEvent[SYNTHETIC_MARKER] = true
canvasElement.dispatchEvent(newEvent)
}
}
// Use CAPTURE phase to intercept events BEFORE they reach the canvas
window.addEventListener('pointerdown', handlePointerDown, true)
window.addEventListener('pointermove', handlePointerMove, true)
window.addEventListener('pointerup', handlePointerUp, true)
return () => {
window.removeEventListener('pointerdown', handlePointerDown, true)
window.removeEventListener('pointermove', handlePointerMove, true)
window.removeEventListener('pointerup', handlePointerUp, true)
}
}
|