DEV Community

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

Posted on

59 3 1 3 5

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

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

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
 
sarahokolo profile image
sahra 💫
Comment hidden by post author
Collapse
 
margishpatel profile image
margishpatel
Comment hidden by post author
 
efpage profile image
Eckehard
Comment hidden by post author
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
 
mohammadjunaid10p profile image
mohammad-junaid-10p
Comment hidden by post author
Collapse
 
margishpatel profile image
margishpatel
Comment hidden by post author
Collapse
 
pavelee profile image
Paweł Ciosek

Great post! 👏 thank you! 🙏

Collapse
 
mr_abhisheikh profile image
Abhishek Shrestha
Comment hidden by post author

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

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay