완성된 작동

원하는 동작

 const [isZoomed, setIsZoomed] = useState(false);

<TransformWrapper
      doubleClick={{
        mode: isZoomed ? "reset" : "zoomIn",
      }}
      onZoom={handleZoomChange}
 >

더블 클릭을 할 때 zoom reset과 zoomIn이 반복되게 하려고 했는데 zoom react-zoom-pan-pinch에서 제공하는 doubleClick mode의 toggle 옵션이 zoomIn과 zoomOut 이었기 때문에 새롭게 개발해야 했습니다.

문제점

1. 리셋을 하고 다시 확대를 위해 더블클릭을 할 때 확대가 안되는 상황 발생

const handleZoomChange = useCallback((ref: ReactZoomPanPinchRef) => {
    setIsZoomed(ref.state.scale > 1);
  }, []);

원인 파악

reset으로 되돌렸을 때 onZoom의 scale값이 변경이 되지 않아 isZoomed의 그대로였습니다.

해결 방안

const handleZoomStop = useCallback((ref: ReactZoomPanPinchRef) => {
    setIsZoomed(ref.state.scale > 1);
  }, []);

<TransformWrapper
      doubleClick={{
        mode: isZoomed ? "reset" : "zoomIn",
      }}
      onZoom={handleZoomChange}
      onZoomStop={handleZoomStop}
    >

onZoomStop에는 값이 잡히는 것을 확인하고 handleZoomStop 함수를 만들어 상태를 변경했습니다.

 

2. 이전과 비슷한 상황 발생

1.0070850997085246
1.0022412078754446
1.0062173879994554
1.0000623005967615
1.0121620352209324
1.0005606131442053

원인 파악

reset 했을 때 디버깅 해본 결과 scale의 값이 완전한 1로 되지 않고 근사값으로 초기화 되는 것을 발견했습니다

해결 방안

const handleZoomStop = useCallback((ref: ReactZoomPanPinchRef) => {
    // 1 -> 1.05
    setIsZoomed(ref.state.scale > 1.05);
  }, []);

앞선 값들을 바탕으로 오차 범위까지 고려하여 isZoomed가 true가 되는 값의 범위를 수정했습니다.

 

마무리

  • 기존 라이브러리의 기능을 그대로 사용하지 않고 원하는 기능을 커스텀 해서 사용해봤습니다.

+ Recent posts