图片放大镜原理及实现步骤
简单的封装一个图片放大镜组件,主要使用@vueuse/core中useMouseInElement方法
-
原理:
- 通过鼠标移动的坐标控制小图上的遮罩层的移动及大图移动显示,使用@vueuse/core中方法useMouseInElement
-
步骤
- 构建基础页面布局
- 用v-if绑定遮罩层及大图的显示隐藏
- 动态绑定style,给遮罩层设置子绝父相定位,给大图设置背景图定位
- 通过使用@vueuse/core中方法useMouseInElement监测鼠标移动坐标变化,同步更新遮罩层的定位及大图的背景定位
<template> <div class="goods-image"> <!-- 小图 --> <div class="small" ref="target"> <img src="../../assets/images/200.png" alt=""> <!-- 遮罩层 --> <div v-if="showFlag" class="layer" :style="{ left:left+'px', top:top+'px' }"></div> </div> <!--大图 --> <div v-if="showFlag" class="large" :style="{ backgroundPositionX: positionX + 'px', backgroundPositionY: positionY + 'px',}"> </div> </div> </template> <script> import { ref, watch } from 'vue' import { useMouseInElement } from '@vueuse/core' export default { name: 'cart', setup () { const positionX = ref(0) const positionY = ref(0) const left = ref(0) const top = ref(0) const target = ref(null) const showFlag = ref(false) // elementX:距离盒子左侧的距离 // elementY:距离盒子右侧的距离 // isOutside是否在盒子外面,如果在盒子外面为true,反之为false console.log(useMouseInElement(target)) const { elementX, elementY, isOutside } = useMouseInElement(target) // 监听elementX, elementY, isOutside的变化 watch([elementX, elementY, isOutside], () => { console.log(elementX.value, elementY.value, isOutside.value) showFlag.value = !isOutside.value // 只有进入到容器中才开始做移动判断 if (isOutside.value) return false // 当横坐标大于300时,偏移值到最大为200(因遮罩层自身有宽高,所以偏移值需注意) if (elementX.value > 300) { left.value = 200 } // 当横坐标小于300时,偏移值到最小为0 if (elementX.value < 100) { left.value = 0 } // 当在横坐标在100-300之间,此时偏移值就为横坐标-100 if (elementX.value < 300 && elementX.value > 100) { left.value = elementX.value - 100 } // 纵坐标同理 if (elementY.value < 100) { top.value = 0 } if (elementY.value > 300) { top.value = 200 } if (elementY.value < 300 && elementY.value > 100) { top.value = elementY.value - 100 } // 大图通过背景图的定位属性进行控制, // 1.鼠标的移动的方向和大图的方向是相反的 (正负) // 2.鼠标每移动一个像素 大图背景移动俩个像素 (x2) positionX.value = -left.value * 2 positionY.value = -top.value * 2 }) return { positionX, positionY, left, top, target, showFlag } } } </script> <style lang="less" scoped> .goods-image{ display:flex; .large{ width: 400px; height: 400px; margin-left: 20px; background:url('~@/assets/images/200.png') no-repeat; background-size: 800px 800px; } .small{ position: relative; width: 400px; height: 400px; img{ width: 100%; } } .layer{ position:absolute; left: 0; top: 0; width: 200px; height: 200px; background-color: #ccc; } } </style> \