Skip to main content

HTML5 Canvas 拖放事件

Konva 不支持拖放事件。但你可以编写自己的拖放事件检测。 要检测拖放目标形状,你必须将拖动的对象移动到另一个层中。

在这个例子中,你可以看到 dropdragenterdragleavedragover 事件的实现。

说明: 拖动一个形状到另一个形状上。或拖动并放下一个形状到另一个形状中。

import Konva from 'konva';

const stage = new Konva.Stage({
  container: 'container',
  width: window.innerWidth,
  height: window.innerHeight,
});

const layer = new Konva.Layer();
const tempLayer = new Konva.Layer();
stage.add(layer);
stage.add(tempLayer);

const text = new Konva.Text({
  fill: 'black',
});
layer.add(text);

let previousShape;

// 创建多个星星
for (let i = 0; i < 10; i++) {
  const star = new Konva.Star({
    x: stage.width() * Math.random(),
    y: stage.height() * Math.random(),
    fill: 'blue',
    numPoints: 10,
    innerRadius: 20,
    outerRadius: 25,
    draggable: true,
    name: 'star ' + i,
    shadowOffsetX: 5,
    shadowOffsetY: 5,
  });

  star.on('dragstart', () => {
    star.moveTo(tempLayer);
    text.text('Moving ' + star.name());
    layer.draw();
  });

  star.on('dragmove', (e) => {
    const pos = stage.getPointerPosition();
    const shape = layer.getIntersection(pos);

    if (previousShape && shape) {
      if (previousShape !== shape) {
        // 离开旧目标
        previousShape.fire('dragleave', { evt: e.evt }, true);
        // 进入新目标
        shape.fire('dragenter', { evt: e.evt }, true);
        previousShape = shape;
      } else {
        previousShape.fire('dragover', { evt: e.evt }, true);
      }
    } else if (!previousShape && shape) {
      previousShape = shape;
      shape.fire('dragenter', { evt: e.evt }, true);
    } else if (previousShape && !shape) {
      previousShape.fire('dragleave', { evt: e.evt }, true);
      previousShape = undefined;
    }
    layer.draw();
  });

  star.on('dragend', (e) => {
    const pos = stage.getPointerPosition();
    const shape = layer.getIntersection(pos);
    if (shape) {
      previousShape.fire('drop', { evt: e.evt }, true);
    }
    previousShape = undefined;
    star.moveTo(layer);
    layer.draw();
  });

  star.on('dragenter', () => {
    star.fill('green');
    text.text('dragenter ' + star.name());
    layer.draw();
  });

  star.on('dragleave', () => {
    star.fill('blue');
    text.text('dragleave ' + star.name());
    layer.draw();
  });

  star.on('dragover', () => {
    text.text('dragover ' + star.name());
    layer.draw();
  });

  star.on('drop', () => {
    star.fill('red');
    text.text('drop ' + star.name());
    layer.draw();
  });

  layer.add(star);
}

layer.draw();