一、需求
图片移动把图片放大
二、分析
第一步:获取的元素
=> 需要一个范围元素
=> 需要一个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
}
})
}
}