Vue3实现电商放大镜效果

发布时间 2023-12-21 21:14:20作者: 自学Java笔记本

效果实现:

image

功能拆解:

  • 左侧滑块跟随鼠标移动
  • 右则大图放大效果实现
  • 鼠标移入控制滑块和大图显示隐藏

滑块跟随鼠标移动

image

思路:获取到当前的鼠标在盒子内的相对位置(useMouseInElement),控制滑块跟随鼠标移动(left/top)

  • 获取鼠标相对位置
  • 控制滑块跟随移动
  1. 有效移动范围内的计算逻辑
    横向:100 < elementX < 300,left = elementX - 小滑块宽度一半
    纵向: 100 < elementY < 300,top = elementY - 小滑块高度一半

  2. 边界距离控制
    横向:elementX > 300 left = 200 elementX < 100 left = 0
    纵向:elementY > 300 top = 200 elementY < 100 top = 0

import { useMouseInElement } from '@vueuse/core'
//elementX: 表示鼠标在目标元素内的 X 坐标。
//elementY: 表示鼠标在目标元素内的 Y 坐标。
//isOutside: 是一个布尔值,表示鼠标是否在目标元素的外部。如果鼠标在目标元素内,isOutside 为 false;如果在目标元素外,isOutside 为 true。
const { elementX, elementY, isOutside } = useMouseInElement(target)
// 3. 控制滑块跟随鼠标移动(监听elementX/Y变化,一旦变化重新设置left/top)
// 定义左右和上下方向的偏移量
const left = ref(0)
const top = ref(0)

// 监听鼠标在元素内的 X 和 Y 坐标的变化
watch([elementX, elementY], () => {
  // 有效范围内控制滑块距离

  // 横向范围限制
  if (elementX.value > 100 && elementX.value < 300) {
    left.value = elementX.value - 100
  }

  // 纵向范围限制
  if (elementY.value > 100 && elementY.value < 300) {
    top.value = elementY.value - 100
  }

  // 边界值处理

  // 如果鼠标在元素右侧边界之外,将 left 设置为 200(元素宽度为 200)
  if (elementX.value > 300) {
    left.value = 200
  }

  // 如果鼠标在元素左侧边界之外,将 left 设置为 0
  if (elementX.value < 100) {
    left.value = 0
  }

  // 如果鼠标在元素下侧边界之外,将 top 设置为 200(元素高度为 200)
  if (elementY.value > 300) {
    top.value = 200
  }

  // 如果鼠标在元素上侧边界之外,将 top 设置为 0
  if (elementY.value < 100) {
    top.value = 0
  }
})

  <!-- 蒙层小滑块 -->
      <div class="layer" :style="{ left: `${left}px`, top: `${top}px` }"></div>

大图效果实现

  • 效果:为实现放大效果,大图的宽高是小图的两倍
  • 思路:大图的移动方向和滑块移动方向相反,且数值为2
// 1.小图切换大图显示
const activeIndex = ref(0)
// 当点击时,获取下标值,并赋值给activeIndex,此时左侧大图即可实现切换
const enterhandler = (index) => {
  activeIndex.value = index
}
const target = ref(null)
// 2.放大镜效果实现
// 2.1 获取鼠标相对位置

const { elementX, elementY, isOutside } = useMouseInElement(target)

// 定义左右和上下方向的偏移量
const left = ref(0)
const top = ref(0)

// 大图的移动范围
const positionX = ref(0)
const positionY = ref(0)

// 监听鼠标在元素内的 X 和 Y 坐标的变化
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
  }

  // 边界值处理

  // 如果鼠标在元素右侧边界之外,将 left 设置为 200(元素宽度为 200)
  if (elementX.value > 300) {
    left.value = 200
  }

  // 如果鼠标在元素左侧边界之外,将 left 设置为 0
  if (elementX.value < 100) {
    left.value = 0
  }

  // 如果鼠标在元素下侧边界之外,将 top 设置为 200(元素高度为 200)
  if (elementY.value > 300) {
    top.value = 200
  }

  // 如果鼠标在元素上侧边界之外,将 top 设置为 0
  if (elementY.value < 100) {
    top.value = 0
  }

  // 控制大图的显示

  // 计算大图的横向偏移量
  positionX.value = -left.value * 2
  // 计算大图的纵向偏移量
  positionY.value = -top.value * 2
})