- 💡 Draw crop area on video above • Double-click corner handles to snap to edges
+ 💡 Draw crop area on video above • Double-click edges or corners to snap
@@ -942,6 +942,16 @@
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
+ // Check for edge click first (between corners)
+ const edge = getEdgeAtPosition(mouseX, mouseY);
+ if (edge) {
+ snapEdgeToSide(edge);
+ updateFormFields();
+ drawCropRect();
+ return;
+ }
+
+ // Fall back to corner handling
const handle = getHandleAtPosition(mouseX, mouseY);
if (handle) {
snapHandleToEdge(handle);
@@ -1017,6 +1027,39 @@
return null;
}
+ function getEdgeAtPosition(x, y) {
+ if (!cropRect) return null;
+
+ const tolerance = 15; // Click detection tolerance in pixels
+ const { x: rx, y: ry, width: rw, height: rh } = cropRect;
+
+ // Check if within the rectangle bounds (with tolerance)
+ const inHorizontalRange = x >= rx - tolerance && x <= rx + rw + tolerance;
+ const inVerticalRange = y >= ry - tolerance && y <= ry + rh + tolerance;
+
+ // Top edge (exclude corners)
+ if (Math.abs(y - ry) <= tolerance && x > rx + handleSize && x < rx + rw - handleSize) {
+ return 'top';
+ }
+
+ // Bottom edge (exclude corners)
+ if (Math.abs(y - (ry + rh)) <= tolerance && x > rx + handleSize && x < rx + rw - handleSize) {
+ return 'bottom';
+ }
+
+ // Left edge (exclude corners)
+ if (Math.abs(x - rx) <= tolerance && y > ry + handleSize && y < ry + rh - handleSize) {
+ return 'left';
+ }
+
+ // Right edge (exclude corners)
+ if (Math.abs(x - (rx + rw)) <= tolerance && y > ry + handleSize && y < ry + rh - handleSize) {
+ return 'right';
+ }
+
+ return null;
+ }
+
function getHandleCursor(handle) {
const cursors = {
'tl': 'nw-resize',
@@ -1122,6 +1165,27 @@
}
}
+ function snapEdgeToSide(edge) {
+ if (!cropRect) return;
+
+ switch (edge) {
+ case 'top': // Snap top edge to y=0
+ cropRect.height += cropRect.y; // Extend height by current y
+ cropRect.y = 0;
+ break;
+ case 'bottom': // Snap bottom edge to canvas height
+ cropRect.height = cropCanvas.height - cropRect.y;
+ break;
+ case 'left': // Snap left edge to x=0
+ cropRect.width += cropRect.x; // Extend width by current x
+ cropRect.x = 0;
+ break;
+ case 'right': // Snap right edge to canvas width
+ cropRect.width = cropCanvas.width - cropRect.x;
+ break;
+ }
+ }
+
function updateFormFields() {
if (!cropRect) return;