Vue3鼠标拖拽生成区域块并选中元素

10 篇文章 0 订阅

Vue3鼠标拖拽生成区域块并选中元素,选中的元素则背景高亮(或者其它逻辑)。

在这里插入图片描述

<script setup>
import { ref } from 'vue'

// 区域ref
const regionRef = ref(null)

// 内容ref
const itemRefs = ref(null)

// 是否开启绘画区域
const enable = ref(false)

// 鼠标开始位置
const start = ref({
  x: 0,
  y: 0
})

// 区域块元素配置
const regionConfig = ref({
  top: '0px',
  left: '0px',
  width: '0px',
  height: '0px'
})


// 鼠标点击
const onMousedown = (e) => {
  const { pageX, pageY } = e
  start.value.x = pageX
  start.value.y = pageY
  regionConfig.value.top = pageY + 'px'
  regionConfig.value.left = pageX + 'px'
  enable.value = true
}

// 鼠标弹起
const onMouseup = () => {
  enable.value = false
}

// 鼠标移动
const onMousemove = (e) => {
  if (!enable.value) return false
  const { pageX, pageY } = e

  // 当前鼠标移动的位置减开始位置得到区域块宽高
  const x = pageX - start.value.x
  const y = pageY - start.value.y

  regionConfig.value.width = Math.abs(x) + 'px'
  regionConfig.value.height = Math.abs(y) + 'px'

  // 鼠标移动的位置小于开始位置,当前鼠标的位置是区域块的位置
  if (x < 0) {
    regionConfig.value.left = pageX + 'px'
  }

  if (y < 0) {
    regionConfig.value.top = pageY + 'px'
  }

  // 获取区域块和内容的位置
  const boxRect = regionRef.value.getBoundingClientRect()

  itemRefs.value.forEach((item) => {
    const rect = item.getBoundingClientRect()

    // 判断区域块包裹内容元素则改变背景颜色
    if (boxRect.top <= rect.top && boxRect.bottom >= rect.bottom && boxRect.left <= rect.left && boxRect.right >= rect.right) {
      item.style.backgroundColor = 'rgb(10, 228, 10)'
    } else {
      item.style.backgroundColor = '#cbccce'
    }
  })
}
</script>

<template>
  <main
    class="w_h_100 home"
    @mousedown="onMousedown"
    @mouseup="onMouseup"
    @mousemove="onMousemove"
  >
    <div class="box">
      <div
        ref="itemRefs"
        class="item"
        v-for="item in 10"
        :key="item"
      >{{ item }}</div>
    </div>

    <div
      ref="regionRef"
      class="region"
      :style="regionConfig"
    ></div>
  </main>
</template>

<style lang="less">
.home {
  display: flex;
  align-items: center;
  justify-content: center;

  .box {
    width: 200px;
    display: flex;
    flex-wrap: wrap;
  }

  .item {
    margin-right: 10px;
    margin-bottom: 10px;
    width: 30px;
    height: 30px;
    color: #fff;
    text-align: center;
    line-height: 30px;
    background-color: #cbccce;
    user-select: none;
  }

  .region {
    position: fixed;
    z-index: 10;
    border: 1px solid #0094ff;
    background-color: rgba(0, 148, 255, 0.1);
  }
}
</style>

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值