当前位置: 首页 > article >正文

图片通过滑块小图切换大图放大镜效果显示(Vue3)

图片通过滑块小图切换大图放大镜效果显示

实现目标:

  1. 显示一组图片列表,鼠标进入小图记录当下小图下标,通过小图下标在数组中对应图片显示到大图位置;

  2. 鼠标进入大图位置时,带动滑块移动,并将放大两倍的大图显示在原大图右边

实现过程:

  1. 实现小图切换大图:通过v-for将图片列表绑定在li标签上,同时为li标签添加鼠标监测事件,并绑定事件处理函数 enterHandler,传入图片索引 i 。初始化响应数据 activeIndex记录当前激活索引。通过 v-on加强 li 标签的样式 ,active激活条件为 i=== activeIndex即当前激活索引与小图索引相同时,左侧大图链接为激活图片索引 imageList[sctiveIndex]
  2. 导入VueUse的 useMouseInElement元素获取鼠标位置,记录鼠标相对位置 elementX、elementY,初始化放大图坐标 positionX、positionY,通过监听器 watch监听鼠标相对位置的变化,小滑块通过 left 、 top控制位置

图中红色正方形为滑块位置,蓝色正方形内为滑块控制的有效范围,需要处理边界(黑色正方形与蓝色正方形的差集)
在这里插入图片描述

控制滑块移动:

// 横向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}
  1. 控制放大图显示

注意观察,当鼠标在左侧大图移动时,右侧放大图移动方向相反

控制放大图坐标:

 // 控制大图显示positionX.value = -left.value * 2positionY.value = -top.value * 2// 控制放大图图片样式
<divclass="large":style="[{backgroundImage: `url(${imageList[activeIndex]})`,backgroundPositionX: `${positionX}px`,backgroundPositionY: `${positionY}px`,},]"v-show="!isOutside"></div>

在这里插入图片描述

在这里插入图片描述
【注:图片源自淘宝,如有侵权立刻删除】

完整代码

<script setup>
import { useMouseInElement } from '@vueuse/core'
import { ref, watch } from 'vue'// 图片列表
const imageList = ['img/O1CN01HhRDRN1PLRFptsiNY_!!2210715771824.jpg_.webp','img/O1CN01TgHapK1PLRFzgigEa_!!2210715771824.jpg_.webp','img/O1CN015Lpahn1PLRFzgiLRv_!!2210715771824.jpg_.webp','img/O1CN017pJsbA1PLRG0Uk1UI_!!2210715771824.jpg_ (1).webp','img/O1CN017pJsbA1PLRG0Uk1UI_!!2210715771824.jpg_.webp',
]// 小图切换大图
const activeIndex = ref(0)
const enterHandler = (i) => {activeIndex.value = i
}// 获取鼠标相对位置
const target = ref(null)
const { elementX, elementY, isOutside } = useMouseInElement(target)// 控制滑块跟随鼠标移动(监听XY变化,变化则重新设计left/top)
const left = ref(0)
const top = ref(0)const positionX = ref(0)
const positionY = ref(0)
watch([elementX, elementY, isOutside], () => {if (isOutside.value) {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 * 2positionY.value = -top.value * 2
})
</script><template><div class="goods-image"><!-- 左侧大图--><div class="middle" ref="target"><img :src="imageList[activeIndex]" alt="" /><!-- 蒙层小滑块 --><div class="layer" :style="{ left: `${left}px`, top: `${top}px` }"></div></div><!-- 小图列表 --><ul class="small"><liv-for="(img, i) in imageList":key="i"@mouseenter="enterHandler(i)":class="{ active: i === activeIndex }"><img :src="img" alt="" /></li></ul><!-- 放大镜大图 --><divclass="large":style="[{backgroundImage: `url(${imageList[activeIndex]})`,backgroundPositionX: `${positionX}px`,backgroundPositionY: `${positionY}px`,},]"v-show="!isOutside"></div></div>
</template><style scoped lang="scss">
.goods-image {width: 480px;height: 400px;position: relative;display: flex;.middle {width: 400px;height: 400px;background: #f5f5f5;}img {max-width: 100%;max-height: 100%;}.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-size: 800px 800px;background-color: #f8f8f8;}.layer {width: 200px;height: 200px;background: rgba(0, 0, 0, 0.2);// 绝对定位left: 0;top: 0;position: absolute;}.small {width: 80px;list-style: none;li {width: 68px;height: 68px;margin-left: 12px;margin-bottom: 15px;cursor: pointer;&:hover,&.active {border: 2px solid pink;}}}
}
* {box-sizing: border-box;
}
</style>
http://www.lryc.cn/news/2378260.html

相关文章:

  • [SSL]1Panel添加阿里云DNS账户
  • C语言编程中的时间处理
  • 计算机网络 : 网络基础
  • C++跨平台开发:突破不同平台的技术密码
  • 实现 STM32 PWM 输出:原理、配置与应用详解
  • Web 架构之负载均衡会话保持
  • 第一次做逆向
  • 【Linux网络】传输层协议TCP
  • AAAI-2025 | 中科院无人机导航新突破!FELA:基于细粒度对齐的无人机视觉对话导航
  • 排序算法之基础排序:冒泡,选择,插入排序详解
  • Linux常用命令42——tar压缩和解压缩文件
  • 网络协议分析 实验七 FTP、HTTP、DHCP
  • HTML 表格与div深度解析区别及常见误区
  • Linux 系统中设置开机启动脚本
  • linux-进程信号的产生
  • 内容中台重构企业知识管理路径
  • ubuntu22.04卸载vscode
  • AGI大模型(19):下载模型到本地之ModelScope(魔搭社区)
  • 基于Spring Boot+Layui构建企业级电子招投标系统实战指南
  • Kali安装详细图文安装教程(文章内附有镜像文件连接提供下载)
  • 2.4GHz无线芯片核心技术解析与典型应用
  • ai agent(智能体)开发 python高级应用4:什么是代理,如何设置squid代理服务器,让crawl4ai 0.6.3 用上代理,获取到数据平权
  • 技术融资:概念与形式、步骤与案例、挑战与应对、发展趋势
  • Chrome代理IP配置教程常见方式附问题解答
  • 微信小程序 密码框改为text后不可见,需要点击一下
  • LLM笔记(六)线性代数
  • Linux——UDP/TCP协议理论
  • Go语言爬虫系列教程(一) 爬虫基础入门
  • PromptIDE提示词开发工具支持定向优化啦
  • 多返回值(Multiple Return Values)- 《Go语言实战指南》