diff --git a/packages/core/src/hooks/useCanvasEvents.tsx b/packages/core/src/hooks/useCanvasEvents.tsx index 4b8a79bab..c9f87c650 100644 --- a/packages/core/src/hooks/useCanvasEvents.tsx +++ b/packages/core/src/hooks/useCanvasEvents.tsx @@ -6,13 +6,13 @@ export function useCanvasEvents() { const onPointerDown = React.useCallback( (e: React.PointerEvent) => { - if (e.button !== 0) return + if (e.button !== 0 && e.button !== 1) return if (!inputs.pointerIsValid(e)) return e.currentTarget.setPointerCapture(e.pointerId) const info = inputs.pointerDown(e, 'canvas') - if (e.button === 0) { + if (e.button === 0 || e.button === 1) { callbacks.onPointCanvas?.(info, e) callbacks.onPointerDown?.(info, e) } @@ -36,7 +36,7 @@ export function useCanvasEvents() { const onPointerUp = React.useCallback( (e: React.PointerEvent) => { - if (e.button !== 0) return + if (e.button !== 0 && e.button !== 1) return inputs.activePointer = undefined diff --git a/packages/tldraw/src/state/TldrawApp.ts b/packages/tldraw/src/state/TldrawApp.ts index b13d2fe89..2635cca89 100644 --- a/packages/tldraw/src/state/TldrawApp.ts +++ b/packages/tldraw/src/state/TldrawApp.ts @@ -2572,9 +2572,9 @@ export class TldrawApp extends StateManager { this.pan(delta) - // onPan is called by onPointerMove when spaceKey is pressed, + // onPan is called by onPointerMove when spaceKey & middle wheel button is pressed, // so we shouldn't call this again. - if (!info.spaceKey) { + if (!info.spaceKey && !(e.buttons === 4)) { this.onPointerMove(info, e as unknown as React.PointerEvent) } } diff --git a/packages/tldraw/src/state/tools/SelectTool/SelectTool.ts b/packages/tldraw/src/state/tools/SelectTool/SelectTool.ts index b538eb57b..48f496a36 100644 --- a/packages/tldraw/src/state/tools/SelectTool/SelectTool.ts +++ b/packages/tldraw/src/state/tools/SelectTool/SelectTool.ts @@ -33,6 +33,7 @@ enum Status { GridCloning = 'gridCloning', ClonePainting = 'clonePainting', SpacePanning = 'spacePanning', + MiddleWheelPanning = 'middleWheelPanning', } export class SelectTool extends BaseTool { @@ -236,7 +237,7 @@ export class SelectTool extends BaseTool { onPointerMove: TLPointerEventHandler = (info, e) => { const { originPoint, currentPoint } = this.app - if (this.status === Status.SpacePanning && e.buttons === 1) { + if ((this.status === Status.SpacePanning && e.buttons === 1) || (this.status === Status.MiddleWheelPanning && e.buttons === 4)) { this.app.onPan?.({ ...info, delta: Vec.neg(info.delta) }, e as unknown as WheelEvent) return } @@ -336,13 +337,21 @@ export class SelectTool extends BaseTool { return } - onPointerDown: TLPointerEventHandler = () => { + onPointerDown: TLPointerEventHandler = (info, e) => { if (this.app.appState.isStyleOpen) { this.app.toggleStylePanel() } + if (e.buttons === 4) { + this.setStatus(Status.MiddleWheelPanning) + } } - onPointerUp: TLPointerEventHandler = (info) => { + onPointerUp: TLPointerEventHandler = (info, e) => { + if (this.status === Status.MiddleWheelPanning) { + this.setStatus(Status.Idle) + return + } + if (this.status === Status.TranslatingClone || this.status === Status.PointingClone) { if (this.pointedId) { this.app.completeSession()