improved crop features
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m8s
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 1m8s
This commit is contained in:
@@ -543,6 +543,9 @@
|
||||
<!-- Crop Controls -->
|
||||
<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
|
||||
</p>
|
||||
<div class="crop-controls">
|
||||
<div class="form-row">
|
||||
<div>
|
||||
@@ -752,6 +755,12 @@
|
||||
scalePercentage = 100;
|
||||
scaleSlider.value = 100;
|
||||
updateScaleDisplay();
|
||||
|
||||
// Set max values for crop inputs
|
||||
document.getElementById('crop-x').max = videoInfo.width;
|
||||
document.getElementById('crop-y').max = videoInfo.height;
|
||||
document.getElementById('crop-width').max = videoInfo.width;
|
||||
document.getElementById('crop-height').max = videoInfo.height;
|
||||
|
||||
// Setup canvas for cropping
|
||||
setupCropCanvas();
|
||||
@@ -906,10 +915,40 @@
|
||||
isDraggingHandle = false;
|
||||
isDraggingBox = false;
|
||||
activeHandle = null;
|
||||
cropCanvas.style.cursor = 'crosshair';
|
||||
|
||||
// Keep crop mode active and canvas visible
|
||||
drawCropRect();
|
||||
});
|
||||
|
||||
// Handle mouse leaving canvas while dragging
|
||||
cropCanvas.addEventListener('mouseleave', (e) => {
|
||||
if (isDrawing || isDraggingHandle || isDraggingBox) {
|
||||
// Finish the drag operation
|
||||
updateFormFields();
|
||||
isDrawing = false;
|
||||
isDraggingHandle = false;
|
||||
isDraggingBox = false;
|
||||
activeHandle = null;
|
||||
drawCropRect();
|
||||
}
|
||||
});
|
||||
|
||||
// Double-click on handles to snap to edges
|
||||
cropCanvas.addEventListener('dblclick', (e) => {
|
||||
if (!cropMode || !cropRect) return;
|
||||
|
||||
const rect = cropCanvas.getBoundingClientRect();
|
||||
const mouseX = e.clientX - rect.left;
|
||||
const mouseY = e.clientY - rect.top;
|
||||
|
||||
const handle = getHandleAtPosition(mouseX, mouseY);
|
||||
if (handle) {
|
||||
snapHandleToEdge(handle);
|
||||
updateFormFields();
|
||||
drawCropRect();
|
||||
}
|
||||
});
|
||||
|
||||
function drawCropRect() {
|
||||
clearCropCanvas();
|
||||
@@ -1056,6 +1095,33 @@
|
||||
drawCropRect();
|
||||
}
|
||||
|
||||
function snapHandleToEdge(handle) {
|
||||
if (!cropRect) return;
|
||||
|
||||
switch (handle) {
|
||||
case 'tl': // Top-left -> snap to top-left corner
|
||||
cropRect.width += cropRect.x; // Extend width by current x
|
||||
cropRect.height += cropRect.y; // Extend height by current y
|
||||
cropRect.x = 0;
|
||||
cropRect.y = 0;
|
||||
break;
|
||||
case 'tr': // Top-right -> snap to top-right corner
|
||||
cropRect.width = cropCanvas.width - cropRect.x;
|
||||
cropRect.height += cropRect.y;
|
||||
cropRect.y = 0;
|
||||
break;
|
||||
case 'bl': // Bottom-left -> snap to bottom-left corner
|
||||
cropRect.width += cropRect.x;
|
||||
cropRect.height = cropCanvas.height - cropRect.y;
|
||||
cropRect.x = 0;
|
||||
break;
|
||||
case 'br': // Bottom-right -> snap to bottom-right corner
|
||||
cropRect.width = cropCanvas.width - cropRect.x;
|
||||
cropRect.height = cropCanvas.height - cropRect.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function updateFormFields() {
|
||||
if (!cropRect) return;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user