Search code examples
reactjszoomingpreviewimage-gallery

React image gallery with magnify effect like Amazon


I try to combine react-image-gallery with react-image-magnify to get gallery with magnify preview effect and according to react-image-gallery docs I am passing MyReactImageMagnify component to the renderItem prop on the ImageGallery component but there is no magnified image on the right side.

Here is how the gallery with magnify should look like https://www.amazon.com/Samsung-MicroSD-Adapter-MB-ME128GA-AM/dp/B06XWZWYVP

And here is the codesandbox with what I have so far https://codesandbox.io/s/goofy-lumiere-gk1y1

class MyImageGallery extends Component {
  myRenderItem() {
    return <MyReactImageMagnify {...this.props} />;
  }

  render() {
    const properties = {
      thumbnailPosition: "left",
      useBrowserFullscreen: false,
      showPlayButton: false,
      renderItem: this.myRenderItem.bind(this),
      items: [
        {
          original: "https://placeimg.com/640/480/any/1",
          thumbnail: "https://placeimg.com/250/150/any/1"
        },
        {
          original: "https://placeimg.com/640/480/any/2",
          thumbnail: "https://placeimg.com/250/150/any/2"
        },
        {
          original: "https://placeimg.com/640/480/any/3",
          thumbnail: "https://placeimg.com/250/150/any/3"
        }
      ]
    };

    return <ImageGallery {...properties} />;
  }
}

Edit: Amazon is just for illustration of "magnify to the right". I made another codesandbox with 2 columns grid, you can see how plain <MyReactImageMagnify /> component works and <MyImageGallery /> doesn't. https://codesandbox.io/s/practical-browser-0dbyo


Solution

  • I think the problem is with an element overflow. The gallery uses an overflow: hidden to hide the not visible slides, so the zoomed image is also hidden.

    The good thing about react-image-magnify is that you can specify a portal where you want to render the large image.

    Here's the sandbox: https://codesandbox.io/s/xenodochial-rosalind-g9ve4

    Create a new div with an id, where you want the large image to be displayed:

    <Grid container spacing={4}>
      <Grid item xs={6}>
        <MyImageGallery />
      </Grid>
      <Grid container spacing={2} item xs={6} direction="column">
        <Grid item>
          <div id="myPortal" />
        </Grid>
      </Grid>
    </Grid>
    

    Each element of the gallery will be a ReactImageMagnify component, with the portal id as a property:

    <ReactImageMagnify
      {...{
        smallImage: {
          alt: "Wristwatch by Ted Baker London",
          isFluidWidth: true,
          src: "https://placeimg.com/640/480/any"
        },
        largeImage: {
          src: "https://placeimg.com/640/480/any",
          width: 640,
          height: 480
        },
        enlargedImagePortalId: "myPortal"
      }}
    />