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;