mirror of
https://github.com/jhbruhn/respira.git
synced 2026-01-27 10:23:41 +00:00
Merge pull request #47 from jhbruhn/fix/30-eslint-hook-rules-useCanvasViewport
fix: Refactor useCanvasViewport to eliminate ESLint hook warnings
This commit is contained in:
commit
3ec9dda235
1 changed files with 35 additions and 44 deletions
|
|
@ -5,13 +5,7 @@
|
||||||
* Handles wheel zoom and button zoom operations
|
* Handles wheel zoom and button zoom operations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import { useState, useEffect, useCallback, type RefObject } from "react";
|
||||||
useState,
|
|
||||||
useEffect,
|
|
||||||
useCallback,
|
|
||||||
useRef,
|
|
||||||
type RefObject,
|
|
||||||
} from "react";
|
|
||||||
import type Konva from "konva";
|
import type Konva from "konva";
|
||||||
import type { PesPatternData } from "../formats/import/pesImporter";
|
import type { PesPatternData } from "../formats/import/pesImporter";
|
||||||
import type { MachineInfo } from "../types/machine";
|
import type { MachineInfo } from "../types/machine";
|
||||||
|
|
@ -34,8 +28,11 @@ export function useCanvasViewport({
|
||||||
const [stagePos, setStagePos] = useState({ x: 0, y: 0 });
|
const [stagePos, setStagePos] = useState({ x: 0, y: 0 });
|
||||||
const [stageScale, setStageScale] = useState(1);
|
const [stageScale, setStageScale] = useState(1);
|
||||||
const [containerSize, setContainerSize] = useState({ width: 0, height: 0 });
|
const [containerSize, setContainerSize] = useState({ width: 0, height: 0 });
|
||||||
const initialScaleRef = useRef<number>(1);
|
const [initialScale, setInitialScale] = useState(1);
|
||||||
const prevPesDataRef = useRef<PesPatternData | null>(null);
|
|
||||||
|
// Track the last processed pattern to detect changes during render
|
||||||
|
const [lastProcessedPattern, setLastProcessedPattern] =
|
||||||
|
useState<PesPatternData | null>(null);
|
||||||
|
|
||||||
// Track container size with ResizeObserver
|
// Track container size with ResizeObserver
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|
@ -59,19 +56,14 @@ export function useCanvasViewport({
|
||||||
return () => resizeObserver.disconnect();
|
return () => resizeObserver.disconnect();
|
||||||
}, [containerRef]);
|
}, [containerRef]);
|
||||||
|
|
||||||
// Calculate and store initial scale when pattern or hoop changes
|
// Reset viewport when pattern changes (during render, not in effect)
|
||||||
useEffect(() => {
|
// This follows the React-recommended pattern for deriving state from props
|
||||||
// Use whichever pattern is available (uploaded or original)
|
|
||||||
const currentPattern = uploadedPesData || pesData;
|
const currentPattern = uploadedPesData || pesData;
|
||||||
if (!currentPattern || containerSize.width === 0) {
|
if (
|
||||||
prevPesDataRef.current = null;
|
currentPattern &&
|
||||||
return;
|
currentPattern !== lastProcessedPattern &&
|
||||||
}
|
containerSize.width > 0
|
||||||
|
) {
|
||||||
// Only recalculate if pattern changed
|
|
||||||
if (prevPesDataRef.current !== currentPattern) {
|
|
||||||
prevPesDataRef.current = currentPattern;
|
|
||||||
|
|
||||||
const { bounds } = currentPattern;
|
const { bounds } = currentPattern;
|
||||||
const viewWidth = machineInfo
|
const viewWidth = machineInfo
|
||||||
? machineInfo.maxWidth
|
? machineInfo.maxWidth
|
||||||
|
|
@ -80,20 +72,20 @@ export function useCanvasViewport({
|
||||||
? machineInfo.maxHeight
|
? machineInfo.maxHeight
|
||||||
: bounds.maxY - bounds.minY;
|
: bounds.maxY - bounds.minY;
|
||||||
|
|
||||||
const initialScale = calculateInitialScale(
|
const newInitialScale = calculateInitialScale(
|
||||||
containerSize.width,
|
containerSize.width,
|
||||||
containerSize.height,
|
containerSize.height,
|
||||||
viewWidth,
|
viewWidth,
|
||||||
viewHeight,
|
viewHeight,
|
||||||
);
|
);
|
||||||
initialScaleRef.current = initialScale;
|
|
||||||
|
|
||||||
// Reset view when pattern changes
|
// Update state during render when pattern changes
|
||||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
// This is the recommended React pattern for resetting state based on props
|
||||||
setStageScale(initialScale);
|
setLastProcessedPattern(currentPattern);
|
||||||
|
setInitialScale(newInitialScale);
|
||||||
|
setStageScale(newInitialScale);
|
||||||
setStagePos({ x: containerSize.width / 2, y: containerSize.height / 2 });
|
setStagePos({ x: containerSize.width / 2, y: containerSize.height / 2 });
|
||||||
}
|
}
|
||||||
}, [pesData, uploadedPesData, machineInfo, containerSize]);
|
|
||||||
|
|
||||||
// Wheel zoom handler
|
// Wheel zoom handler
|
||||||
const handleWheel = useCallback((e: Konva.KonvaEventObject<WheelEvent>) => {
|
const handleWheel = useCallback((e: Konva.KonvaEventObject<WheelEvent>) => {
|
||||||
|
|
@ -159,10 +151,9 @@ export function useCanvasViewport({
|
||||||
}, [containerSize]);
|
}, [containerSize]);
|
||||||
|
|
||||||
const handleZoomReset = useCallback(() => {
|
const handleZoomReset = useCallback(() => {
|
||||||
const initialScale = initialScaleRef.current;
|
|
||||||
setStageScale(initialScale);
|
setStageScale(initialScale);
|
||||||
setStagePos({ x: containerSize.width / 2, y: containerSize.height / 2 });
|
setStagePos({ x: containerSize.width / 2, y: containerSize.height / 2 });
|
||||||
}, [containerSize]);
|
}, [initialScale, containerSize]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
// State
|
// State
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue