| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| import { state } from '../state.js';
|
| import { canvasCoords } from '../canvas-coords.js';
|
|
|
| export function createCloneTool({ activeLayer, saveState, strokeTo, showToast }) {
|
| return {
|
| begin(e) {
|
| const layer = activeLayer();
|
| const coords = canvasCoords(e, state.mainCanvas);
|
|
|
|
|
|
|
| const isTouchEvt = e.type && e.type.startsWith('touch');
|
| let isDoubleTap = false;
|
| if (isTouchEvt) {
|
| const t = e.touches ? e.touches[0] : null;
|
| const cx = t ? t.clientX : 0;
|
| const cy = t ? t.clientY : 0;
|
| const now = Date.now();
|
| const dt = now - state.cloneLastTapTime;
|
| const dx = cx - state.cloneLastTapX;
|
| const dy = cy - state.cloneLastTapY;
|
| if (dt < 500 && Math.hypot(dx, dy) < 40) {
|
| isDoubleTap = true;
|
| state.cloneLastTapTime = 0;
|
| } else {
|
| state.cloneLastTapTime = now;
|
| state.cloneLastTapX = cx;
|
| state.cloneLastTapY = cy;
|
| }
|
| }
|
| if (e.altKey || isDoubleTap) {
|
| state.cloneSourceX = coords.x;
|
| state.cloneSourceY = coords.y;
|
| state.cloneSourceLayerId = (layer && layer.id) || state.activeLayerId;
|
| state.cloneSourceSnapshot = null;
|
| showToast('Clone source set');
|
| return;
|
| }
|
| if (state.cloneSourceX === null || state.cloneSourceY === null) {
|
| showToast(isTouchEvt
|
| ? 'Double-tap first to set a clone source'
|
| : 'Alt-click first to set a clone source');
|
| return;
|
| }
|
| if (!layer || layer.locked) return;
|
| saveState('Clone stroke');
|
|
|
|
|
|
|
| const srcLayer = state.layers.find(l => l.id === state.cloneSourceLayerId) || layer;
|
| const snap = document.createElement('canvas');
|
| snap.width = srcLayer.canvas.width;
|
| snap.height = srcLayer.canvas.height;
|
| snap.getContext('2d').drawImage(srcLayer.canvas, 0, 0);
|
| state.cloneSourceSnapshot = snap;
|
| state.cloneStrokeStartX = coords.x;
|
| state.cloneStrokeStartY = coords.y;
|
| state.drawing = true;
|
| state.lastX = coords.x;
|
| state.lastY = coords.y;
|
| strokeTo(coords.x, coords.y);
|
| },
|
| };
|
| }
|
|
|