使用 React 创建图像放大镜
今天,我们来创建一个简单的图像放大镜组件。
首先,让我们创建组件的基本结构。
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>
);
}
然后,我们需要添加一个控制放大镜显示的状态
const [showMagnifier, setShowMagnifier] = useState(false);
以及更新状态的事件处理程序。
...
<img
src={src}
style={{ height: height, width: width }}
onMouseEnter={(e) => {
setShowMagnifier(true);
}}
onMouseLeave={() => {
setShowMagnifier(false);
}}
alt={"img"}
/>
...
现在,我们需要添加一个保存放大镜 x、y 位置的状态,并在鼠标悬停在图像上时更新它。
...
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]);
}}
...
/>
坐标pageX/Y
相对于当前页面的左/上角。
是pageXOffset/pageYOffset
页面的滚动偏移量。
是left/top
图像左/上位置的坐标。
const x = e.pageX - left - window.pageXOffset;
const y = e.pageY - top - window.pageYOffset;
这两个计算将根据图像为我们提供光标的 x/y 坐标。
为了计算放大镜的位置,我们还需要知道图像的像素大小,因此当鼠标进入图像时,让我们更新它。
<img
...
onMouseEnter={(e) => {
// update image size and turn-on magnifier
const elem = e.currentTarget;
const { width, height } = elem.getBoundingClientRect();
setSize([width, height]);
setShowMagnifier(true);
}}
...
/>
现在,我们可以为放大镜添加位置和其他基本样式。
<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",
}}
/>
然后,我们需要放大放大镜内的图像。
...
//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`
...
我们成功了。以下是完整代码和演示:
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>
);
}
谢谢大家!
文章来源:https://dev.to/anxiny/create-an-image-magnifier-with-react-3fd7