mirror of
https://github.com/Stirling-Tools/Stirling-PDF.git
synced 2025-09-22 19:46:39 +00:00
Positioning and logic fixes
This commit is contained in:
parent
5a24e00497
commit
03eda04aec
@ -43,7 +43,7 @@ const CropAreaSelector: React.FC<CropAreaSelectorProps> = ({
|
||||
// Convert PDF crop area to DOM coordinates for display
|
||||
const domRect = pdfToDOMCoordinates(cropArea, pdfBounds);
|
||||
|
||||
// Handle mouse down on overlay (start dragging)
|
||||
// Handle mouse down on overlay (start dragging or resizing)
|
||||
const handleOverlayMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
if (disabled || !containerRef.current) return;
|
||||
|
||||
@ -54,19 +54,19 @@ const CropAreaSelector: React.FC<CropAreaSelectorProps> = ({
|
||||
const x = e.clientX - rect.left;
|
||||
const y = e.clientY - rect.top;
|
||||
|
||||
// Check if we're clicking on a resize handle
|
||||
// Check if we're clicking on a resize handle first (higher priority)
|
||||
const handle = getResizeHandle(x, y, domRect);
|
||||
|
||||
if (handle) {
|
||||
setIsResizing(handle);
|
||||
setInitialCropArea(cropArea);
|
||||
} else {
|
||||
// Check if we're clicking within the crop area for dragging
|
||||
if (isPointInCropArea(x, y, domRect)) {
|
||||
setIsDragging(false); // Ensure we're not dragging when resizing
|
||||
} else if (isPointInCropArea(x, y, domRect)) {
|
||||
// Only allow dragging if we're not on a resize handle
|
||||
setIsDragging(true);
|
||||
setIsResizing(null); // Ensure we're not resizing when dragging
|
||||
setDragStart({ x: x - domRect.x, y: y - domRect.y });
|
||||
}
|
||||
}
|
||||
}, [disabled, cropArea, domRect]);
|
||||
|
||||
// Handle mouse down on container (start new selection)
|
||||
@ -211,15 +211,15 @@ const CropAreaSelector: React.FC<CropAreaSelectorProps> = ({
|
||||
|
||||
function getResizeHandle(x: number, y: number, domRect: DOMRect): ResizeHandle {
|
||||
const handleSize = 8;
|
||||
const tolerance = 4;
|
||||
const tolerance = handleSize;
|
||||
|
||||
// Corner handles
|
||||
// Corner handles (check these first, they have priority)
|
||||
if (isNear(x, domRect.x, tolerance) && isNear(y, domRect.y, tolerance)) return 'nw';
|
||||
if (isNear(x, domRect.x + domRect.width, tolerance) && isNear(y, domRect.y, tolerance)) return 'ne';
|
||||
if (isNear(x, domRect.x, tolerance) && isNear(y, domRect.y + domRect.height, tolerance)) return 'sw';
|
||||
if (isNear(x, domRect.x + domRect.width, tolerance) && isNear(y, domRect.y + domRect.height, tolerance)) return 'se';
|
||||
|
||||
// Edge handles
|
||||
// Edge handles (only if not in corner area)
|
||||
if (isNear(x, domRect.x + domRect.width / 2, tolerance) && isNear(y, domRect.y, tolerance)) return 'n';
|
||||
if (isNear(x, domRect.x + domRect.width, tolerance) && isNear(y, domRect.y + domRect.height / 2, tolerance)) return 'e';
|
||||
if (isNear(x, domRect.x + domRect.width / 2, tolerance) && isNear(y, domRect.y + domRect.height, tolerance)) return 's';
|
||||
|
@ -1,28 +1,24 @@
|
||||
import React, { useMemo, useState, useEffect } from "react";
|
||||
import { useMemo, useState, useEffect } from "react";
|
||||
import { Stack, Text, Box, Group, NumberInput, ActionIcon, Center, Alert } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import RestartAltIcon from "@mui/icons-material/RestartAlt";
|
||||
import InfoIcon from "@mui/icons-material/Info";
|
||||
import { CropParametersHook } from "../../../hooks/tools/crop/useCropParameters";
|
||||
import { useSelectedFiles } from "../../../contexts/file/fileHooks";
|
||||
import { useFileContext } from "../../../contexts/FileContext";
|
||||
import DocumentThumbnail from "../../shared/filePreview/DocumentThumbnail";
|
||||
import CropAreaSelector from "./CropAreaSelector";
|
||||
import {
|
||||
calculatePDFBounds,
|
||||
PDFBounds,
|
||||
CropArea,
|
||||
getPDFAspectRatio,
|
||||
createFullPDFCropArea
|
||||
CropArea
|
||||
} from "../../../utils/cropCoordinates";
|
||||
import { pdfWorkerManager } from "../../../services/pdfWorkerManager";
|
||||
import DocumentThumbnail from "../../shared/filePreview/DocumentThumbnail";
|
||||
|
||||
interface CropSettingsProps {
|
||||
parameters: CropParametersHook;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const CONTAINER_SIZE = 400; // Larger container for better crop precision
|
||||
const CONTAINER_SIZE = 250; // Fit within actual pane width
|
||||
|
||||
const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
@ -41,7 +37,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
// Get thumbnail for the selected file
|
||||
const [thumbnail, setThumbnail] = useState<string | null>(null);
|
||||
const [pdfBounds, setPdfBounds] = useState<PDFBounds | null>(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const loadPDFDimensions = async () => {
|
||||
@ -52,7 +47,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
}
|
||||
|
||||
setThumbnail(selectedStub.thumbnailUrl || null);
|
||||
setLoading(true);
|
||||
|
||||
try {
|
||||
// Get PDF dimensions from the actual file
|
||||
@ -95,8 +89,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
if (parameters.parameters.width === 595 && parameters.parameters.height === 842) {
|
||||
parameters.resetToFullPDF(bounds);
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@ -106,6 +98,7 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
// Current crop area
|
||||
const cropArea = parameters.getCropArea();
|
||||
|
||||
|
||||
// Handle crop area changes from the selector
|
||||
const handleCropAreaChange = (newCropArea: CropArea) => {
|
||||
if (pdfBounds) {
|
||||
@ -139,19 +132,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
return Math.round((cropAreaSize / totalArea) * 100);
|
||||
}, [cropArea, pdfBounds]);
|
||||
|
||||
// Get aspect ratio information
|
||||
const aspectRatioInfo = useMemo(() => {
|
||||
if (!pdfBounds) return null;
|
||||
const pdfRatio = getPDFAspectRatio(pdfBounds);
|
||||
const cropRatio = cropArea.width / cropArea.height;
|
||||
|
||||
return {
|
||||
pdf: pdfRatio.toFixed(2),
|
||||
crop: cropRatio.toFixed(2),
|
||||
orientation: pdfRatio > 1 ? 'Landscape' : 'Portrait'
|
||||
};
|
||||
}, [pdfBounds, cropArea]);
|
||||
|
||||
if (!selectedStub || !pdfBounds) {
|
||||
return (
|
||||
<Center style={{ height: '200px' }}>
|
||||
@ -222,14 +202,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
<Text size="xs" color="dimmed">
|
||||
{t("crop.info.percentage", "Area: {{percentage}}%", { percentage: cropPercentage })}
|
||||
</Text>
|
||||
{aspectRatioInfo && (
|
||||
<Text size="xs" color="dimmed">
|
||||
{t("crop.info.ratio", "Ratio: {{ratio}} ({{orientation}})", {
|
||||
ratio: aspectRatioInfo.crop,
|
||||
orientation: parseFloat(aspectRatioInfo.crop) > 1 ? 'Landscape' : 'Portrait'
|
||||
})}
|
||||
</Text>
|
||||
)}
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@ -289,28 +261,6 @@ const CropSettings = ({ parameters, disabled = false }: CropSettingsProps) => {
|
||||
/>
|
||||
</Group>
|
||||
|
||||
{/* PDF Dimensions Info */}
|
||||
<Alert
|
||||
icon={<InfoIcon />}
|
||||
color="blue"
|
||||
variant="light"
|
||||
style={{ fontSize: '0.75rem' }}
|
||||
>
|
||||
<Text size="xs">
|
||||
{t("crop.info.pdfDimensions", "PDF Size: {{width}} × {{height}} points", {
|
||||
width: Math.round(pdfBounds.actualWidth),
|
||||
height: Math.round(pdfBounds.actualHeight)
|
||||
})}
|
||||
</Text>
|
||||
{aspectRatioInfo && (
|
||||
<Text size="xs">
|
||||
{t("crop.info.aspectRatio", "Aspect Ratio: {{ratio}} ({{orientation}})", {
|
||||
ratio: aspectRatioInfo.pdf,
|
||||
orientation: aspectRatioInfo.orientation
|
||||
})}
|
||||
</Text>
|
||||
)}
|
||||
</Alert>
|
||||
|
||||
{/* Validation Alert */}
|
||||
{!isCropValid && (
|
||||
|
@ -59,7 +59,7 @@ export const calculatePDFBounds = (
|
||||
const thumbnailWidth = actualPDFWidth * scale;
|
||||
const thumbnailHeight = actualPDFHeight * scale;
|
||||
|
||||
// Calculate centering offsets
|
||||
// Calculate centering offsets - these represent where the thumbnail is positioned within the container
|
||||
const offsetX = (containerWidth - thumbnailWidth) / 2;
|
||||
const offsetY = (containerHeight - thumbnailHeight) / 2;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user