效果

在这里插入图片描述

引用组件

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在盒子中的坐标:

  1. 获取鼠标在整个页面的位置;
  2. 获取盒子在浏览器左上角的位置;
  3. 鼠标在缩略图区域的坐标(localX & localY)= 鼠标在整个页面的位置 - 盒子在浏览器左上角的位置
  4. 再用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,
        });
    }

参考文章

放大器组件
react写一个仿淘宝图片放大器

Github源码

源码地址

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐