Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 2, 2021 08:53 pm GMT

Create an Image Magnifier with React

Today, let's create a simple image magnifier component.

First, let's create the basic structure of the component.

function ImageMagnifier({  src,  width,  height,  magnifierHeight = 100,  magnifieWidth = 100,  zoomLevel = 1.5}: {  src: string;  width?: string;  height?: string;  magnifierHeight?: number;  magnifieWidth?: number;  zoomLevel?: number;}) {  return (    // the container    <div      style={{        position: "relative",        height: height,        width: width      }}    >      // the image      <img        src={src}        style={{ height: height, width: width }}        alt={"img"}      />      // a div for the magnifier      <div></div>    </div>  );}

Then, we need to add a state that controll the display of magnifier

 const [showMagnifier, setShowMagnifier] = useState(false);

and, the event handler that update the state.

...    <img        src={src}        style={{ height: height, width: width }}        onMouseEnter={(e) => {          setShowMagnifier(true);        }}        onMouseLeave={() => {          setShowMagnifier(false);        }}        alt={"img"}      />...

Now, we need to add a state that holds x, y position of magnifier, and update it when mouse move hover the image.

...const [[x, y], setXY] = useState([0, 0]);...<img    ...    onMouseMove={(e) => {          // update cursor position          const elem = e.currentTarget;          const { top, left } = elem.getBoundingClientRect();          // calculate cursor position on the image          const x = e.pageX - left - window.pageXOffset;          const y = e.pageY - top - window.pageYOffset;          setXY([x, y]);    }}    .../>

The pageX/Y coordinates are relative to the left/top corner of current page.
The pageXOffset/pageYOffset are the scroll offsets of the page.
The left/top are the coordinates of the image left/top position.

const x = e.pageX - left - window.pageXOffset;const y = e.pageY - top - window.pageYOffset;

These two calculations will give us the cursor's x/y coordinates based on the image.

In order to calculate the position of the magnifier, we also need to have the size of image in pixels, so let's update it when mouse is entering the image.

<img    ...    onMouseEnter={(e) => {          // update image size and turn-on magnifier          const elem = e.currentTarget;          const { width, height } = elem.getBoundingClientRect();          setSize([width, height]);          setShowMagnifier(true);    }}    .../>

Now, we can add the position and other basic styles to the magnifier.

<div    style={{        display: showMagnifier ? "" : "none",         position: "absolute",        // prevent magnifier blocks the mousemove event of img        pointerEvents: "none",        // set size of magnifier        height: `${magnifierHeight}px`,        width: `${magnifieWidth}px`,        // move element center to cursor pos        top: `${y - magnifierHeight / 2}px`,        left: `${x - magnifieWidth / 2}px`,        opacity: "1", // reduce opacity so you can verify position        border: "1px solid lightgray", // show the border of magnifier        backgroundColor: "white",        backgroundImage: `url('${src}')`,        backgroundRepeat: "no-repeat",    }}/>

Then, we need to zoom the image inside the magnifier.

    ...    //calculate zoomed image size    backgroundSize: `${imgWidth * zoomLevel}px ${imgHeight * zoomLevel}px`,    ...

Also, we need to center the image in the magnifier base on cursor position on the image.

    ...    //calculate position of zoomed image.    backgroundPositionX: `${-x * zoomLevel + magnifieWidth / 2}px`,    backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`    ...

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

function ImageMagnifier({  src,  width,  height,  magnifierHeight = 100,  magnifieWidth = 100,  zoomLevel = 1.5}: {  src: string;  width?: string;  height?: string;  magnifierHeight?: number;  magnifieWidth?: number;  zoomLevel?: number;}) {  const [[x, y], setXY] = useState([0, 0]);  const [[imgWidth, imgHeight], setSize] = useState([0, 0]);  const [showMagnifier, setShowMagnifier] = useState(false);  return (    <div      style={{        position: "relative",        height: height,        width: width      }}    >      <img        src={src}        style={{ height: height, width: width }}        onMouseEnter={(e) => {          // update image size and turn-on magnifier          const elem = e.currentTarget;          const { width, height } = elem.getBoundingClientRect();          setSize([width, height]);          setShowMagnifier(true);        }}        onMouseMove={(e) => {          // update cursor position          const elem = e.currentTarget;          const { top, left } = elem.getBoundingClientRect();          // calculate cursor position on the image          const x = e.pageX - left - window.pageXOffset;          const y = e.pageY - top - window.pageYOffset;          setXY([x, y]);        }}        onMouseLeave={() => {          // close magnifier          setShowMagnifier(false);        }}        alt={"img"}      />      <div        style={{          display: showMagnifier ? "" : "none",          position: "absolute",          // prevent magnifier blocks the mousemove event of img          pointerEvents: "none",          // set size of magnifier          height: `${magnifierHeight}px`,          width: `${magnifieWidth}px`,          // move element center to cursor pos          top: `${y - magnifierHeight / 2}px`,          left: `${x - magnifieWidth / 2}px`,          opacity: "1", // reduce opacity so you can verify position          border: "1px solid lightgray",          backgroundColor: "white",          backgroundImage: `url('${src}')`,          backgroundRepeat: "no-repeat",          //calculate zoomed image size          backgroundSize: `${imgWidth * zoomLevel}px ${            imgHeight * zoomLevel          }px`,          //calculate position of zoomed image.          backgroundPositionX: `${-x * zoomLevel + magnifieWidth / 2}px`,          backgroundPositionY: `${-y * zoomLevel + magnifierHeight / 2}px`        }}      ></div>    </div>  );}

Thank you all!


Original Link: https://dev.to/anxinyang/create-an-image-magnifier-with-react-3fd7

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To