案例 放大镜

一、需求

图片移动把图片放大

二、分析

第一步获取的元素

=> 需要一个范围元素

=> 需要一个show盒子

=> 需要一个 遮罩层 盒子

=> 需要一个 list 盒子

=> 需要一个 enlarge 盒子

=> 需要一个 enlarge 盒子 中的图片(大图)

第二步:获取尺寸

=> 需要获取到 show 盒子的尺寸

=> 需要获取到 mask 盒子的尺寸

=> 需要获取到 大图 盒子的尺寸

方法:

=> 计算比例

        -> 我们决定了 修改 enlarge 盒子的大小

        -> 就需要获取到 show 盒子 mask 盒子 大图的尺寸

=> 移入移出

        移入:

        -> 鼠标要进入 show 盒子的时候

        -> 让 mask 盒子和 enlarge 盒子显示

=> 移动联动

        -> 我们的鼠标在show 盒子中移动的时候

        -> 我们的 mask 盒子要跟随移动

        -> 我们的大图要按照比例的反方向移动

=> 点击切换

        -> 我们在点击小图的时候

        -> 需要切换类名 (排他思想)

        -> 让对应的show 盒子中的图片和enlarge盒子中的图片发生改变

                + 就是拿到对应的图片的地址 , 赋值给img标签的src属性

三、代码实现

HTML页:

    <!-- 布局结构 -->
    <!-- 整个放大镜区域 -->
    <div class="box" id="box">

        <!-- 正常显示图片区域 -->
        <div class="show">
            <img src="./imgs/1.jpg" alt="">

            <!-- 遮罩层盒子 -->
            <div class="mask"></div>
        </div>

        <!-- 图片切换列表 -->
        <div class="list">
            <img class="active" src="./imgs/1.small.jpg" data-show="./imgs/1.jpg" data-bg="./imgs/1.big.jpg" alt="">
            <!-- 用自定义属性的方式渲染到页面上 因为用户拿不到图片 只能拿到地址 -->
            <img src="./imgs/2.small.jpg" data-show="./imgs/2.jpg" data-bg="./imgs/2.big.jpg" alt="">
        </div>

        <!-- 放大镜的盒子 -->
        <div class="enlarge">
            <img src="./imgs/1.big.jpg" alt="">
        </div>
    </div>

    <script src="./enlarge.js"></script>
    <script>
        // 使用的时候
        // 需要实例化一个对象
        let e = new Enlarge('#box')
        console.log(e);
    </script>

JS页

class Enlarge { 
    constructor(options) { 
        // 拿到我们的范围元素
        this.ele = document.querySelector(options)
        // 获取我们需要的各个元素
        this.show = this.ele.querySelector('.show')
        this.mask = this.ele.querySelector('.mask')
        this.list = this.ele.querySelector('.list')
        this.enlarge = this.ele.querySelector('.enlarge')
        this.picture = this.enlarge.firstElementChild

        // 获取尺寸
        this.show_w = this.show.clientWidth
        this.show_h = this.show.clientHeight
        this.mask_w = parseInt(window.getComputedStyle(this.mask).width)
        this.mask_h = parseInt(window.getComputedStyle(this.mask).height)
        this.picture_w = parseInt(window.getComputedStyle(this.picture).width)
        this.picture_h = parseInt(window.getComputedStyle(this.picture).height)
        

        // 调用方法
        this.score()
        this.overOut()
        this.move()
        this.clickChange()
    }

    // 方法
    // 计算比例
    score() { 
        console.log('计算比例');

        /* 
            mask 盒子      enlarge 盒子 (我们要求的)
           ----------  =  -------------------------
            show 盒子                 大图
        
        */
        // 计算出 enlarge 盒子的尺寸
        this.enlarge_w = this.mask_w * this.picture_w / this.show_w
        this.enlarge_h = this.mask_h * this.picture_h / this.show_h
        // 赋值给enlarge盒子
        this.enlarge.style.width = this.enlarge_w  + 'px'
        this.enlarge.style.height = this.enlarge_h  + 'px'
    }

    //移入移出
    overOut() { 
        console.log('移入移出');
        this.show.addEventListener('mouseover', () => { 
            // 让mask盒子和 enlarge 盒子 显示
            this.mask.style.display = 'block'
            this.enlarge.style.display = 'block'
        })
        this.show.addEventListener('mouseout', () => { 
            // 让mask盒子和 enlarge 盒子 隐藏
            this.mask.style.display = 'none'
            this.enlarge.style.display = 'none'
        })
    }

    // 移动联动
    move() { 
        console.log('移动联动');
        // 问题: 给谁添加什么事件?
        // 给 show 盒子添加 鼠标移动事件
        this.show.addEventListener('mousemove', e => { 
            e = e || window.event

            // 获取坐标点 (那一组 : offset)
            let x = e.offsetX - this.mask_w / 2
            let y = e.offsetY - this.mask_h / 2

            // 边界值判断
            if (x < 0) x = 0
            if (y < 0) y = 0
            if (x > this.show_w - this.mask_w) x = this.show_w - this.mask_w
            if (y > this.show_h - this.mask_h) y = this.show_h - this.mask_h

            // 赋值给 mask 盒子
            this.mask.style.left = x + 'px'
            this.mask.style.top = y + 'px'


            // 大图能各随移动
            /*
                mask盒子移动的距离      mask盒子的宽度
                ----------------- = ------------------
                  大图移动的距离(X)     enlarge盒子的宽度
            */
            
            let bg_x = x * this.enlarge_w / this.mask_w
            let bg_y = y * this.enlarge_h / this.mask_h

            // 赋值给 大图
            this.picture.style.left = -bg_x + 'px'
            this.picture.style.top = -bg_y + 'px'
        })
    }

    // 点击切换
    clickChange() { 
        console.log('点击切换');
        // 利用事件委托的方式来添加事件
        // 事件添加给 list 盒子
        this.list.addEventListener('click', e => { 
            e = e || window.event
            // 获取目标元素
            let target = e.target 
            // 判断我们要点击的元素
            if (target.nodeName === 'IMG') { 
                // 清除所有的类名
                for (let i = 0; i < this.list.children.length; i++) { 
                    this.list.children[i].classList.remove('active')
                }

                // 给你点击的那一个加上
                target.classList.add('active')
                // 获取自定义属性
                let show_src = target.dataset.show
                let picture_src = target.dataset.bg

                console.log(show_src);
                // 把获取到的地址赋值给对应的img标签
                this.show.firstElementChild.src = show_src
                this.picture.src = picture_src
            }
        })
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值