DEV Community

Cover image for Build an Image Magnifier Component in ReactJs
margishpatel
margishpatel

Posted on

Build an Image Magnifier Component in ReactJs

React image magnifier tutorial.

Create an Image Magnifier Component in ReactJs. With step-by-step instructions and code examples, you'll learn how to enhance user experience by allowing them to zoom in on images for a closer look. Follow along to build your own customizable image magnifier component and elevate your web development skills!"

Step 1: Setting Up the Component Structure
First, let's establish the basic structure of our image magnifier component. We'll define the component function and set up its initial state.

import React, { useState } from 'react';

function ImageMagnifier({
  src,
  width,
  height,
  magnifierHeight = 100,
  magnifierWidth = 100,
  zoomLevel = 1.5
}) {
  const [[x, y], setXY] = useState([0, 0]);
  const [[imgWidth, imgHeight], setSize] = useState([0, 0]);
  const [showMagnifier, setShowMagnifier] = useState(false);

  // Rest of the component code will be added in subsequent steps
}
Enter fullscreen mode Exit fullscreen mode

Step 2: Managing Mouse Events
Next, let's handle mouse events to control the display of the magnifier when hovering over the image.

<img
  src={src}
  style={{ height: height, width: width }}
  onMouseEnter={(e) => {
    const elem = e.currentTarget;
    const { width, height } = elem.getBoundingClientRect();
    setSize([width, height]);
    setShowMagnifier(true);
  }}
  onMouseMove={(e) => {
    const elem = e.currentTarget;
    const { top, left } = elem.getBoundingClientRect();
    const x = e.pageX - left - window.pageXOffset;
    const y = e.pageY - top - window.pageYOffset;
    setXY([x, y]);
  }}
  onMouseLeave={() => {
    setShowMagnifier(false);
  }}
  alt={"img"}
/>
Enter fullscreen mode Exit fullscreen mode

Step 3: Rendering the Magnifier
Now, let's add the magnifier element and style it based on the cursor position and image dimensions.

<div
  style={{
    display: showMagnifier ? "" : "none",
    position: "absolute",
    pointerEvents: "none",
    height: `${magnifierHeight}px`,
    width: `${magnifierWidth}px`,
    top: `${y - magnifierHeight / 2}px`,
    left: `${x - magnifierWidth / 2}px`,
    opacity: "1",
    border: "1px solid lightgray",
    backgroundColor: "white",
    backgroundImage: `url('${src}')`,
    backgroundRepeat: "no-repeat",
    backgroundSize: `${imgWidth * zoomLevel}px ${imgHeight * zoomLevel}px`,
    backgroundPositionX: `${-x * zoomLevel + magnifierWidth / 2}px`,
    backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`
  }}
></div>
Enter fullscreen mode Exit fullscreen mode

We done it. Here is the full code and a demo:

// ImageMagnifier.js
import { useState } from 'react';

const ImageMagnifier = ({
    src,
    className,
    width,
    height,
    alt,
    magnifierHeight = 150,
    magnifierWidth = 150,
    zoomLevel = 3
}) => {
    const [showMagnifier, setShowMagnifier] = useState(false);
    const [[imgWidth, imgHeight], setSize] = useState([0, 0]);
    const [[x, y], setXY] = useState([0, 0]);

    const mouseEnter = (e) => {
        const el = e.currentTarget;

        const { width, height } = el.getBoundingClientRect();
        setSize([width, height]);
        setShowMagnifier(true);
    }

    const mouseLeave = (e) => {
        e.preventDefault();
        setShowMagnifier(false);
    }

    const mouseMove = (e) => {
        const el = e.currentTarget;
        const { top, left } = el.getBoundingClientRect();

        const x = e.pageX - left - window.scrollX;
        const y = e.pageY - top - window.scrollY;

        setXY([x, y]);
    };

    return <div className="relative inline-block">
        <img
            src={src}
            className={className}
            width={width}
            height={height}
            alt={alt}
            onMouseEnter={(e) => mouseEnter(e)}
            onMouseLeave={(e) => mouseLeave(e)}
            onMouseMove={(e) => mouseMove(e)}
        />
        <div
            style={{
                display: showMagnifier ? '' : 'none',
                position: 'absolute',
                pointerEvents: 'none',
                height: `${magnifierHeight}px`,
                width: `${magnifierWidth}px`,
                opacity: '1',
                border: '1px solid lightgrey',
                backgroundColor: 'white',
                borderRadius: '5px',
                backgroundImage: `url('${src}')`,
                backgroundRepeat: 'no-repeat',
                top: `${y - magnifierHeight / 2}px`,
                left: `${x - magnifierWidth / 2}px`,
                backgroundSize: `${imgWidth * zoomLevel}px ${imgHeight * zoomLevel}px`,
                backgroundPositionX: `${-x * zoomLevel + magnifierWidth / 2}px`,
                backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`,
            }}
        />
    </div>
};

export default ImageMagnifier;
Enter fullscreen mode Exit fullscreen mode
// App.js
import React from 'react';
import ImageMagnifier from './ImageMagnifier';

const App = () => {
    return (
        <div>
            <ImageMagnifier 
                src="../images/demo-img.jpg"
                width={300}
                height={200}
                magnifierHeight={100}
                magnifierWidth={100}
                zoomLevel={2}
                alt="Sample Image"
            />
        </div>
    );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Example of Building an Image Magnifier Component in ReactJs

Conclusion
And there you have it! We've successfully created a simple yet functional image magnifier component in React. Users can now hover over images to inspect them closely, thanks to our intuitive magnifier feature.

Feel free to customize and enhance this component further to suit your specific needs. Happy coding!

Hope you like it.

That’s it — thanks.

To read my other articles click here.


👋Hey there, Let’s connect on:

Linkdin: Margish Patel
Twitter: @margish96patel
Email: babariyamargish97@gmail.com

Top comments (9)

Collapse
 
efpage profile image
Eckehard • Edited

You totally convinced me that in some cases using react is pure overhead. Why not use a webcomponent? Even plain JS would do the job...

Please check out this demo, which requires less than 10 lines of code.

Collapse
 
jankapunkt profile image
Jan Küster

Please do not forget this might be a minimal example where React may be overhead but it's still an example worth to check out and integrate as one possible feature on your larger react codebase.

Collapse
 
sarahokolo profile image
Info Comment hidden by post author - thread only accessible via permalink
sahra 💫

Nah, I would say the demo you provided is completely different, making the comparison quite void, what he has here is way cooler. Also the component just encapsulates the entire code needed to create the magnifier, and it happens to have way more lines of code than this.

Collapse
 
margishpatel profile image
Info Comment hidden by post author - thread only accessible via permalink
margishpatel

This code represents a working component from my own project, and I thought it would be beneficial to share it with others. It's a prime example of how React can be used to create interactive features like image magnifiers. By including this code in my blog, I hope to provide a helpful resource for fellow developers looking to implement similar functionality in their projects.

Sharing knowledge and facilitating growth within the community is what drives me, and I hope this contribution proves beneficial to many.

Given that many individuals may have already incorporated similar functionality into their projects, I aimed to provide a concise and effective solution through my blog post.

 
efpage profile image
Info Comment hidden by post author - thread only accessible via permalink
Eckehard

Hy @margishpatel,

thank you for sharing. It is important and valuable that people share their knowledge. React is a great platform to maintain application state, but as we see, it brings some overhead.

In this special case, data and interaction can be held closely together and there is no interaction with other parts of your page, so maybe it´s worth to think about other solutions to do the job.

Collapse
 
mohammadjunaid10p profile image
Info Comment hidden by post author - thread only accessible via permalink
mohammad-junaid-10p

Well the webcomponent is using more code than the example here, with similar performance, so that's a no kind off, & the provided example will require additional work to make it a moving magnifier.

Collapse
 
margishpatel profile image
Info Comment hidden by post author - thread only accessible via permalink
margishpatel

This code represents a working component from my own project, and I thought it would be beneficial to share it with others. It's a prime example of how React can be used to create interactive features like image magnifiers. By including this code in my blog, I hope to provide a helpful resource for fellow developers looking to implement similar functionality in their projects.

Sharing knowledge and facilitating growth within the community is what drives me, and I hope this contribution proves beneficial to many.

Given that many individuals may have already incorporated similar functionality into their projects, I aimed to provide a concise and effective solution through my blog post.

Collapse
 
pavelee profile image
Paweł Ciosek

Great post! 👏 thank you! 🙏

Collapse
 
mr_abhisheikh profile image
Info Comment hidden by post author - thread only accessible via permalink
Abhishek Shrestha

sdhjdsbjhcds

Some comments have been hidden by the post's author - find out more