da效果预览:
当鼠标浮在图片上时,灰色小框跟随鼠标运动。右侧大图显示。灰色框不会跑出图片,鼠标移动,右侧大图相应跟随移动。
实现思路
在实现前,我们想梳理一下我们要实现什么功能
- 灰色框跟随鼠标移动,注意处理边界情况
- 当鼠标进入时右侧大图出现,鼠标移出时右侧大图消失
- 鼠标向左移动是,右侧大图向右移动二倍的距离
我们一步一步实现这个功能。
实现准备
首先我们认识一个辅助函数。vue3生态系统中vueuse中的useMouseInElement
我们主要注意组件中的x,y,isOutside属性分别代表了鼠标相对于组件的水平距离、垂直距离、是否在组件内。
组件使用方法:
下载vueuse:
npm i @vueuse/core
初始化使用
<script setup>
import { useMouseInElement } from '@vueuse/core'
const { elementX, elementY, isOutside } = useMouseInElement(target)
</script>
我们通过解析表达来获取所需要的数据,注意我们获取到的数据都是响应式的,会动态变化。
具体实现
实现小滑块吸附鼠标移动
HTML结构:
<template>
<div class="goods-image">
<!-- 左侧大图-->
<div class="middle" ref="target">
<img :src="imageList[curImg]" alt="" />
<!-- 蒙层小滑块 -->
<div class="layer" :style="{ left: `${left}px`, top: `${top}px` }"></div>
</div>
<!-- 小图列表 -->
<ul class="small">
<li
v-for="(img, i) in imageList"
:key="i"
:class="{ active: curImg === i }"
@mouseenter="chooseNewImg(i)"
>
<img :src="img" alt="" />
</li>
</ul>
<!-- 放大镜大图 -->
<div
class="large"
:style="[
{
backgroundImage: `url(${imageList[0]})`,
backgroundPositionX: `${positionX}px`,
backgroundPositionY: `${positionY}px`
}
]"
v-show="!isOutside"
></div>
</script>
<style>
// 左侧图片样式
.middle {
width: 400px;
height: 400px;
background: #f5f5f5;
}
// 蒙层样式
.layer {
width: 200px;
height: 200px;
background: rgba(0, 0, 0, 0.2);
// 绝对定位 然后跟随咱们鼠标控制left和top属性就可以让滑块移动起来
left: 0;
top: 0;
position: absolute;
}
// 右侧细节图样式
.large {
position: absolute;
top: 0;
left: 412px;
width: 400px;
height: 400px;
z-index: 500;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
background-repeat: no-repeat;
// 背景图:盒子的大小 = 2:1 将来控制背景图的移动来实现放大的效果查看 background-position
background-size: 800px 800px;
background-color: #f8f8f8;
}
</style>
我们忽略下方的小图列表,我们为蒙层绑定了一个动态的css,通过left和top来控制蒙层小滑块。
下方提供了css样式,该图长宽都为400px,蒙层的长宽为200px。而右侧大图的back-ground-size为800px*800px是正常图片的二倍,实现放大效果。
那么我们应该如何确定left和top呢?
这里需要仔细理解一下,小滑块长200px,而我们的需要将小滑块的中心吸附在鼠标上,那么小滑块的left和top都要减去小滑块高度的一半。
当为超过边界时,小滑块吸附在鼠标上。
当超过边界的时候,则直接锁定在固定位置。
代码实现:
watch([elementX, elementY], () => {
if (!isOutside) {
return
}
// 横向
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 < 100) {
left.value = 0
}
if (elementX.value > 300) {
left.value = 200
}
if (elementY.value < 100) {
top.value = 0
}
if (elementY.value > 300) {
top.value = 200
}
})
实现右侧跟踪显示具体细节
实现跟踪首先要想明白一个问题。
你的鼠标吸附的是蒙层。蒙层往右,图片应该往左。这就像你拿显微镜看标本,往右挪显微镜,相当于往左移动标本。
放大的图片是二倍显示,那么移动的距离自然也应该是二倍。
解决这个问题,代码自然就好写了。只需要每次反向二倍移动即可。
// 放大图片位置
const positionX = ref(0)
const positionY = ref(0)
const target = ref(null)
const { elementX, elementY, isOutside } = useMouseInElement(target)
watch([elementX, elementY], () => {
if (!isOutside) {
return
}
// 横向
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 < 100) {
left.value = 0
}
if (elementX.value > 300) {
left.value = 200
}
if (elementY.value < 100) {
top.value = 0
}
if (elementY.value > 300) {
top.value = 200
}
// 放大镜位置
positionX.value = -left.value * 2
positionY.value = -top.value * 2
})
<!-- 放大镜大图 -->
<div
class="large"
:style="[
{
backgroundImage: `url(${imageList[0]})`,
backgroundPositionX: `${positionX}px`,
backgroundPositionY: `${positionY}px`
}
]"
v-show="!isOutside"
></div>
这样就轻松实现啦!快去试试吧。
标签:elementX,elementY,top,JavaScript,value,vue3,100,电商,left From: https://blog.csdn.net/linsiraixuexi/article/details/142899920