fix: Mobile image crop fix
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m20s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m20s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 51s
Deploy to Staging / Verify Staging (pull_request) Successful in 9s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
* @ai-context Allows user to adjust crop area with touch/mouse, confirm or retake
|
* @ai-context Allows user to adjust crop area with touch/mouse, confirm or retake
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState, useRef, useEffect } from 'react';
|
||||||
import { Box, IconButton, Button, Typography, CircularProgress } from '@mui/material';
|
import { Box, IconButton, Button, Typography, CircularProgress } from '@mui/material';
|
||||||
import CheckIcon from '@mui/icons-material/Check';
|
import CheckIcon from '@mui/icons-material/Check';
|
||||||
import RefreshIcon from '@mui/icons-material/Refresh';
|
import RefreshIcon from '@mui/icons-material/Refresh';
|
||||||
@@ -22,12 +22,28 @@ export const CropTool: React.FC<CropToolProps> = ({
|
|||||||
onSkip,
|
onSkip,
|
||||||
}) => {
|
}) => {
|
||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
|
const imageAreaRef = useRef<HTMLDivElement>(null);
|
||||||
|
const [imageMaxHeight, setImageMaxHeight] = useState(0);
|
||||||
|
|
||||||
const { cropArea, isDragging, resetCrop, executeCrop, handleDragStart } =
|
const { cropArea, isDragging, resetCrop, executeCrop, handleDragStart } =
|
||||||
useImageCrop({
|
useImageCrop({
|
||||||
aspectRatio: lockAspectRatio ? aspectRatio : undefined,
|
aspectRatio: lockAspectRatio ? aspectRatio : undefined,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Measure available height for the image so the crop container
|
||||||
|
// matches the rendered image exactly (fixes mobile crop offset)
|
||||||
|
useEffect(() => {
|
||||||
|
const updateMaxHeight = () => {
|
||||||
|
if (imageAreaRef.current) {
|
||||||
|
const rect = imageAreaRef.current.getBoundingClientRect();
|
||||||
|
setImageMaxHeight(rect.height - 32); // subtract p:2 padding (16px * 2)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
updateMaxHeight();
|
||||||
|
window.addEventListener('resize', updateMaxHeight);
|
||||||
|
return () => window.removeEventListener('resize', updateMaxHeight);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleConfirm = useCallback(async () => {
|
const handleConfirm = useCallback(async () => {
|
||||||
setIsProcessing(true);
|
setIsProcessing(true);
|
||||||
try {
|
try {
|
||||||
@@ -61,6 +77,7 @@ export const CropTool: React.FC<CropToolProps> = ({
|
|||||||
>
|
>
|
||||||
{/* Image with crop overlay */}
|
{/* Image with crop overlay */}
|
||||||
<Box
|
<Box
|
||||||
|
ref={imageAreaRef}
|
||||||
sx={{
|
sx={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
@@ -75,8 +92,6 @@ export const CropTool: React.FC<CropToolProps> = ({
|
|||||||
data-crop-container
|
data-crop-container
|
||||||
sx={{
|
sx={{
|
||||||
position: 'relative',
|
position: 'relative',
|
||||||
maxWidth: '100%',
|
|
||||||
maxHeight: '100%',
|
|
||||||
userSelect: 'none',
|
userSelect: 'none',
|
||||||
touchAction: isDragging ? 'none' : 'auto',
|
touchAction: isDragging ? 'none' : 'auto',
|
||||||
}}
|
}}
|
||||||
@@ -87,7 +102,7 @@ export const CropTool: React.FC<CropToolProps> = ({
|
|||||||
alt="Captured"
|
alt="Captured"
|
||||||
style={{
|
style={{
|
||||||
maxWidth: '100%',
|
maxWidth: '100%',
|
||||||
maxHeight: '100%',
|
maxHeight: imageMaxHeight > 0 ? `${imageMaxHeight}px` : '70vh',
|
||||||
display: 'block',
|
display: 'block',
|
||||||
}}
|
}}
|
||||||
draggable={false}
|
draggable={false}
|
||||||
|
|||||||
Reference in New Issue
Block a user