效果展示

鼠标进入右侧小图时显示大图
鼠标进入左侧图,显示遮罩和右侧放大区
右侧放大区,显示左侧遮罩层内容
思路
获取鼠标在左侧的位置 :通过vueuse的useMouseInElement方法获取
// elementX 鼠标在当前元素x轴的位置// elementY 鼠标在当前元素y轴的位置// isOutside 鼠标是否在当前元素外 在外面为true 在内部为fales// target 当前被监控的元素const { elementX, elementY, isOutside } = useMouseInElement(target)
放大区css控制
1:通过设背景大小 background-size: x,y 是其盒子的二倍 达到放大效果
2:根据左侧鼠标位置动态设置背景位置 达到移动效果background-position-x,background-position-y
代码
<template><div class="goods-image" ><!-- 被放大的图片 style 控制显示的图片 bgPosition 控制显示的图片位置--><div v-show="!isOutside" class="large" :style="{backgroundImage: `url(${images[curIdx]})`, ...bgPosition}"></div><!-- 左边的大图 --><div class="middle" ref="target"><img :src="images[curIdx]" alt=""><!-- 放大镜的遮罩层 --><div v-show="!isOutside" class="layer" :style="layerStyle"></div></div><!-- 右边的小图 --><ul class="small"><!-- 鼠标移入时小图时改变大图显示的索引 --><liv-for="(url,idx) in images":key="idx":class="{active:curIdx==idx}"@mouseenter="curIdx=idx"><img :src="url" alt=""></li></ul></div></template><script>import { ref, watch, reactive } from 'vue'// 导入 useMouseInElementimport { useMouseInElement } from '@vueuse/core'export default {props: { images: { type: Array, default: () => [] } },setup () {// 监控左侧大图 鼠标的移动const target = ref(null)// elementX 鼠标在x轴的移动 elementY 鼠标在y轴的移动 isOutside鼠标是否移出当前监控元素 是为trueconst { elementX, elementY, isOutside } = useMouseInElement(target)// 定义 控制放大镜遮罩的位置的变量const layerStyle = reactive({top: 0,left: 0})// 定义被放大图背景位置const bgPosition = reactive({'background-position-x': 0, // 精准的css样式的名字,方便直接使用'background-position-y': 0})// 监控鼠标的位置变化watch([elementX, elementY, isOutside], () => {// 计算遮罩位置 鼠标在遮罩中间位置 鼠标位置减遮罩宽高的一半let top = elementY.value - 100let left = elementX.value - 100// 限制鼠标在当前盒子内 盒子大小400*400if (top > 200) top = 200if (left > 200) left = 200if (top < 0) top = 0if (left < 0) left = 0// 传递遮罩位置layerStyle.top = top + 'px'layerStyle.left = left + 'px'// 计算被放大图片的背景位置 初始位置显示左上角 向左移为负 倍数为2bgPosition['background-position-x'] = (-2 * left) + 'px'bgPosition['background-position-y'] = (-2 * top) + 'px'console.log(layerStyle.top, layerStyle.left)})// 当前图片的下标const curIdx = ref(0)return { curIdx, elementX, elementY, isOutside, target, layerStyle, bgPosition }}}</script><style scoped lang="less">.goods-image {width: 480px;height: 400px;position: relative;display: flex;z-index: 500;.large {position: absolute;top: 0;left: 412px;width: 400px;height: 400px;box-shadow: 0 0 10px rgba(0,0,0,0.1);background-repeat: no-repeat;background-size: 800px 800px;background-color: #f8f8f8;}.middle {width: 400px;height: 400px;background: #f5f5f5;position: relative;cursor: move;.layer {width: 200px;height: 200px;background: rgba(0,0,0,.2);left: 0;top: 0;position: absolute;}}.small {width: 80px;li {width: 68px;height: 68px;margin-left: 12px;margin-bottom: 15px;cursor: pointer;&:hover,&.active {border: 2px solid @xtxColor;}}}}</style>
