diff --git a/src/components/FileUpload.tsx b/src/components/FileUpload.tsx index 3ad24c4..2f7e54e 100644 --- a/src/components/FileUpload.tsx +++ b/src/components/FileUpload.tsx @@ -17,6 +17,10 @@ import { } from "../utils/rotationUtils"; import { encodeStitchesToPen } from "../formats/pen/encoder"; import { decodePenData } from "../formats/pen/decoder"; +import { + calculatePatternCenter, + calculateBoundsFromDecodedStitches, +} from "./PatternCanvas/patternCanvasHelpers"; import { PatternInfoSkeleton } from "./SkeletonLoader"; import { PatternInfo } from "./PatternInfo"; import { @@ -154,11 +158,6 @@ export function FileUpload() { // Apply rotation if needed if (patternRotation && patternRotation !== 0) { - console.log( - "[FileUpload] Applying rotation before upload:", - patternRotation, - ); - // Transform stitches const rotatedStitches = transformStitchesRotation( pesData.stitches, @@ -174,57 +173,25 @@ export function FileUpload() { const decoded = decodePenData(penDataToUpload); // Calculate bounds from the DECODED stitches (the actual data that will be rendered) - let decodedMinX = Infinity, - decodedMaxX = -Infinity; - let decodedMinY = Infinity, - decodedMaxY = -Infinity; - for (const stitch of decoded.stitches) { - if (stitch.x < decodedMinX) decodedMinX = stitch.x; - if (stitch.x > decodedMaxX) decodedMaxX = stitch.x; - if (stitch.y < decodedMinY) decodedMinY = stitch.y; - if (stitch.y > decodedMaxY) decodedMaxY = stitch.y; - } - const rotatedBounds = { - minX: decodedMinX, - maxX: decodedMaxX, - minY: decodedMinY, - maxY: decodedMaxY, - }; + const rotatedBounds = calculateBoundsFromDecodedStitches(decoded); // Calculate the center of the rotated pattern - const originalCenterX = (pesData.bounds.minX + pesData.bounds.maxX) / 2; - const originalCenterY = (pesData.bounds.minY + pesData.bounds.maxY) / 2; - const rotatedCenterX = (rotatedBounds.minX + rotatedBounds.maxX) / 2; - const rotatedCenterY = (rotatedBounds.minY + rotatedBounds.maxY) / 2; - const centerShiftX = rotatedCenterX - originalCenterX; - const centerShiftY = rotatedCenterY - originalCenterY; - - console.log("[FileUpload] Pattern centers:", { - originalCenter: { x: originalCenterX, y: originalCenterY }, - rotatedCenter: { x: rotatedCenterX, y: rotatedCenterY }, - centerShift: { x: centerShiftX, y: centerShiftY }, - }); + const originalCenter = calculatePatternCenter(pesData.bounds); + const rotatedCenter = calculatePatternCenter(rotatedBounds); + const centerShiftX = rotatedCenter.x - originalCenter.x; + const centerShiftY = rotatedCenter.y - originalCenter.y; // CRITICAL: Adjust position to compensate for the center shift! // In Konva, visual position = (x - offsetX, y - offsetY). - // Original visual pos: (x - originalCenterX, y - originalCenterY) - // New visual pos: (newX - rotatedCenterX, newY - rotatedCenterY) - // For same visual position: newX = x + (rotatedCenterX - originalCenterX) + // Original visual pos: (x - originalCenter.x, y - originalCenter.y) + // New visual pos: (newX - rotatedCenter.x, newY - rotatedCenter.y) + // For same visual position: newX = x + (rotatedCenter.x - originalCenter.x) // So we need to add (rotatedCenter - originalCenter) to the position. const adjustedOffset = { x: patternOffset.x + centerShiftX, y: patternOffset.y + centerShiftY, }; - console.log( - "[FileUpload] Adjusting position to compensate for center shift:", - { - originalPosition: patternOffset, - adjustedPosition: adjustedOffset, - shift: { x: centerShiftX, y: centerShiftY }, - }, - ); - // Create rotated PesPatternData for upload pesDataForUpload = { ...pesData, @@ -236,7 +203,6 @@ export function FileUpload() { // Save uploaded pattern to store for preview BEFORE starting upload // This allows the preview to show immediately when isUploading becomes true - console.log("[FileUpload] Saving uploaded pattern for preview"); setUploadedPattern(pesDataForUpload, adjustedOffset); // Upload the pattern with offset @@ -287,29 +253,13 @@ export function FileUpload() { // The patternOffset represents the pattern's CENTER position (due to offsetX/offsetY in canvas) // So we need to calculate bounds relative to the center - const centerX = (bounds.minX + bounds.maxX) / 2; - const centerY = (bounds.minY + bounds.maxY) / 2; + const center = calculatePatternCenter(bounds); // Calculate actual bounds in world coordinates - const patternMinX = patternOffset.x - centerX + bounds.minX; - const patternMaxX = patternOffset.x - centerX + bounds.maxX; - const patternMinY = patternOffset.y - centerY + bounds.minY; - const patternMaxY = patternOffset.y - centerY + bounds.maxY; - - console.log("[Bounds Check] Pattern center:", { centerX, centerY }); - console.log("[Bounds Check] Offset (center position):", patternOffset); - console.log("[Bounds Check] Pattern bounds with offset:", { - minX: patternMinX, - maxX: patternMaxX, - minY: patternMinY, - maxY: patternMaxY, - }); - console.log("[Bounds Check] Hoop bounds:", { - minX: -maxWidth / 2, - maxX: maxWidth / 2, - minY: -maxHeight / 2, - maxY: maxHeight / 2, - }); + const patternMinX = patternOffset.x - center.x + bounds.minX; + const patternMaxX = patternOffset.x - center.x + bounds.maxX; + const patternMinY = patternOffset.y - center.y + bounds.minY; + const patternMaxY = patternOffset.y - center.y + bounds.maxY; // Hoop bounds (centered at origin) const hoopMinX = -maxWidth / 2; diff --git a/src/components/PatternCanvas/PatternLayer.tsx b/src/components/PatternCanvas/PatternLayer.tsx index 5d6535e..d104877 100644 --- a/src/components/PatternCanvas/PatternLayer.tsx +++ b/src/components/PatternCanvas/PatternLayer.tsx @@ -55,16 +55,6 @@ export function PatternLayer({ const groupName = isInteractive ? "pattern-group" : "uploaded-pattern-group"; - console.log( - `[PatternLayer] Rendering ${isInteractive ? "original" : "uploaded"} pattern:`, - { - position: offset, - rotation: isInteractive ? rotation : "n/a", - center, - bounds: pesData.bounds, - }, - ); - return ( <> maxX) maxX = stitch.x; + if (stitch.y < minY) minY = stitch.y; + if (stitch.y > maxY) maxY = stitch.y; + } + + return { minX, maxX, minY, maxY }; +} + /** * Calculate new stage position for zooming towards a specific point * Used for both wheel zoom and button zoom operations diff --git a/src/utils/rotationUtils.ts b/src/utils/rotationUtils.ts index 9724602..bcd9d1a 100644 --- a/src/utils/rotationUtils.ts +++ b/src/utils/rotationUtils.ts @@ -1,3 +1,5 @@ +import { calculatePatternCenter } from "../components/PatternCanvas/patternCanvasHelpers"; + /** * Rotate a single point around a center */ @@ -31,11 +33,10 @@ export function transformStitchesRotation( ): number[][] { if (angleDegrees === 0 || angleDegrees === 360) return stitches; - const centerX = (bounds.minX + bounds.maxX) / 2; - const centerY = (bounds.minY + bounds.maxY) / 2; + const center = calculatePatternCenter(bounds); return stitches.map(([x, y, cmd, colorIndex]) => { - const rotated = rotatePoint(x, y, centerX, centerY, angleDegrees); + const rotated = rotatePoint(x, y, center.x, center.y, angleDegrees); return [Math.round(rotated.x), Math.round(rotated.y), cmd, colorIndex]; }); } @@ -49,8 +50,7 @@ export function calculateRotatedBounds( ): { minX: number; maxX: number; minY: number; maxY: number } { if (angleDegrees === 0 || angleDegrees === 360) return bounds; - const centerX = (bounds.minX + bounds.maxX) / 2; - const centerY = (bounds.minY + bounds.maxY) / 2; + const center = calculatePatternCenter(bounds); // Rotate all four corners const corners = [ @@ -61,7 +61,7 @@ export function calculateRotatedBounds( ]; const rotatedCorners = corners.map(([x, y]) => - rotatePoint(x, y, centerX, centerY, angleDegrees), + rotatePoint(x, y, center.x, center.y, angleDegrees), ); return {