try to fix mobile crop
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 2m40s

This commit is contained in:
2026-02-10 21:51:00 -05:00
parent c10c9d819c
commit 229f7c4b16

View File

@@ -748,7 +748,7 @@
<p><strong>Codec:</strong> ${videoInfo.codec}</p>
<div style="margin-top: 15px; text-align: center;">
<button class="crop-mode-btn" id="crop-mode-btn">🎯 Click to Draw Crop Area</button>
<p class="crop-hint" id="crop-hint" style="display: none;">Click and drag to select • Drag corners to resize • Drag center to move</p>
<p class="crop-hint" id="crop-hint" style="display: none;">Click and drag to select • Drag corners and edges to resize or double click them to max • Drag center to move</p>
</div>
`;
@@ -830,10 +830,26 @@
cropCanvas.addEventListener('mousedown', (e) => {
if (!cropMode) return;
e.preventDefault();
const rect = cropCanvas.getBoundingClientRect();
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
handlePointerDown(mouseX, mouseY);
});
cropCanvas.addEventListener('touchstart', (e) => {
if (!cropMode) return;
e.preventDefault();
const rect = cropCanvas.getBoundingClientRect();
const touch = e.touches[0];
const mouseX = touch.clientX - rect.left;
const mouseY = touch.clientY - rect.top;
handlePointerDown(mouseX, mouseY);
});
function handlePointerDown(mouseX, mouseY) {
// Check if clicking on a handle
if (cropRect) {
const handle = getHandleAtPosition(mouseX, mouseY);
@@ -866,7 +882,7 @@
cropRect = null;
startX = mouseX;
startY = mouseY;
});
}
cropCanvas.addEventListener('mousemove', (e) => {
if (!cropMode) return;
@@ -874,6 +890,21 @@
const mouseX = e.clientX - rect.left;
const mouseY = e.clientY - rect.top;
handlePointerMove(mouseX, mouseY);
});
cropCanvas.addEventListener('touchmove', (e) => {
if (!cropMode) return;
e.preventDefault();
const rect = cropCanvas.getBoundingClientRect();
const touch = e.touches[0];
const mouseX = touch.clientX - rect.left;
const mouseY = touch.clientY - rect.top;
handlePointerMove(mouseX, mouseY);
});
function handlePointerMove(mouseX, mouseY) {
// Update cursor based on position
if (!isDrawing && !isDraggingHandle && !isDraggingEdge && !isDraggingBox && cropRect) {
const handle = getHandleAtPosition(mouseX, mouseY);
@@ -924,11 +955,20 @@
};
drawCropRect();
}
});
}
cropCanvas.addEventListener('mouseup', (e) => {
if (!cropMode) return;
handlePointerUp();
});
cropCanvas.addEventListener('touchend', (e) => {
if (!cropMode) return;
e.preventDefault();
handlePointerUp();
});
function handlePointerUp() {
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
updateFormFields();
}
@@ -943,20 +983,18 @@
// Keep crop mode active and canvas visible
drawCropRect();
});
}
// Handle mouse leaving canvas while dragging
cropCanvas.addEventListener('mouseleave', (e) => {
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
// Finish the drag operation
updateFormFields();
isDrawing = false;
isDraggingHandle = false;
isDraggingEdge = false;
isDraggingBox = false;
activeHandle = null;
activeEdge = null;
drawCropRect();
handlePointerUp();
}
});
cropCanvas.addEventListener('touchcancel', (e) => {
if (cropMode) {
handlePointerUp();
}
});
@@ -1038,6 +1076,9 @@
function getHandleAtPosition(x, y) {
if (!cropRect) return null;
// Larger hit area on mobile (touch targets should be at least 44x44px)
const hitSize = 'ontouchstart' in window ? 22 : handleSize;
const handles = [
{ name: 'tl', x: cropRect.x, y: cropRect.y },
{ name: 'tr', x: cropRect.x + cropRect.width, y: cropRect.y },
@@ -1046,7 +1087,7 @@
];
for (const handle of handles) {
if (Math.abs(x - handle.x) <= handleSize && Math.abs(y - handle.y) <= handleSize) {
if (Math.abs(x - handle.x) <= hitSize && Math.abs(y - handle.y) <= hitSize) {
return handle.name;
}
}
@@ -1056,30 +1097,32 @@
function getEdgeAtPosition(x, y) {
if (!cropRect) return null;
const tolerance = 15; // Click detection tolerance in pixels
// Larger tolerance on mobile for easier touch interaction
const tolerance = 'ontouchstart' in window ? 25 : 15;
const { x: rx, y: ry, width: rw, height: rh } = cropRect;
const hitSize = 'ontouchstart' in window ? 22 : handleSize;
// 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) {
if (Math.abs(y - ry) <= tolerance && x > rx + hitSize && x < rx + rw - hitSize) {
return 'top';
}
// Bottom edge (exclude corners)
if (Math.abs(y - (ry + rh)) <= tolerance && x > rx + handleSize && x < rx + rw - handleSize) {
if (Math.abs(y - (ry + rh)) <= tolerance && x > rx + hitSize && x < rx + rw - hitSize) {
return 'bottom';
}
// Left edge (exclude corners)
if (Math.abs(x - rx) <= tolerance && y > ry + handleSize && y < ry + rh - handleSize) {
if (Math.abs(x - rx) <= tolerance && y > ry + hitSize && y < ry + rh - hitSize) {
return 'left';
}
// Right edge (exclude corners)
if (Math.abs(x - (rx + rw)) <= tolerance && y > ry + handleSize && y < ry + rh - handleSize) {
if (Math.abs(x - (rx + rw)) <= tolerance && y > ry + hitSize && y < ry + rh - hitSize) {
return 'right';
}