Skip to main content

拖放碰撞检测演示

如何在画布上找到重叠对象?

在这个演示中,我们将使用简单的碰撞检测来突出显示交叉的对象。 为了简单起见,我们将仅使用边界框来检测碰撞。

红色边框用于显示边界框。

import Konva from 'konva';

var width = window.innerWidth;
var height = window.innerHeight;

var stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

var layer = new Konva.Layer();
stage.add(layer);

function createShape() {
  var group = new Konva.Group({
    x: Math.random() * width,
    y: Math.random() * height,
    draggable: true,
  });
  var shape = new Konva.Rect({
    width: 30 + Math.random() * 30,
    height: 30 + Math.random() * 30,
    fill: 'grey',
    rotation: 360 * Math.random(),
    name: 'fillShape',
  });
  group.add(shape);

  var boundingBox = shape.getClientRect({ relativeTo: group });

  var box = new Konva.Rect({
    x: boundingBox.x,
    y: boundingBox.y,
    width: boundingBox.width,
    height: boundingBox.height,
    stroke: 'red',
    strokeWidth: 1,
  });
  group.add(box);
  return group;
}

for (var i = 0; i < 10; i++) {
  layer.add(createShape());
}

layer.on('dragmove', function (e) {
  var target = e.target;
  var targetRect = e.target.getClientRect();
  layer.children.forEach(function (group) {
    // 不检查与自身的交叉
    if (group === target) {
      return;
    }
    if (haveIntersection(group.getClientRect(), targetRect)) {
      group.findOne('.fillShape').fill('red');
    } else {
      group.findOne('.fillShape').fill('grey');
    }
  });
});

function haveIntersection(r1, r2) {
  return !(
    r2.x > r1.x + r1.width ||
    r2.x + r2.width < r1.x ||
    r2.y > r1.y + r1.height ||
    r2.y + r2.height < r1.y
  );
}