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">
|
<div class="form-group">
|
||||||
<label>✂️ Crop Video</label>
|
<label>✂️ Crop Video</label>
|
||||||
<p style="font-size: 0.9em; color: #6c757d; margin-bottom: 10px;">
|
<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>
|
</p>
|
||||||
<div class="crop-controls">
|
<div class="crop-controls">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
@@ -942,6 +942,16 @@
|
|||||||
const mouseX = e.clientX - rect.left;
|
const mouseX = e.clientX - rect.left;
|
||||||
const mouseY = e.clientY - rect.top;
|
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);
|
const handle = getHandleAtPosition(mouseX, mouseY);
|
||||||
if (handle) {
|
if (handle) {
|
||||||
snapHandleToEdge(handle);
|
snapHandleToEdge(handle);
|
||||||
@@ -1017,6 +1027,39 @@
|
|||||||
return null;
|
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) {
|
function getHandleCursor(handle) {
|
||||||
const cursors = {
|
const cursors = {
|
||||||
'tl': 'nw-resize',
|
'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() {
|
function updateFormFields() {
|
||||||
if (!cropRect) return;
|
if (!cropRect) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user