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 -->
|
<!-- Crop Controls -->
|
||||||
<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;">
|
||||||
|
💡 Draw crop area on video above • Double-click corner handles to snap to edges
|
||||||
|
</p>
|
||||||
<div class="crop-controls">
|
<div class="crop-controls">
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div>
|
<div>
|
||||||
@@ -753,6 +756,12 @@
|
|||||||
scaleSlider.value = 100;
|
scaleSlider.value = 100;
|
||||||
updateScaleDisplay();
|
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
|
// Setup canvas for cropping
|
||||||
setupCropCanvas();
|
setupCropCanvas();
|
||||||
|
|
||||||
@@ -906,11 +915,41 @@
|
|||||||
isDraggingHandle = false;
|
isDraggingHandle = false;
|
||||||
isDraggingBox = false;
|
isDraggingBox = false;
|
||||||
activeHandle = null;
|
activeHandle = null;
|
||||||
|
cropCanvas.style.cursor = 'crosshair';
|
||||||
|
|
||||||
// Keep crop mode active and canvas visible
|
// Keep crop mode active and canvas visible
|
||||||
drawCropRect();
|
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() {
|
function drawCropRect() {
|
||||||
clearCropCanvas();
|
clearCropCanvas();
|
||||||
|
|
||||||
@@ -1056,6 +1095,33 @@
|
|||||||
drawCropRect();
|
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() {
|
function updateFormFields() {
|
||||||
if (!cropRect) return;
|
if (!cropRect) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user