1

I have the following React code:

import React, { useState } from "react";
import  { SideBySideMagnifier } from "react-image-magnifiers";
import image from './tree.jpg';
import './App.css';

const Grid = () => {
  return (
    <div className="input-grid">
      <div className="input-container">
        <label htmlFor="x1">x1:</label>
        <input type="text" id="x1" />
      </div>
      <div className="input-container">
        <label htmlFor="x2">x2:</label>
        <input type="text" id="x2" />
      </div>
      <div className="input-container">
        <label htmlFor="y1">y1:</label>
        <input type="text" id="y1" />
      </div>
      <div className="input-container">
        <label htmlFor="y2">y2:</label>
        <input type="text" id="y2" />
      </div>
    </div>
  );
};;

const Coordinates = () => {
  const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
  const [clickPosition, setClickPosition] = useState({ x: null, y: null });
  const [hovering, setHovering] = useState(false);

  const handleMouseMove = (event) => {
    setMousePosition({ x: event.clientX, y: event.clientY });
    const image = document.getElementById('rocker-img');
    if (event.clientX > image.offsetLeft && event.clientX < image.offsetLeft + image.clientWidth
      && event.clientY > image.offsetTop && event.clientY < image.offsetTop + image.clientHeight) {
      setHovering(true);
    } else {
      setHovering(false);
    }
};

 const handleClick = (event) => {
    setClickPosition({ x: mousePosition.x, y: mousePosition.y });
  };

  const handleClearClick = (event) => {
    setClickPosition({ x: null, y: null });
  };

  return (
    <div className="container">
      <div className="image-container">
        <SideBySideMagnifier
          imageSrc={image}
          imageAlt="Example"
        />
      </div>
      <div className="empty-div"></div>
      <div className="coords-container">
        <p className="coords">X: {mousePosition.x}</p>
        <p className="coords2">Y: {mousePosition.y}</p>
      </div>
      <div className="text-box-container">
        <label htmlFor="coordinates">Coordinates: </label>
        <input type="text" id="coordinates" value={clickPosition.x !== null ? `(${clickPosition.x}, ${clickPosition.y})` : ''} readOnly />
        <button onClick={handleClearClick}>Clear</button>
      </div>
      <Grid />
    </div>
  );
};

export default Coordinates;

I'm using the SideBySideMagnifier class from 'react-image-magnifiers', but when I hover over my 'tree.jpg', it doesn't display the image just to the right of the tree.jpg, it sorts of tacks it on up and to the right. Additionally, it isn't magnifying the picture.

Is there a way to accomplish this with the given library, or is there perhaps a way to do this manually in React?

Here is the associated CSS:

img {
  height: 350px;
  width: 350px;
  margin-top: 20px;
  margin-left: 50px;
  float: left;
}

.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  height: 400px;
  width: 500px;
  margin-left: 50px;
}

.empty-div {
  flex-grow: 1;
}

.image-container {
  display: flex;
  position: relative;
}

.coords-container {
  display: flex;
  justify-content: center;
  margin-top: 10px;
}

.coords {
  margin: 0;
  padding-left: 20px;
}

.coords2 {
  margin: 0 0 0 20px;
}

.crosshair {
  position: absolute;
  width: 20px;
  height: 20px;
  border: 1px solid black;
  border-radius: 50%;
  pointer-events: none;
  transform: translate(-50%, -50%);
  }

.text-box-container button {
  margin-left: 5px;
};

.input-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-column-gap: 5px;
  grid-row-gap: 5px;
  margin-top: 10px;
}

.input-container {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.input-container label {
  margin-right: 5px;
}

.input-container input {
  margin-left: 5px;
}


.input-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-column-gap: 5px;
  grid-row-gap: 5px;
  margin-top: 10px;
}

.input-container {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}

.input-container label {
  margin-right: 5px;
}

.input-container input {
  margin-left: 5px;
}
ZapRowsdower
  • 140
  • 8

1 Answers1

0

First of all, you shouldn't modify the size of the img tag directly, this caused all images (including the one used by react-image-magnifiers internally) to be forced to use the size you have specified, includes the zoomed in view on the right. In addition, the margin on the img also affected the anchoring for similar reasons.

In order to solve this, first remove the CSS for img selector, then create a less generic CSS rule like this:

.magnifier {
  height: 350px;
  width: 350px;
  margin-top: 20px;
  margin-left: 50px;
  float: left;
}

After that, add a className="magnifier" to your <SideBySideMagnifier component. This className property is the only thing you need to control the size of your image. The library will figure out how to render everything else for you by assigning the className to the wrapper element as well as the img tag underneath.

AngYC
  • 3,051
  • 6
  • 20
  • Oh, perfect! What I'm really trying to do is imlpement the ability to zoom in, while also retaining the ability to scroll around on screen and have it still display the x,y coordinates of the pixels, as well as clicking on the image to display the pixel coordinates in the text boxes I have set up. Is there a way to retain that functionality and the zooming? – ZapRowsdower Apr 29 '23 at 00:25