diff --git a/templates/index.html b/templates/index.html index f404f54..863f040 100644 --- a/templates/index.html +++ b/templates/index.html @@ -668,8 +668,10 @@ let muteAudio = false; let compressionQuality = 23; let isDraggingHandle = false; + let isDraggingEdge = false; let isDraggingBox = false; let activeHandle = null; + let activeEdge = null; let dragOffsetX = 0; let dragOffsetY = 0; const handleSize = 12; @@ -841,6 +843,14 @@ return; } + // Check if clicking on an edge + const edge = getEdgeAtPosition(mouseX, mouseY); + if (edge) { + isDraggingEdge = true; + activeEdge = edge; + return; + } + // Check if clicking inside the box to move it if (isInsideRect(mouseX, mouseY)) { isDraggingBox = true; @@ -865,14 +875,19 @@ const mouseY = e.clientY - rect.top; // Update cursor based on position - if (!isDrawing && !isDraggingHandle && !isDraggingBox && cropRect) { + if (!isDrawing && !isDraggingHandle && !isDraggingEdge && !isDraggingBox && cropRect) { const handle = getHandleAtPosition(mouseX, mouseY); if (handle) { cropCanvas.style.cursor = getHandleCursor(handle); - } else if (isInsideRect(mouseX, mouseY)) { - cropCanvas.style.cursor = 'move'; } else { - cropCanvas.style.cursor = 'crosshair'; + const edge = getEdgeAtPosition(mouseX, mouseY); + if (edge) { + cropCanvas.style.cursor = getEdgeCursor(edge); + } else if (isInsideRect(mouseX, mouseY)) { + cropCanvas.style.cursor = 'move'; + } else { + cropCanvas.style.cursor = 'crosshair'; + } } } @@ -883,6 +898,13 @@ return; } + // Handle edge resizing + if (isDraggingEdge && cropRect) { + resizeEdge(mouseX, mouseY); + updateFormFields(); + return; + } + // Handle moving if (isDraggingBox && cropRect) { moveCropRect(mouseX, mouseY); @@ -907,14 +929,16 @@ cropCanvas.addEventListener('mouseup', (e) => { if (!cropMode) return; - if (isDrawing || isDraggingHandle || isDraggingBox) { + if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) { updateFormFields(); } isDrawing = false; isDraggingHandle = false; + isDraggingEdge = false; isDraggingBox = false; activeHandle = null; + activeEdge = null; cropCanvas.style.cursor = 'crosshair'; // Keep crop mode active and canvas visible @@ -923,13 +947,15 @@ // Handle mouse leaving canvas while dragging cropCanvas.addEventListener('mouseleave', (e) => { - if (isDrawing || isDraggingHandle || isDraggingBox) { + if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) { // Finish the drag operation updateFormFields(); isDrawing = false; isDraggingHandle = false; + isDraggingEdge = false; isDraggingBox = false; activeHandle = null; + activeEdge = null; drawCropRect(); } }); @@ -1070,6 +1096,16 @@ return cursors[handle] || 'default'; } + function getEdgeCursor(edge) { + const cursors = { + 'top': 'ns-resize', + 'bottom': 'ns-resize', + 'left': 'ew-resize', + 'right': 'ew-resize' + }; + return cursors[edge] || 'default'; + } + function isInsideRect(x, y) { if (!cropRect) return false; return x >= cropRect.x && x <= cropRect.x + cropRect.width && @@ -1127,6 +1163,47 @@ drawCropRect(); } + function resizeEdge(mouseX, mouseY) { + const minSize = 20; + + switch (activeEdge) { + case 'top': + const newHeight = cropRect.y + cropRect.height - mouseY; + if (newHeight > minSize && mouseY >= 0) { + cropRect.height = newHeight; + cropRect.y = mouseY; + } + break; + case 'bottom': + const heightBottom = mouseY - cropRect.y; + if (heightBottom > minSize && mouseY <= cropCanvas.height) { + cropRect.height = heightBottom; + } + break; + case 'left': + const newWidth = cropRect.x + cropRect.width - mouseX; + if (newWidth > minSize && mouseX >= 0) { + cropRect.width = newWidth; + cropRect.x = mouseX; + } + break; + case 'right': + const widthRight = mouseX - cropRect.x; + if (widthRight > minSize && mouseX <= cropCanvas.width) { + cropRect.width = widthRight; + } + break; + } + + // Constrain to canvas bounds + cropRect.x = Math.max(0, cropRect.x); + cropRect.y = Math.max(0, cropRect.y); + cropRect.width = Math.min(cropRect.width, cropCanvas.width - cropRect.x); + cropRect.height = Math.min(cropRect.height, cropCanvas.height - cropRect.y); + + drawCropRect(); + } + function moveCropRect(mouseX, mouseY) { const newX = mouseX - dragOffsetX; const newY = mouseY - dragOffsetY;