线框的跟随移动

<!--  -->
<template>
  <div>
    <div class="box">
      <div v-for="item in list" :key="item.id" ref="innerBox" class="inner_box" @mouseenter="mouseenter">
        <div class="content">{{ item.id }}</div>
      </div>
      <div v-show="showPointer" ref="pointer" class="pointer"></div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }, { id: 10 }, { id: 11 }],
      showPointer: false,
    };
  },
  mounted() {
    this.calcPointerPosition(this.$refs.innerBox[0]);
    this.showPointer = true;
  },
  methods: {
    mouseenter(e) {
      const target = e.target;
      this.calcPointerPosition(target);
    },
    calcPointerPosition(dom) {
      this.$refs.pointer.style.setProperty("--s", dom.offsetWidth + "px");
      this.$refs.pointer.style.setProperty("--x", dom.offsetLeft + "px");
      this.$refs.pointer.style.setProperty("--y", dom.offsetTop + "px");
    },
  },
};
</script>
<style lang="scss" scoped>
* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}
.box {
  position: relative;
  background-color: black;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  padding: 20px;
  gap: 20px;
  .inner_box {
    // 保持宽高比
    position: relative;
    width: 100%;
    padding-top: 100%;
    .content {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: aqua;
    }
  }
  .pointer {
    --g: 15px; /* 线框与容器间距 */
    --s: 240px; /* 容器尺寸 动态 */
    --x: 0px; /* 线框左上角横坐标 动态 */
    --y: 0px; /* 线框左上角纵坐标 动态 */
    width: calc(var(--s) + var(--g) * 2); /* 线框宽度为容器宽度+2倍间距 高度同理 */
    height: calc(var(--s) + var(--g) * 2);
    position: absolute;
    left: calc(var(--x) - var(--g));
    top: calc(var(--y) - var(--g));
    border: 3px solid white;
    transition: 0.3s;
  }
}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值