兄弟们好,第一次在CSDN博客写文章,心情有些激动。今天给各位兄弟们展示一个简单的vue3仿淘宝放大镜效果。
话不多说直接贴代码
先来上个布局
<div class="content" style="margin-top:20px" ref="contentRef">
<div class="pic-content" @mousemove="mousemove" @mouseleave="mouseleave" ref="picRef">
<img :src="mainImgUrl">
<div class="mask" :style="{ 'left': left + 'px', 'top': top + 'px', }" ref="mask" v-show="maskShow"></div>
</div>
<div class="small-pic">
<div class="btn" @click="imgLeft()"><</div>
<div class="img-content">
<ul class="img-list" :style="imgStyle">
<template v-for="(item, index) in picList" :key="index">
<li class="img-li" @click="changeImg(item, index)"
:class="index === imgActiveIndex ? 'active' : ''">
<img :src="item">
</li>
</template>
</ul>
</div>
<div class="btn" @click="imgRight()">
>
</div>
</div>
<div class="big" v-if="maskShow">
<img :src="mainImgUrl" :style="{ 'left': imgX + 'px', 'top': imgY + 'px', }" />
</div>
</div>
再来上个js
import { ref, computed, onMounted } from 'vue'
import a from '../assets/2.jpg'
import b from '../assets/3.jpg'
import c from '../assets/4.jpg'
import d from '../assets/5.jpg'
const picList = ref<any>([a, b, c, d, b, a, c, d])
const mainImgUrl = ref<string>('')
const imgActiveIndex = ref<number>(0)
const maskShow = ref<boolean>(false)
onMounted(() => {
mainImgUrl.value = picList.value[0]
})
const imgStyle: any = computed(() => {//此处基于一次显示的图片数量计算
if (picList.value.length > 4) {
if (imgActiveIndex.value < 4) {
return {
transform: `translate3d(${-((imgActiveIndex.value * 112))}px, 0, 0)`
}
} else {
return {
transform: `translate3d(${-(((picList.value.length - 4) * 112))}px, 0, 0)`
}
}
}
})
// 左箭头
const imgLeft = () => {
if (imgActiveIndex.value > 0) {
imgActiveIndex.value--
picList.value.forEach((item: any, index: any) => {
if (imgActiveIndex.value === index) {
mainImgUrl.value = item
}
})
} else {
if (imgActiveIndex.value == 0) {
imgActiveIndex.value = picList.value.length - 1
mainImgUrl.value = picList.value[picList.value.length - 1]
}
}
}
// 右箭头
const imgRight = () => {
if (imgActiveIndex.value < picList.value.length - 1) {
imgActiveIndex.value++
picList.value.forEach((item: any, index: number) => {
if (imgActiveIndex.value === index) {
mainImgUrl.value = item
}
})
} else if (imgActiveIndex.value === picList.value.length - 1) {
imgActiveIndex.value = 0;
mainImgUrl.value = picList.value[0]
}
}
const changeImg = (item: any, index: number) => {
mainImgUrl.value = item
imgActiveIndex.value = index
}
//鼠标移动事件
const contentRef = ref<HTMLElement|null>(null)
const picRef = ref<any>(null)
const mask = ref<any>(null)
const left = ref<any>(null)
const top = ref<any>(null)
const imgX = ref<any>(null)
const imgY = ref<any>(null)
const mousemove = (e: any) => {
maskShow.value = true
//鼠标相对位置
let mx = e.pageX
let my = e.pageY
//插件容器位置
let picX = contentRef.value?.offsetLeft??0
let picY = contentRef.value?.offsetTop??0
//相减得到鼠标相对于图片的位置
let maskX = mx - picX
let maskY = my - picY
// 获取蒙版的中心点
maskX = maskX - mask.value.offsetWidth / 2;
maskY = maskY - mask.value.offsetHeight / 2;
//小于图片临界判断
maskX = maskX < 0 ? 0 : maskX;
maskY = maskY < 0 ? 0 : maskY;
//大于图片临界判断
const maxX = picRef.value.offsetWidth - mask.value.offsetWidth
const maxY = picRef.value.offsetHeight - mask.value.offsetHeight
maskX = maskX > maxX ? maxX : maskX;
maskY = maskY > maxY ? maxY : maskY;
let bigImgX = - maskX * 2 //2是放大图和原图的大小比例
let bigImgY = -maskY * 2
console.log(maskX)
left.value = maskX
top.value = maskY
imgX.value = bigImgX
imgY.value = bigImgY
}
const mouseleave = () => {
maskShow.value = false
}
最后效果图
最后插个本文下载链接:vue3+vite+ts 仿淘宝放大镜效果
兄弟们需要可以下载引入
搞完收工,感谢观看,下次再见