图片放大镜(有意思的JS 二)

我是你们的索儿呀,很幸运我的文章能与你相见
愿萌新能直观的感受到Javascript的趣味性,愿有一定基础者有所收获,愿大佬不吝赐教

在这里插入图片描述

在我们逛淘宝、京东等购物网站时,每一个商品都是以图片显示,当我们鼠标划图片的时候,在旁边可以显示局部放大的图片

本篇文章的目的是,介绍JavaScript实现放大镜效果

思路及代码实现

文件结构

  • 对于一个看起来很清晰的图片,如果将图片放大,你会发现图片越来越模糊
  • 所以右边div的背景图片需要一个更加清晰的图片文件,防止左边图片局部放大显示后变的模糊

一般,网站需要考虑到图片的大小和图片的清晰度之间的平衡:如果图片清晰度高,就需要占用过多空间;如果需要为了节省空间,那么势必要牺牲图片清晰度

html代码:

<div class="small">
    <div class="magnifier"></div>
</div>
<div class="big"></div>

css代码:
div.small设置为相对定位,
div.magnifier设置为绝对定位,其left、right由JS控制
三个div的width、height都由JS控制

其余内容皆由JavaScript完成

一:思维导图

二:游戏配置

/**
 * 配置
 */
var config = {
    smallBg: "imgs/small.jpg",
    bigBg: "imgs/big.jpg",
    smallDiv: document.querySelector(".small"),
    bigDiv: document.querySelector(".big"),
    magnifierDiv: document.querySelector(".small .magnifier"),
    smallDivSize: {  //小图尺寸(即小的div的尺寸)
        width: 384,
        height: 216
    },
    bigDivSize: {  //大的div的尺寸
        width: 576,
        height: 324
    },
    bigBgSize: {  //大图尺寸
        width: 1920,
        height: 1080
    },
    

};
//放大镜div的宽、高
config.magnifierDivSize = {
    width: config.bigDivSize.width / config.bigBgSize.width * config.smallDivSize.width,
    height: config.bigDivSize.height / config.bigBgSize.height * config.smallDivSize.height
};
  1. 小图尺寸 = div.small尺寸
  2. div.magnifier的尺寸 / 小图尺寸 = div.big尺寸 / 大图尺寸

小图尺寸、大图尺寸:取决于提供的图片大小,是确定的;div.small尺寸、div.big尺寸:取决于网页布局,是确定的;而div.magnifier的尺寸,需要使用第二个公式进行计算

三:初始化div.small、div.big

设置它们的宽高和背景图片

/**
 * 初始化div.small、div.big
 */
function initDiv(){
    //div.small
    style = config.smallDiv.style;
    style.width = config.smallDivSize.width + 'px';
    style.height = config.smallDivSize.height + 'px';
    style.background = 'url("' + config.smallBg + '") no-repeat left top/100% 100%';
    //div.big
    style = config.bigDiv.style;
    style.width = config.bigDivSize.width + 'px';
    style.height = config.bigDivSize.height + 'px';
    style.background = 'url("' + config.bigBg + '") no-repeat';
    style.display = 'none';
}

四:初始化放大镜div

设置放大镜div宽高

/**
 * 初始化div.magnifier
 */
function initMagnifierDiv(){
    style = config.magnifierDiv.style;
    style.width = config.magnifierDivSize.width + 'px';
    style.height = config.magnifierDivSize.height + 'px';
    style.display = 'none';
}

五:鼠标事件

首先,给放大镜div注册:鼠标进入事件、鼠标移出事件

  • 当鼠标进入div.small时,div.magnifier、div.big显现出来
  • 与之相对,当鼠标离开div.small时,div.magnifier、div.big消失
dom = config.smallDiv;

dom.onmouseenter = function(){
    config.magnifierDiv.style.display = 'block';
    config.bigDiv.style.display = 'block';
}

dom.onmouseleave = function(){
    config.magnifierDiv.style.display = 'none';
    config.bigDiv.style.display = 'none';
}

然后,重中之重,鼠标移动事件

(1) 当鼠标在div.small中移动时,首先要得到鼠标在div.small的偏移量(坐标),分两种情况:

(1.1)当鼠标移动事件由div.small触发时,通过offsetX、offsetY即可获取偏移量

(1.2)当鼠标移动事件由div.magnifier触发时,通过offsetX、offsetY获取的只是鼠标相对于div.magnifier的偏移量,所以还要加上div.magnifier的left(top)与div.magnifier的边框宽度

e.offsetX、e.offsetY:

  • 鼠标相对于事件源的内边距的坐标
/**
 * 得到鼠标在div.small的偏移量(坐标)
 * @param {MouseEvent} e 
 */
function getOffset(e){
    if(e.target === config.smallDiv){
        return {
            x: e.offsetX,
            y: e.offsetY
        }
    }else{
        var style = getComputedStyle(config.magnifierDiv);
        var left = parseFloat(style.left);  //parseFloat()去掉单位px
        var top = parseFloat(style.top);
        return {
            x: e.offsetX + left + 1,
            y: e.offsetY + top + 1
        }
    }
}

(2) 根据鼠标的偏移量,设置div.magnifier的left、top

(2.1)鼠标相对于div.small的偏移量 减去 div.magnifier的宽(高)的一半,即div.magnifier的left(top),这样可以使鼠标在放大镜div的中心

(2.2)要注意边界值的判定,并对其进行处理

/**
 * 根据鼠标的偏移量,设置div.magnifier的left、top
 * @param {*} offset 
 */
function setPosition(offset){
    var left = offset.x - config.magnifierDivSize.width / 2;
    var top = offset.y - config.magnifierDivSize.height / 2;
    if(left < 0){
        left = 0;
    }
    if(top < 0){
        top = 0;
    }
    if(left > config.smallDivSize.width - config.magnifierDivSize.width){
        left = config.smallDivSize.width - config.magnifierDivSize.width;
    }
    if(top > config.smallDivSize.height - config.magnifierDivSize.height){
        top = config.smallDivSize.height - config.magnifierDivSize.height;
    }
    config.magnifierDiv.style.left = left + 'px';
    config.magnifierDiv.style.top = top +'px';
}

(3) div.small的背景图片的某一部分,通过放大镜(div.magnifier),

在右边的div.big上进行映射:

有这么个比值可以用来设置div.big的background-position(通过图解说)

div.magnifier相对于div.small的left / div.small的宽度
=
background-position-x的绝对值 / div.big的背景图片的宽度

另一个与此同理

/**
 * 图片经过放大镜后,在div.big的映射
 */
function setBigDivBg(){
    var bgLeft = -1 * parseFloat(getComputedStyle(config.magnifierDiv).left) / config.smallDivSize.width * config.bigBgSize.width; 
    var bgTop = -1 * parseFloat(getComputedStyle(config.magnifierDiv).top) / config.smallDivSize.height * config.bigBgSize.height;
    config.bigDiv.style.backgroundPosition = bgLeft + 'px ' + bgTop + 'px';
}

代码获取

放大镜的完整核心代码,有两个方式获取

所谓核心代码,即本篇文章带你实现的放大镜的完整代码,没有加入许许多多花里胡哨的东西,以免文章无法连贯讲解

  1. 百度网盘
    文件夹链接:https://pan.baidu.com/s/120rZT1r-cDAdpBRU8_9spA
    提取码:e458
    压缩包链接:https://pan.baidu.com/s/1ldbJ-2v0OCm7g-mk3NuB9w
    提取码:9g7g
  2. github:https://github.com/Zhangguohao666/demo-front-end/tree/master/magnifier

本文代码思路参考自:渡一,袁进老师


发布了146 篇原创文章 · 获赞 287 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/Zhangguohao666/article/details/104433090