React Material Image List With Magnification

Overview

This short article will quickly go over how to build an image viewer with zoom similar to Amazon’s product viewing page. The image viewer component will have multiple images to choose from and can zoom in. The zoom feature is similar to what you see in Amazon when viewing a product. This is especially useful when displaying products for an e-commerce site.

Libraries Needed

MUI – Material UI v5.4.3

Material UI library for React

npm install @mui/material @mui/lab @emotion/react @emotion/styled

react-image-magnifiers has multiple option for image magnification. This example uses the side by side component.

npm install react-image-magnifiers

Image Magnify Component

Below is the source for ‘.\ImageMagnify.js’. This component takes an array of images that are in the ‘.\public’ folder and displays a MUI image list and SideBySideMagnifier with a single image. The SideBySideMagnifier from react-image-magnifiers is used to show the magnified image on the right side.

With the  mouseActivation property set to MOUSE_ACTIVATION.SINGLE_CLICK, the image magnification starts when the mouse hovers over the single image. TOUCH_ACTIVATION is set for mobile devices.

import React, { Component } from 'react';
import ImageList from '@mui/material/ImageList';
import ImageListItem from '@mui/material/ImageListItem';
import {
  SideBySideMagnifier,
  MOUSE_ACTIVATION,
  TOUCH_ACTIVATION
} from "react-image-magnifiers";

export default function ImageMagnify(props) {

    const [displayImage, setDisplayImage] = React.useState(props.data[0])
    const handleChangeImage = (img) => {
      setDisplayImage(img)
    }
    return (
        <div>

          <SideBySideMagnifier
              imageSrc={displayImage} 
              imageAlt="Example"
              fillAvailableSpace={false}
              alwaysInPlace={false}
              overlayOpacity={0.6}
              style={{ order: "1"  }}              
              inPlaceMinBreakpoint={641}
              imageAlt="Example"
              largeImageSrc={displayImage} // Optional
              mouseActivation={MOUSE_ACTIVATION.SINGLE_CLICK} // Optional
              touchActivation={TOUCH_ACTIVATION.SINGLE_TAP} // Optional
              zoomContainerBorder="1px solid #ccc"
              zoomContainerBoxShadow="0 4px 8px rgba(0,0,0,.5)"
              //largeImageSrc={props.lgData[0]} // Optional
            />
           <ImageList sx={{ width: 500, height: 450 }} cols={3} rowHeight={164}>
            {props.data.map((item) => (
              <ImageListItem key={item} onClick={() => handleChangeImage(item)} sx={{cursor: 'pointer'}}>
                <img
                  
                  src={`${item}?w=164&h=164&fit=crop&auto=format`}
                  srcSet={`${item}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`}                  
                  loading="lazy"
                />
              </ImageListItem>
            ))}
          </ImageList>
          
            
     
        </div>
    );
}

App Component

Source code below is for ‘app.js’. Import the component above and create an array of multiple images that gets passed to the ImageMagnify component. ImageMagnify is placed inside a MUI Container and Grid to limit the overall width. The alternative is to limit the size of the images in the ‘.\ImageMagnify.js’ file.

import React from "react";
import Grid from "@mui/material/Grid";
import ImageMagnify from "./components/ImageMagnify";
import { Container } from "@mui/material";

export default function App() {
  const imagesData = ["/images/image_1.jpg","/images/image_2.jpg","/images/image_3.jpg"]
          
  return (
      <Container maxWidth='lg' sx={{mt:9}}>
        <Grid container spacing={2}>
          <Grid item xs={3} md={4}>
            <ImageCarouselZoom data={imagesData}/>
  
          </Grid>
          <Grid item xs={4} md={4}>
          </Grid>
        </Grid>        
      </Container>
    );
 
}