react-zoom-pan-pinch icon indicating copy to clipboard operation
react-zoom-pan-pinch copied to clipboard

Is there any way to do rotate in this library?

Open Tamagouuu opened this issue 11 months ago • 5 comments

It will be good if the viewer have ability to rotate, isn't it?

Tamagouuu avatar Mar 04 '24 05:03 Tamagouuu

It is also necessary for me

hadarhubara10 avatar Mar 31 '24 13:03 hadarhubara10

I implemented rotation outside of the lib by doing something like this:

given the ref to an image:

  const imageRef = useRef<HTMLImageElement>(null)

I implemented and exposed the following API (through a custom context):

    const rotateClockwise = useCallback(() => {
      if (!imageRef?.current) return
      setRotation((rotation) => {
        const newRotation = (rotation + 90) % 360
        imageRef.current!.style.transform = `rotate(${newRotation}deg)`
        return newRotation
      })
    }, [setRotation, imageRef]);
    const rotateCounterClockwise = useCallback(() => {
      if (!imageRef?.current) return
      setRotation((rotation) => {
        const newRotation = (rotation - 90) % 360
        imageRef.current!.style.transform = `rotate(${newRotation}deg)`
        return newRotation
      })
    }, [setRotation, imageRef]);

Then I implemented it on the image itself:

  return (
      <TransformWrapper>
        <ImageControls />
        <TransformComponent>
          <img ref={imageRef} id="img" src={uri} />
        </TransformComponent>
      </TransformWrapper>
   )

then the ImageControls is just a custom version of the default Controls that implements both useControls() for the lib and my own context.

TBH, if I got little time, I believe it can be easy to add to the API

HTH

guyzmo avatar May 30 '24 22:05 guyzmo

This should be a pull request.

vojdan avatar Jul 22 '24 21:07 vojdan

This solution doesnt update the trasform wrapper/component rotation thus it make the panning bugged. Im searching for an alternative solution, did anyone found something yet?

Trisogene avatar Jul 26 '24 06:07 Trisogene

Setting the width and height in the wrapper and content wrapper with an !important fixed the panning issue for me, and centering the content with flex if your alignment is off.

const [rotation, setRotation] = React.useState(0);

const rotateClockwise = useCallback(() => {
    setRotation(rotation => {
        const newRotation = (rotation + 90) % 360;
        return newRotation;
     });
}, [setRotation]);

const rotateAnticlockwise = useCallback(() => {
    setRotation(rotation => {
        const newRotation = (rotation - 90) % 360;
        return newRotation;
    });
}, [setRotation]);


return (
    <TransformWrapper>
       <TransformComponent
           wrapperClass="!h-screen !w-screen"
           contentClass="!h-screen !w-full flex items-center justify-center"
        >
            <picture>
                <img
                   src={src}
                   style={{
                       objectFit: "cover",
                       maxHeight: "100vh",
                       maxWidth: "100vw",
                       transform: `rotate(${rotation}deg)`
                   }}
                />
            </picture>
        </TransformComponent>
     </TransformWrapper>

     <button onClick={() => rotateClockwise()} >Rotate clockwise</button>
     <button onClick={() => rotateAnticlockwise()} >Rotate Anticlockwise</button>
)

abrasumente999 avatar Jul 26 '24 13:07 abrasumente999