使用react完成图片放大功能(淘宝放大镜)
·
效果

引用组件
import React from 'react';
import ImageMagnifier from "./ImageMagnifier";
class ImgDemo extends React.Component{
constructor(props) {
super(props);
this.state={
// 略缩图:
minImg:"./small.jpg",
// 高清图
maxImg:"./large.jpg",
}
}
render(){
const {minImg,maxImg} = this.state;
return(
<ImageMagnifier minImg={minImg} maxImg={maxImg}/>
)
}
}
export default ImgDemo;
实现原理
在左边的盒子中放入图片的缩略图,右边的盒子只有在鼠标放上去时显示,并且放置的是对应图片的大图,这个大图只在右边盒子中显示出局部。
鼠标放在左边缩略图的时候,会出现一个遮罩层(mask),这个mask覆盖缩率图的位置会在右边的盒子中“局部放大”显示。(只显示右边图片的局部)。
遮罩层大小 / 缩略图大小 = 放大部分 / 图片原始大小。
当鼠标在左边缩略图中移动时,会带着这个遮罩层移动。获取遮罩层(mask)在小图中的位置,然后改变对应大图在右边盒子中局部显示的位置。
当遮罩层向下移动的时候,这个大图向上等比例移动。只需要把溢出的部分隐藏(overflow:hidden)即可达到放大效果。
大图宽度/缩略图显示的宽度 = 图片移动的距离 / mask移动的距离
CSS部分
注意事项:
遮罩层和图片放大镜容器应该设置为 绝对定位absolute 而且起始是 隐藏的, 父元素相对定位 relative,这样遮罩层可以在父元素中移动。
关于css position可以看阮一峰的css定位详解
React JS部分

获取mask在盒子中的坐标:
- 获取鼠标在整个页面的位置;
- 获取盒子在浏览器左上角的位置;
- 鼠标在缩略图区域的坐标(localX & localY)= 鼠标在整个页面的位置 - 盒子在浏览器左上角的位置
- 再用
localX、localY减去mask宽高的一半,即为遮罩层左上角的坐标。
然后把遮罩层加到页面上,但需要判断是否溢出——即mask左上角坐标是否在盒子中,如果溢出,就改变左上角坐标使得盒子与边界部分重叠。——到达边界时,鼠标可以在遮罩层的靠近边界区域随意移动,而遮罩层不动。
最后进行等比例移动大图。
calculationBlock(offsetx,offsety){
let cssStyle = JSON.parse(JSON.stringify(this.state.cssStyle))
let offsetX = offsetx - 50; // 鼠标在盒子中的位置 - mask宽的一半
let offsetY = offsety - 50; // 鼠标在盒子中的位置 - mask高的一半
/*block position*/
// 防止鼠标移动过快导致计算失误,只要小于或大于对应值,直接设置偏移量等于最小或最大值
// left 取值为 大于 0, 小于 盒子的宽 - mask的宽
if(offsetX < 0){
offsetX = 0;
}
if(offsetX > 350){
offsetX = 350;
}
// top 取值为 大于0 ,小于 盒子的高 - mask的高
if(offsetY< 0){
offsetY = 0;
}
if(offsetY > 350){
offsetY = 350;
}
// 移动mask
cssStyle.mouseBlock.left = parseFloat(offsetX) +"px";
cssStyle.mouseBlock.top = parseFloat(offsetY ) + "px";
/*计算图片放大位置*/
// 右侧大图片,等比例移动
// 大图片走的距离 / mask 走的距离 = 大图片 / 小图片
let bigImg = document.querySelector(".big img")
// <img className={'small img'} style={cssStyle.imgStyle} src={minImg}/>
let smallImg = document.querySelector('.small img')
let ratio = bigImg.offsetWidth / smallImg.offsetWidth;
cssStyle.imgStyle2.left = - parseFloat( (offsetX) * ratio) +"px";
cssStyle.imgStyle2.top = - parseFloat((offsetY) *ratio) + "px";
this.setState({
cssStyle:cssStyle,
});
}
参考文章
Github源码
更多推荐
所有评论(0)