input.js (1.5 KB)


 1 // Getting images into the app: cursor tracking, clipboard paste, drag and drop
 2 
 3 // Track mouse position for paste placement
 4 let lastMouseX = -1;
 5 let lastMouseY = -1;
 6 document.addEventListener('mousemove', (e) => {
 7 	lastMouseX = e.clientX;
 8 	lastMouseY = e.clientY;
 9 });
10 
11 // Clipboard paste support
12 document.addEventListener('paste', async (e) => {
13 	const items = e.clipboardData?.items;
14 	if (!items) return;
15 
16 	const imageFiles = [];
17 	for (const item of items) {
18 		if (item.type.startsWith('image/')) {
19 			const file = item.getAsFile();
20 			if (file) imageFiles.push(file);
21 		}
22 	}
23 
24 	if (imageFiles.length === 0) {
25 		showPopup('No image found in clipboard');
26 		return;
27 	}
28 
29 	// Use last known mouse position relative to grid; off-grid positions are clamped downstream,
30 	// so only a cursor we've never seen falls back to (0, 0)
31 	const gridRect = grid.getBoundingClientRect();
32 	const hasCursor = lastMouseX >= 0 && lastMouseY >= 0;
33 
34 	const dropX = hasCursor ? lastMouseX - gridRect.left : 0;
35 	const dropY = hasCursor ? lastMouseY - gridRect.top : 0;
36 
37 	await processAndAddImages(imageFiles, dropX, dropY);
38 });
39 
40 // Prevent default drag behavior on entire document
41 document.addEventListener('dragover', (e) => {
42 	e.preventDefault();
43 	e.stopPropagation();
44 });
45 
46 document.addEventListener('drop', async (e) => {
47 	e.preventDefault();
48 	e.stopPropagation();
49 
50 	// Get drop position relative to the grid
51 	const gridRect = grid.getBoundingClientRect();
52 	const dropX = e.clientX - gridRect.left;
53 	const dropY = e.clientY - gridRect.top;
54 
55 	await processAndAddImages(e.dataTransfer.files, dropX, dropY);
56 });