| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { state } from '../state.js';
|
| import { canvasCoords } from '../canvas-coords.js';
|
| import { computeSnap as computeSnapImpl } from '../snap.js';
|
|
|
| export function createMoveTool({ activeLayer, saveState, composite }) {
|
| function computeSnap(layer, nx, ny) {
|
| return computeSnapImpl(layer, nx, ny, {
|
| zoom: state.zoom,
|
| canvasW: state.imgWidth,
|
| canvasH: state.imgHeight,
|
| otherLayers: state.layers.map(l => ({
|
| visible: l.visible,
|
| id: l.id,
|
| canvas: l.canvas,
|
| offset: state.layerOffsets.get(l.id) || { x: 0, y: 0 },
|
| })),
|
| });
|
| }
|
|
|
| return {
|
| begin(e) {
|
| const layer = activeLayer();
|
| if (!layer || layer.locked) return;
|
| saveState();
|
| state.moving = true;
|
| const coords = canvasCoords(e, state.mainCanvas);
|
| const off = state.layerOffsets.get(layer.id) || { x: 0, y: 0 };
|
| state.moveStartX = coords.x;
|
| state.moveStartY = coords.y;
|
| state.moveLayerOffsetX = off.x;
|
| state.moveLayerOffsetY = off.y;
|
| },
|
| drag(e) {
|
| if (!state.moving) return;
|
| e.preventDefault();
|
| const layer = activeLayer();
|
| if (!layer) return;
|
| const coords = canvasCoords(e, state.mainCanvas);
|
| const dx = coords.x - state.moveStartX;
|
| const dy = coords.y - state.moveStartY;
|
| let nx = state.moveLayerOffsetX + dx;
|
| let ny = state.moveLayerOffsetY + dy;
|
|
|
|
|
|
|
| if (e.ctrlKey || e.metaKey) {
|
| const snapped = computeSnap(layer, nx, ny);
|
| nx = snapped.x;
|
| ny = snapped.y;
|
| state.activeSnapGuides = snapped.guides;
|
| } else {
|
| state.activeSnapGuides = null;
|
| }
|
| state.layerOffsets.set(layer.id, { x: nx, y: ny });
|
| composite();
|
| },
|
| end() {
|
| state.moving = false;
|
| state.activeSnapGuides = null;
|
| },
|
| };
|
| }
|
|
|