放大镜组件封装

145 阅读1分钟

图片放大镜原理及实现步骤

简单的封装一个图片放大镜组件,主要使用@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>

    \