Skip to main content

如何将 DOM 图像拖放到画布中

在这个演示中,我们将展示如何将放置在画布外部的 DOM 元素拖放到舞台中。

您看到的第一张图像是一个 DOM 图像。我们可以使用 HTML5 拖放 来启用它的拖动。

如果您需要在触摸设备上为 DOM 元素启用拖放,则需要一些额外的步骤。您可以在 这里 阅读更多信息。

说明: 将尤达拖放到画布中。

import Konva from 'konva';

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

// 添加 DOM 元素以在容器外部渲染
document.getElementById('container').insertAdjacentHTML(
  'beforebegin',
  `
  <p>将尤达拖放到灰色区域。</p>
  <div id="drag-items">
    <img src="https://konvajs.org/assets/yoda.jpg" draggable="true" style="height: 100px; margin: 5px;" />
    <img src="https://konvajs.org/assets/darth-vader.jpg" draggable="true" style="height: 100px; margin: 5px;" />
  </div>
`
);

// 用灰色背景样式化容器
document.getElementById('container').style.backgroundColor = 'rgba(0, 0, 0, 0.1)';

// 创建舞台和图层
const stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height - 150, // 留出空间给 DOM 元素
});

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

// 跟踪拖动元素的 URL
let itemURL = '';
document
  .getElementById('drag-items')
  .addEventListener('dragstart', function (e) {
    itemURL = e.target.src;
  });

// 处理容器上的 dragover
const container = stage.container();
container.addEventListener('dragover', function (e) {
  e.preventDefault(); // 重要 - 必须阻止默认行为
});

// 处理容器上的 drop
container.addEventListener('drop', function (e) {
  e.preventDefault();
  
  // 手动注册指针位置,因为这是一个 DOM 事件
  stage.setPointersPositions(e);
  
  // 加载图像并将其添加到图层
  Konva.Image.fromURL(itemURL, function (image) {
    // 根据图像尺寸计算合适的大小
    const img = image.image();
    const maxDimension = 100;
    let width = img.width;
    let height = img.height;
    
    if (width > height) {
      height = (height / width) * maxDimension;
      width = maxDimension;
    } else {
      width = (width / height) * maxDimension;
      height = maxDimension;
    }
    
    image.size({
      width: width,
      height: height
    });
    
    layer.add(image);
    image.position(stage.getPointerPosition());
    image.draggable(true);
  });
});