snap edges on crop
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m10s
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m10s
This commit is contained in:
@@ -544,7 +544,7 @@
|
||||
<div class="form-group">
|
||||
<label>✂️ Crop Video</label>
|
||||
<p style="font-size: 0.9em; color: #6c757d; margin-bottom: 10px;">
|
||||
💡 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
|
||||
</p>
|
||||
<div class="crop-controls">
|
||||
<div class="form-row">
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user