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

Fit to screen

Open ignlopezsanchez opened this issue 1 year ago • 6 comments

Is your feature request related to a problem? Please describe. I need to add a functionality to 'fit to screen' ,for example for content very wide.

Describe the solution you'd like A function to adjust the scale automatically to have all content inside wrapper.

Describe alternatives you've considered At the moment I do not know hoy to solve it

ignlopezsanchez avatar May 11 '23 12:05 ignlopezsanchez

Hi, can you show an example of what are you trying to do?

cojoclaudiu avatar May 11 '23 12:05 cojoclaudiu

Hi, can you show an example of what are you trying to do?

Imagine a very big diagram. And it is very wide. At scale of 1 (100%) you can't see everything because it is bigger than the container. With a fit to screen function, the scale would be automatically set in order to have all content visible. In our example, scale would be lower than 1 in order to make content smaller and visible.

ignlopezsanchez avatar May 11 '23 13:05 ignlopezsanchez

Have same problem. Did you find any solution to this?

LeszekKld avatar May 18 '23 13:05 LeszekKld

If one of you provide the codesandbox example I can come up with a solution

cojoclaudiu avatar May 18 '23 14:05 cojoclaudiu

If one of you provide the codesandbox example I can come up with a solution

I think we cannot provide a codesandbox as this is a requested feature. Let me know if what I said it is not clear and I will try to explain.

ignlopezsanchez avatar Jun 29 '23 10:06 ignlopezsanchez

I've found a way to do this, you can either use the centerView or setTransform handler functions. If you have a ref to the wrapper component (something that might have a fixed width / height on your page) and also a ref to the actual content itself (you can wrap it in a div and attach the ref to that), then you can easily calculate the "scale" needed to call one of the above functions. For example:

  // assume wrapperRef and contentRef are declared here in the component

  const fitContentToWrapper = useCallback(
    (centerView: (scale: number) => void) => {
      if (wrapperRef.current && contentRef.current) {
        const wrapperWidth = wrapperRef.current.clientWidth;
        const wrapperHeight = wrapperRef.current.clientHeight;

        const contentWidth = contentRef.current.clientWidth;
        const contentHeight = contentRef.current.clientHeight;

        const widthScale = wrapperWidth / contentWidth;
        const heightScale = wrapperHeight / contentHeight;

        const scale = widthScale < heightScale ? widthScale : heightScale;

        centerView(scale);
      }
    },
    []
  );

  ...

  return (
    <div ref={wrapperRef}>
      <TransformWrapper>
        {({ centerView }) => (
          <>
            <div className="tools">
              <button onClick={() => fitContentToWrapper(centerView)}>fit</button>
            </div>
            <TransformComponent>
              <div ref={contentRef}>{CONTENT HERE}</div>
            </TransformComponent>
          </>
        )}
      </TransformWrapper>
    </div>
  );

I can confirm that this works for my use case.

cliffsun91 avatar Jul 03 '23 11:07 cliffsun91