try to fix mobile crop
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 2m40s
All checks were successful
Build Images and Deploy / Update-PROD-Stack (push) Successful in 2m40s
This commit is contained in:
@@ -748,7 +748,7 @@
|
|||||||
<p><strong>Codec:</strong> ${videoInfo.codec}</p>
|
<p><strong>Codec:</strong> ${videoInfo.codec}</p>
|
||||||
<div style="margin-top: 15px; text-align: center;">
|
<div style="margin-top: 15px; text-align: center;">
|
||||||
<button class="crop-mode-btn" id="crop-mode-btn">🎯 Click to Draw Crop Area</button>
|
<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>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@@ -830,10 +830,26 @@
|
|||||||
|
|
||||||
cropCanvas.addEventListener('mousedown', (e) => {
|
cropCanvas.addEventListener('mousedown', (e) => {
|
||||||
if (!cropMode) return;
|
if (!cropMode) return;
|
||||||
|
e.preventDefault();
|
||||||
const rect = cropCanvas.getBoundingClientRect();
|
const rect = cropCanvas.getBoundingClientRect();
|
||||||
const mouseX = e.clientX - rect.left;
|
const mouseX = e.clientX - rect.left;
|
||||||
const mouseY = e.clientY - rect.top;
|
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
|
// Check if clicking on a handle
|
||||||
if (cropRect) {
|
if (cropRect) {
|
||||||
const handle = getHandleAtPosition(mouseX, mouseY);
|
const handle = getHandleAtPosition(mouseX, mouseY);
|
||||||
@@ -866,7 +882,7 @@
|
|||||||
cropRect = null;
|
cropRect = null;
|
||||||
startX = mouseX;
|
startX = mouseX;
|
||||||
startY = mouseY;
|
startY = mouseY;
|
||||||
});
|
}
|
||||||
|
|
||||||
cropCanvas.addEventListener('mousemove', (e) => {
|
cropCanvas.addEventListener('mousemove', (e) => {
|
||||||
if (!cropMode) return;
|
if (!cropMode) return;
|
||||||
@@ -874,6 +890,21 @@
|
|||||||
const mouseX = e.clientX - rect.left;
|
const mouseX = e.clientX - rect.left;
|
||||||
const mouseY = e.clientY - rect.top;
|
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
|
// Update cursor based on position
|
||||||
if (!isDrawing && !isDraggingHandle && !isDraggingEdge && !isDraggingBox && cropRect) {
|
if (!isDrawing && !isDraggingHandle && !isDraggingEdge && !isDraggingBox && cropRect) {
|
||||||
const handle = getHandleAtPosition(mouseX, mouseY);
|
const handle = getHandleAtPosition(mouseX, mouseY);
|
||||||
@@ -924,11 +955,20 @@
|
|||||||
};
|
};
|
||||||
drawCropRect();
|
drawCropRect();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
cropCanvas.addEventListener('mouseup', (e) => {
|
cropCanvas.addEventListener('mouseup', (e) => {
|
||||||
if (!cropMode) return;
|
if (!cropMode) return;
|
||||||
|
handlePointerUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
cropCanvas.addEventListener('touchend', (e) => {
|
||||||
|
if (!cropMode) return;
|
||||||
|
e.preventDefault();
|
||||||
|
handlePointerUp();
|
||||||
|
});
|
||||||
|
|
||||||
|
function handlePointerUp() {
|
||||||
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
|
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
|
||||||
updateFormFields();
|
updateFormFields();
|
||||||
}
|
}
|
||||||
@@ -943,20 +983,18 @@
|
|||||||
|
|
||||||
// Keep crop mode active and canvas visible
|
// Keep crop mode active and canvas visible
|
||||||
drawCropRect();
|
drawCropRect();
|
||||||
});
|
}
|
||||||
|
|
||||||
// Handle mouse leaving canvas while dragging
|
// Handle mouse leaving canvas while dragging
|
||||||
cropCanvas.addEventListener('mouseleave', (e) => {
|
cropCanvas.addEventListener('mouseleave', (e) => {
|
||||||
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
|
if (isDrawing || isDraggingHandle || isDraggingEdge || isDraggingBox) {
|
||||||
// Finish the drag operation
|
handlePointerUp();
|
||||||
updateFormFields();
|
}
|
||||||
isDrawing = false;
|
});
|
||||||
isDraggingHandle = false;
|
|
||||||
isDraggingEdge = false;
|
cropCanvas.addEventListener('touchcancel', (e) => {
|
||||||
isDraggingBox = false;
|
if (cropMode) {
|
||||||
activeHandle = null;
|
handlePointerUp();
|
||||||
activeEdge = null;
|
|
||||||
drawCropRect();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1038,6 +1076,9 @@
|
|||||||
function getHandleAtPosition(x, y) {
|
function getHandleAtPosition(x, y) {
|
||||||
if (!cropRect) return null;
|
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 = [
|
const handles = [
|
||||||
{ name: 'tl', x: cropRect.x, y: cropRect.y },
|
{ name: 'tl', x: cropRect.x, y: cropRect.y },
|
||||||
{ name: 'tr', x: cropRect.x + cropRect.width, y: cropRect.y },
|
{ name: 'tr', x: cropRect.x + cropRect.width, y: cropRect.y },
|
||||||
@@ -1046,7 +1087,7 @@
|
|||||||
];
|
];
|
||||||
|
|
||||||
for (const handle of handles) {
|
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;
|
return handle.name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1056,30 +1097,32 @@
|
|||||||
function getEdgeAtPosition(x, y) {
|
function getEdgeAtPosition(x, y) {
|
||||||
if (!cropRect) return null;
|
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 { x: rx, y: ry, width: rw, height: rh } = cropRect;
|
||||||
|
const hitSize = 'ontouchstart' in window ? 22 : handleSize;
|
||||||
|
|
||||||
// Check if within the rectangle bounds (with tolerance)
|
// Check if within the rectangle bounds (with tolerance)
|
||||||
const inHorizontalRange = x >= rx - tolerance && x <= rx + rw + tolerance;
|
const inHorizontalRange = x >= rx - tolerance && x <= rx + rw + tolerance;
|
||||||
const inVerticalRange = y >= ry - tolerance && y <= ry + rh + tolerance;
|
const inVerticalRange = y >= ry - tolerance && y <= ry + rh + tolerance;
|
||||||
|
|
||||||
// Top edge (exclude corners)
|
// 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';
|
return 'top';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bottom edge (exclude corners)
|
// 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';
|
return 'bottom';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Left edge (exclude corners)
|
// 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';
|
return 'left';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Right edge (exclude corners)
|
// 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';
|
return 'right';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user