vue 元素碰撞检测 一对多

image.png
想用vue 做个一对多的元素碰撞,右侧三个标签可以拖拽,怎么判断拖拽一个标签跟黄色某个标签碰撞了??

阅读 3.8k
3 个回答

来一个简单粗暴的方法:

建立一个坐标系,每个标签可以用其左上角坐标点加自身长宽共四个属性表示:

const tag = {
  t: 0,
  l: 0,
  w: 100,
  h: 50
}

重叠计算,用的 ts 类型清晰一些:

interface Tag {
  t: number,
  l: number,
  w: number,
  h: number
}

interface Point {
  x: number,
  y: number
}

interface Bounds {
  t: number,
  r: number,
  b: number,
  l: number
}

// 判断一个点是否在一个区域内
function testInside(bounds: Bounds, point: Point) {
  return point.x >= bounds.l && point.x <= bounds.r && point.y >= bounds.t && point.y <= bounds.b
}

function testOverlap(source: Tag, target: Tag) {
  // 用一个标签构建一个区域
  const bounds: Bounds = {
    t: source.t,
    r: source.l + source.w,
    b: source.t + source.h,
    l: source.l
  }

  // 拖拽的标签的任意一个点在另一个标签中即出现重叠
  return testInside(bounds, { x: source.l, y: source.t }) ||
    testInside(bounds, { x: source.l + source.w, y: source.t }) ||
    testInside(bounds, { x: source.l, y: source.t + source.h }) ||
    testInside(bounds, { x: source.l + source.w, y: source.t + source.h })
}

拖拽的标签分别和静态的标签进行重叠计算即可。

方案一:直接通过drag & drop API 将黄色块变为可释放区域,蓝色块变为可拖拽元素,然后蓝色块被拖到与黄色块有交集区域的时候,dragover或dragenter回调就能知道。当然表面上你把黄色块设置为了可释放区域,实际上是可以不让他释放的。(PS: 这种方法是否能在最边缘碰撞检测到,有待实践证明)

方案二:采用楼上答主的拖拽重叠算法之类的方法计算

这个地方不需要碰撞检测,如果所有元素都是 DOM 节点的话,只需要普通的 mouseover 事件就好了。我也不建议用 <canvas> 画然后做碰撞检测,太浪费资源和时间。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题