1. 通过小图切换大图实现:
思路:维护一个数组图片列表,
鼠标划入小图记录当前小图下标值,通过下标值
在数组中取对应图片
,显示到大图位置
2. 放大镜效果实现------滑块跟随鼠标移动
思路: 获取到当前的
鼠标在盒子内的相对位置
(
vueUse提供的
useMouseInElement
),
控
制滑块跟随鼠标移动(left/top)
1. 有效移动范围内的计算逻辑
横向:100 < elementX < 300,
left = elementX - 小滑块宽度一半
纵向: 100 < elementY < 300,
top = elementY - 小滑块高度一半
2. 边界距离控制
横向:elementX > 300 left = 200 elementX < 100 left = 0
纵向:elementY > 300 top = 200 elementY < 100 top = 0
3. 放大镜效果实现 - 大图效果实现
思路:大图的移动方向和滑块移动方向相反,且数值为2倍
4. 放大镜效果实现 - 鼠标移入控制显隐
思路:鼠标移入盒子(isOutside),滑块和大图才显示(v-show)
<script setup>
import {ref, watch} from "vue";
import {useMouseInElement} from '@vueuse/core'
// 图片列表
const imageList = [
"https://yanxuan-item.nosdn.127.net/d917c92e663c5ed0bb577c7ded73e4ec.png",
"https://yanxuan-item.nosdn.127.net/e801b9572f0b0c02a52952b01adab967.jpg",
"https://yanxuan-item.nosdn.127.net/b52c447ad472d51adbdde1a83f550ac2.jpg",
"https://yanxuan-item.nosdn.127.net/f93243224dc37674dfca5874fe089c60.jpg",
"https://yanxuan-item.nosdn.127.net/f881cfe7de9a576aaeea6ee0d1d24823.jpg"
]
// 小图切换大图显示
const activeindex = ref(0)
const enterhandler = (i) => {
activeindex.value = i
}
// 获取鼠标相对位置
const target = ref(null)
const {elementX, elementY, isOutside} = useMouseInElement(target)
// 控制滑块跟踪数百哦移动(监听elementX/Y变化,一旦变化,重新设置left/top)
const left = ref(0)
const top = ref(0)
const positionX = ref(0)
const positionY = ref(0)
watch([elementX, elementY], () => {
console.log('xy变化了')
//如果鼠标没有在盒子里面,直接不执行后面的逻辑
if(isOutside.value) return
// console.log('后续逻辑执行了')
// 有效范围内控制滑块距离
// 横向
if (elementX.value > 100 && elementX.value < 300) {
left.value = elementX.value - 100
}
// 纵向
if (elementY.value > 100 && elementY.value < 300) {
top.value = elementY.value - 100
}
// 边界处理
if (elementX.value > 300) {
left.value = 200
}
if (elementX.value < 100) {
left.value = 0
}
if (elementY.value > 300) {
top.value = 200
}
if (elementY.value < 100) {
top.value = 0
}
// 控制大图显示
positionX.value = -left.value * 2
positionY.value = -top.value * 2
})
</script>
<template>
{{ elementX }}-------{{ elementY }}-------{{ isOutside }}
<div class="goods-image">
<!-- 左侧大图-->
<div class="middle" ref="target">
<img :src="imageList[activeindex]" alt=""/>
<!-- 蒙层小滑块 -->
<div class="layer" v-show="!isOutside" :style="{ left: `${left}px`, top: `${top}px` }"></div>
</div>
<!-- 小图列表 -->
<ul class="small">
<li v-for="(img, i) in imageList" :key="i" @mouseenter="enterhandler(i)"
:class="{ active:i === activeindex }">
<img :src="img" alt=""/>
</li>
</ul>
<!-- 放大镜大图 -->
<div class="large" :style="[
{
backgroundImage: `url(${imageList[0]})`,
backgroundPositionX: `${positionX}px`,
backgroundPositionY: `${positionY}px`,
},
]" v-show="!isOutside" ></div>
</div>
</template>