vue3--放大镜效果实现
// elementX , elementY target元素范围内的坐标值。
2.定义left,top变量蒙层移动的距离
left=elementX-蒙层盒子宽度的一半
top=element-蒙层盒子高度的一半
3.watch()监控elementX ,elementY。控制移动范围,
监听元素内鼠标移动的坐标变化=》控制蒙层移动=》计算蒙层:left和top的值
x轴
如 elementX<蒙层盒子宽度的一半,表示超出左边,让left=0
如elementX>盒子容器的宽度-蒙层盒子宽度的一半,表示超出右边,让left=盒子容器的宽度-蒙层盒子的宽度。
其他,left=elementX-蒙层盒子宽度的一半
y轴
如 elementY<蒙层盒子高度的一半,表示超出上面,让top=0
如elementY>盒子容器的高度-蒙层盒子高度的一半,表示超出右边,让top=盒子容器的宽度-蒙层盒子的宽度。
其他,top=elementY-蒙层盒子高度的一半
<template> <!-- 测试 --> <!-- <h1> div.middle内移动坐标x:{{ elementX }},y:{{ elementY }},是否在盒子外移动:{{ isOutside }} </h1> --> <div class="goods-image"> <!-- 放大镜图片 --> <div class="large" v-show="!isOutside" :style="[ { backgroundImage: `url(${list[currIndex]})`, backgroundPosition: `${bg.x}px ${bg.y}px`, }, ]" ></div> <!-- 左侧-大图 --> <div class="middle" ref="target"> <img :src="list[currIndex]" alt="" /> <!-- 正方体蒙层滑块 --> <div v-show="!isOutside" class="layer" :style="{ left: `${pos.left}px`, top: `${pos.top}px` }" ></div> </div> <!-- 右侧-小图片列表 --> <ul class="small"> <li v-for="(img, i) in list" :key="i" @mouseenter="currIndex = i"> <img :src="img" alt="" /> </li> </ul> </div> </template> <script> import { ref, watch } from 'vue' import { useMouseInElement } from '@vueuse/core' export default { name: 'GoodsImage', props: { list: { type: Array, default: () => [] } }, setup () { // 需求:鼠标经过某个小图,在左侧显示它的大图 /** * 1. 鼠标经过获取当前图片的索引值 * 2. 根据索引值获取当前图片的url */ const currIndex = ref(0) /** * 放大镜实现: * 前置知识:浏览器坐标系从左上角开始(x:0,y:0) * * 1. 获取元素内鼠标移动的坐标 * 2. 监听元素内鼠标移动的坐标变化=》控制蒙层移动=》计算蒙层:left和top的值 * 结论: * 1. 蒙层移动的范围: 100< pos <300 * 2. 蒙层位置计算公式:left = elementX - 100 | top = elementY - 100 */ // target 限定鼠标移动范围 const target = ref(null) // 蒙层位置变量 const pos = ref({ left: 0, top: 0 }) // 蒙层区域图片放大(2X) const bg = ref({ x: 0, y: 0 }) // elementX, elementY target元素范围内的坐标值 const { elementX, elementY, isOutside } = useMouseInElement(target) watch([elementX, elementY], () => { // 横向移动x轴 if (elementX.value < 100) { // 超出置0(左边) pos.value.left = 0 } else if (elementX.value > 300) { // 超出置200(右边) pos.value.left = 200 } else { pos.value.left = elementX.value - 100 } // 纵向移动y轴 if (elementY.value < 100) { // 超出置0(上) pos.value.top = 0 } else if (elementY.value > 300) { // 超出置200(下) pos.value.top = 200 } else { pos.value.top = elementY.value - 100 } // 计算背景图放大 bg.value.x = -pos.value.left * 2 bg.value.y = -pos.value.top * 2 }) return { currIndex, target, elementX, elementY, isOutside, pos, bg } } } </script> <style scoped lang="less"> .goods-image { width: 480px; height: 400px; position: relative; display: flex; // 放大镜图片(弹层) .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; background-size: 800px 800px; background-color: #f8f8f8; } .middle { width: 400px; height: 400px; background: #f5f5f5; // 滑块定位 .layer { width: 200px; height: 200px; background: rgba(0, 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>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现