Files
AFFiNE-Mirror/blocksuite/affine/blocks/root/src/edgeless/gfx-tool/pan-tool.ts
T
Saul-Mirone 1f45cc5dec refactor(editor): unify directories naming (#11516)
**Directory Structure Changes**

- Renamed multiple block-related directories by removing the "block-" prefix:
  - `block-attachment` → `attachment`
  - `block-bookmark` → `bookmark`
  - `block-callout` → `callout`
  - `block-code` → `code`
  - `block-data-view` → `data-view`
  - `block-database` → `database`
  - `block-divider` → `divider`
  - `block-edgeless-text` → `edgeless-text`
  - `block-embed` → `embed`
2025-04-07 12:34:40 +00:00

88 lines
2.0 KiB
TypeScript

import { on } from '@blocksuite/affine-shared/utils';
import type { PointerEventState } from '@blocksuite/std';
import { BaseTool, MouseButton } from '@blocksuite/std/gfx';
import { Signal } from '@preact/signals-core';
export type PanToolOption = {
panning: boolean;
};
export class PanTool extends BaseTool<PanToolOption> {
static override toolName = 'pan';
private _lastPoint: [number, number] | null = null;
readonly panning$ = new Signal<boolean>(false);
override get allowDragWithRightButton(): boolean {
return true;
}
override dragEnd(_: PointerEventState): void {
this._lastPoint = null;
this.panning$.value = false;
}
override dragMove(e: PointerEventState): void {
if (!this._lastPoint) return;
const { viewport } = this.gfx;
const { zoom } = viewport;
const [lastX, lastY] = this._lastPoint;
const deltaX = lastX - e.x;
const deltaY = lastY - e.y;
this._lastPoint = [e.x, e.y];
viewport.applyDeltaCenter(deltaX / zoom, deltaY / zoom);
}
override dragStart(e: PointerEventState): void {
this._lastPoint = [e.x, e.y];
this.panning$.value = true;
}
override mounted(): void {
this.addHook('pointerDown', evt => {
const shouldPanWithMiddle = evt.raw.button === MouseButton.MIDDLE;
if (!shouldPanWithMiddle) {
return;
}
evt.raw.preventDefault();
const selection = this.gfx.selection.surfaceSelections;
const currentTool = this.controller.currentToolOption$.peek();
const restoreToPrevious = () => {
this.controller.setTool(currentTool);
this.gfx.selection.set(selection);
};
this.controller.setTool('pan', {
panning: true,
});
const dispose = on(document, 'pointerup', evt => {
if (evt.button === MouseButton.MIDDLE) {
restoreToPrevious();
dispose();
}
});
return false;
});
}
}
declare module '@blocksuite/std/gfx' {
interface GfxToolsMap {
pan: PanTool;
}
interface GfxToolsOption {
pan: PanToolOption;
}
}