clamp image size/position to grid boundaries

Hunter
Thursday, October 16th, 2025 at 12:25 PM

index.html+24-14

index.html
358  				const dxCells = Math.round(dx / CELL_SIZE_PX);
359  				const dyCells = Math.round(dy / CELL_SIZE_PX);
360  
    -				const newXCell = Math.max(0, dragState.startXCell + dxCells);
    -				const newYCell = Math.max(0, dragState.startYCell + dyCells);
361 +				const newXCell = Math.max(0, Math.min(GRID_COLS - dragState.image.widthCells, dragState.startXCell + dxCells));
362 +				const newYCell = Math.max(0, Math.min(GRID_ROWS - dragState.image.heightCells, dragState.startYCell + dyCells));
363  
364  				dragState.image.xCell = newXCell;
365  				dragState.image.yCell = newYCell;

376  				const dir = resizeState.direction;
377  				const img = resizeState.image;
378  
    -				let newX = resizeState.startXCell;
    -				let newY = resizeState.startYCell;
    -				let newW = resizeState.startWidthCells;
    -				let newH = resizeState.startHeightCells;
379 +				let newX = img.xCell;
380 +				let newY = img.yCell;
381 +				let newW = img.widthCells;
382 +				let newH = img.heightCells;
383  
384  				if (dir.includes('e')) {
    -					newW = Math.max(1, resizeState.startWidthCells + dxCells);
385 +					const proposedW = Math.max(1, resizeState.startWidthCells + dxCells);
386 +					// Clamp to grid boundary
387 +					newW = Math.min(proposedW, GRID_COLS - resizeState.startXCell);
388  				}
389  				if (dir.includes('w')) {
390  					const delta = Math.min(dxCells, resizeState.startWidthCells - 1);
    -					newX = resizeState.startXCell + delta;
    -					newW = resizeState.startWidthCells - delta;
391 +					const proposedX = resizeState.startXCell + delta;
392 +					// Clamp to grid boundary
393 +					const clampedX = Math.max(0, proposedX);
394 +					newX = clampedX;
395 +					newW = resizeState.startWidthCells - (clampedX - resizeState.startXCell);
396  				}
397  				if (dir.includes('s')) {
    -					newH = Math.max(1, resizeState.startHeightCells + dyCells);
398 +					const proposedH = Math.max(1, resizeState.startHeightCells + dyCells);
399 +					// Clamp to grid boundary
400 +					newH = Math.min(proposedH, GRID_ROWS - resizeState.startYCell);
401  				}
402  				if (dir.includes('n')) {
403  					const delta = Math.min(dyCells, resizeState.startHeightCells - 1);
    -					newY = resizeState.startYCell + delta;
    -					newH = resizeState.startHeightCells - delta;
404 +					const proposedY = resizeState.startYCell + delta;
405 +					// Clamp to grid boundary
406 +					const clampedY = Math.max(0, proposedY);
407 +					newY = clampedY;
408 +					newH = resizeState.startHeightCells - (clampedY - resizeState.startYCell);
409  				}
410  
    -				img.xCell = Math.max(0, newX);
    -				img.yCell = Math.max(0, newY);
411 +				img.xCell = newX;
412 +				img.yCell = newY;
413  				img.widthCells = newW;
414  				img.heightCells = newH;
415  				updateImagePosition(img);