• 案例:商品放大镜效果


    整个案例可以分为三个功能模块:

    ① 鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开则隐藏遮挡层和大图片的盒子的功能:就是显示与隐藏。

    ② 黄色的遮藏层要跟随鼠标移动的功能:

    • 把鼠标坐标给遮挡层不合适,因为遮挡层是用定位方式设置的,所以它的坐标是以父盒子为准的
    • 首先获得鼠标在盒子里的坐标
    • 之后把数值给遮挡层作为left和top值
    • 此时用到鼠标移动事件,但是还是在小图片盒子内移动
    • 鼠标位置应该在遮挡层的正中间,因此遮挡层需要再减去盒子自身高度和宽度的一半
    • 遮挡层不能超出小盒子的范围(要把遮挡层卡在小图片的盒子内)
    • 如果小于0,就把遮挡层的坐标设置为0
    • 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
    • 遮挡层的最大移动距离:小图片盒子宽度减去遮挡层盒子宽度

    ③ 移动黄色的遮挡层,同时大图片也要跟随移动的功能:

    大图片的移动距离公式为:

    注意:大图片与遮挡层移动的方向应该是相反的!!!自己好好想一想是不是这个理

    <!-- 页面布局 -->
    <div class="preview_img">
        <img src="upload/s3.png" alt="">
        <div class="mask"></div>
        <div class="big">
            <img src="upload/big.jpg" alt="" class="bigImage">
        </div>
    </div>
    /* css样式 */
    .preview_img {
        position: relative;
        height: 398px;
        border: 1px solid #ccc;
    }
    .mask {
        display: none;
        position: absolute;
        top: 0;
        left: 0;
        width: 300px;
        height: 300px;
        background-color: #fede4f;
        /* 设置背景颜色的透明度 */
        opacity: .5;
        border: 1px solid #ccc;
        /* 鼠标经过时显示为move的形状 */
        cursor: move;
    }
    .big {
        display: none;
        /* 使用绝对定位定到预览图盒子的右边 */
        position: absolute;
        left: 410px;
        top: 0;
        /* 提高层级,使该放大图显示在最上层 */
        z-index: 999;
        width: 500px;
        height: 500px;
        background-color: pink;
        border: 1px solid #ccc;
        /* 里面的图片太大会溢出盒子,做溢出隐藏处理 */
        overflow: hidden;
    }
    .big img {
        position: absolute;
        top: 0;
        left: 0;
    }
    // JS逻辑代码
    window.addEventListener('load', function() {
        // 获取元素
        var preview_img = document.querySelector('.preview_img');
        var mask = document.querySelector('.mask');
        var big = document.querySelector('.big');
        // 1. 当我们鼠标经过preview_img就显示和隐藏mask遮挡层和big大盒子
        preview_img.addEventListener('mouseover', function() {
            mask.style.display = 'block';
            big.style.display = 'block';
        });
        preview_img.addEventListener('mouseout', function() {
            mask.style.display = 'none';
            big.style.display = 'none';
        });
        // 2. 鼠标移动的时候,让遮盖层的盒子跟着鼠标来走
        preview_img.addEventListener('mousemove', function(e) {
            //(1)先计算出鼠标在盒子内的坐标
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            // console.log(x, y);
            // 修改坐标只能用style,offset是只读的
            //(2)让鼠标始终在遮盖层的正中间显示:减去盒子高度和宽度的一半
            //(3)mask移动的距离
            var maskX = x - mask.offsetWidth / 2;
            var maskY = y - mask.offsetHeight / 2;        
            // 遮挡层的最大移动距离:因为遮挡层mask和图片preview_img都是正方形的,
            // 所以preview_img.offsetWidth - mask.offsetWidth和preview_img.offsetHeight - mask.offsetHeight是一样的
            var maskMax = preview_img.offsetWidth - mask.offsetWidth;
            //(4)使遮挡层mask不超出preview_img的范围
            if (maskX <= 0) {
                maskX = 0;
            }else if(maskX >= maskMax) {
                maskX = maskMax;
            }
            if (maskY <= 0) {
                maskY = 0;
            }else if(maskY >= maskMax) {
                maskY = maskMax;
            }
            mask.style.left = maskX + 'px';
            mask.style.top = maskY + 'px';
            // 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
            // 大图
            var bigImage = document.querySelector('.bigImage');
            // 大图片最大移动距离(大图片的大小比它的父盒子要大很多)
            var bigMax = bigImage.offsetWidth - big.offsetWidth;
            // 大图片的移动距离 X Y
            var bigX = maskX * bigMax / maskMax;
            var bigY = maskY * bigMax / maskMax;
            // 注意,大图片必须与父盒子是定位的关系才能移动
            // 注意:大图片与遮挡层移动的方向应该是相反的
            bigImage.style.left = -bigX + 'px';
            bigImage.style.top = -bigY + 'px';
        });
    });
  • 相关阅读:
    FJUT3260
    Codeforces Round #387 (Div. 2)
    poj 1375
    试题 历届试题 蚂蚁感冒(模拟)
    丢手绢(尺取)
    「金」点石成金(dfs)
    小A买彩票(dp)
    不平行的直线
    最少交换次数
    第k小数(桶排序)
  • 原文地址:https://www.cnblogs.com/zcy9838/p/12953803.html
Copyright © 2020-2023  润新知