I am working on adapting this image magnifier code for React Typescript without relying on an external library. The original Vanilla Javascript Codepen can be found here. Instead of copying and pasting the CSS into a separate file, I want to incorporate it within my const styles
or explore using a styled component to achieve the same outcome.
One question I have is how to avoid manual DOM manipulation with getElementById as I believe there could be a better way to handle this in React Typescript.
The structure involves a container for centering the element, followed by a magnifyWrapper that serves as the hover div triggering the display of a larger version of the image when hovered over.
Other elements include the main image and a ghost div for loading the enlarged image.
React Typescript Code
import React from 'react';
const styles = {
container: {
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
},
magnifyWrapper: {
position: "relative",
maxHeight: "50vh",
image: {
maxHeight: "inherit",
},
#largeImg: {
background: "url("https://images.unsplash.com/photo-1542856204-00101eb6def4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=975&q=80")",
noRepeat "#fff",
width: "100px",
height: "100px",
boxShadow: "0 5px 10px -2px rgba(0, 0, 0, 0.3)",
pointerEvents: "none",
position: "absolute",
border: "4px solid #efefef",
zIndex: "99",
borderRadius: "100%",
display: "block",
opacity: "0",
transition: "opacity 0.2s",
},
&:hover,
&:active: {
#largeImg: {
opacity: "1"
}
}
}
};
interface Props {
magnified: HTMLElement;
original: HTMLElement;
imgWidth: number;
imgHeight: number;
}
function Magnifier(props: Props) {
document.getElementById("zoom").addEventListener(
"mousemove",
function (e) {
let original = document.getElementById("main-img"),
magnified = document.getElementById("large-img"),
style = magnified.style,
x = e.pageX - this.offsetLeft,
y = e.pageY - this.offsetTop,
imgWidth = original.width,
imgHeight = original.height,
xperc = (x / imgWidth) * 100,
yperc = (y / imgHeight) * 100;
if (x > 0.01 * imgWidth) {
xperc += 0.15 * xperc;
}
if (y >= 0.01 * imgHeight) {
yperc += 0.15 * yperc;
}
style.backgroundPositionX = xperc - 9 + "%";
style.backgroundPositionY = yperc - 9 + "%";
style.left = x - 50 + "px";
style.top = y - 50 + "px";
},
false
);
return (
<div sx={styles.container} >
<div id="zoom" sx={styles.magnifyWrapper}>
<img
src="https://images.unsplash.com/photo-1542856204-00101eb6def4?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=975&q=80" id="main-img"
/>
<div sx={styles.largeImg}></div>
</div>
</div>
);
}
export { Magnifier };