拖放到Fabric.js画布中

use*_*317 11 drag-and-drop fabricjs

如何将项目(如图像或其他画布中的其他对象)拖放到由fabricjs管理的画布中?我已经找到了许多如何在canvas中移动项目的例子,但我想将项目从外部元素拖放到画布中.

nat*_*eta 18

既然你问了一个例子而我还没有尝试过,那么这里有:

示例小提琴


标记

<div id="images">
    <img draggable="true" src="http://i.imgur.com/8rmMZI3.jpg" width="250" height="250"></img>
    <img draggable="true" src="http://i.imgur.com/q9aLMza.png" width="252" height="295"></img>
    <img draggable="true" src="http://i.imgur.com/wMU4SFn.jpg" width="238" height="319"></img>
</div>

<div id="canvas-container">
    <canvas id="canvas" width="800" height="600"></canvas>
</div>
Run Code Online (Sandbox Code Playgroud)

JS细分

1. Fabric.canvas实例

首先,我们想要我们的画布,当然:

var canvas = new fabric.Canvas('c');
Run Code Online (Sandbox Code Playgroud)

2.特征检测(可选)

不确定这是必要的,因为你有一个画布使浏览器很可能也有拖放.如果您使用它,您可以使用Modernizr这样做:

if (Modernizr.draganddrop) {
    // Browser supports HTML5 DnD.

    // Bind the event listeners for the image elements

    // Bind the event listeners for the canvas
} else {
    // Replace with a fallback to a library solution.
    alert("This browser doesn't support the HTML5 Drag and Drop API.");
}
Run Code Online (Sandbox Code Playgroud)

3.活动

同样,与下面的源文章不同,源元素和目标元素是不同的(在文章的示例中,您只是div在同一个父容器中移动s),所以我没有注意到某些事件是针对元素的拖动,但大多数都绑定到您要删除的元素.

注意:我知道这在技术上是一个关于Fabric.js的问题,但是在<canvas>使用Fabric.js 添加对象的上下文中它实际上是一个关于拖放的问题,这就是为什么我要深入一点关于DnD的东西现在.

为了 <img>

  • dragstart (我在这里添加了一个类以降低不透明度)
  • dragend (并在此删除该课程)

用于#canvas-container:

  • dragenter (添加了一个类给画布容器那个漂亮的虚线)
  • dragover:您可以在此处设置event.dataTransfer.dropEffect属性以显示其中一种本机游标类型.默认设置在'move'这里,但我设置它,'copy'因为我实际上没有删除<img>元素(实际上你可以在小提琴中,例如创建几个McClures).
  • dragleave (删除了这里的虚线)
  • drop:此事件的处理程序创建并添加fabric.Image对象(请参阅小提琴).
if (Modernizr.draganddrop) {
    // Browser supports HTML5 DnD.

    // Bind the event listeners for the image elements
    var images = document.querySelectorAll('#images img');
    [].forEach.call(images, function (img) {
        img.addEventListener('dragstart', handleDragStart, false);
        img.addEventListener('dragend', handleDragEnd, false);
    });
    // Bind the event listeners for the canvas
    var canvasContainer = document.getElementById('canvas-container');
    canvasContainer.addEventListener('dragenter', handleDragEnter, false);
    canvasContainer.addEventListener('dragover', handleDragOver, false);
    canvasContainer.addEventListener('dragleave', handleDragLeave, false);
    canvasContainer.addEventListener('drop', handleDrop, false);
} else {
    // Replace with a fallback to a library solution.
    alert("This browser doesn't support the HTML5 Drag and Drop API.");
}
Run Code Online (Sandbox Code Playgroud)

资料来源:

  • @natchiketa 很抱歉恢复旧线程,但是。为什么小提琴不再起作用了?而且,fabricjs 'canvas-container' 是一个类,而不是最新的 Fabricjs 的 id。您可以修复您的代码以便我可以使用它吗?谢谢! (3认同)

Aha*_*iPK 16

我经历了@natchiketa的小提琴,并解决了问题,只是检查这个小提琴..

http://jsfiddle.net/Ahammadalipk/w8kkc/185/

    window.onload = function () {

        var canvas = new fabric.Canvas('canvas');

        /* 
        NOTE: the start and end handlers are events for the <img> elements; the rest are bound to 
        the canvas container.
        */

        function handleDragStart(e) {
            [].forEach.call(images, function (img) {
                img.classList.remove('img_dragging');
            });
            this.classList.add('img_dragging');
        }

        function handleDragOver(e) {
            if (e.preventDefault) {
                e.preventDefault(); 
            }

            e.dataTransfer.dropEffect = 'copy';
            return false;
        }

        function handleDragEnter(e) {                
            this.classList.add('over');
        }

        function handleDragLeave(e) {
            this.classList.remove('over'); 
        }

        function handleDrop(e) {               
            if (e.stopPropagation) {
                e.stopPropagation(); // stops the browser from redirecting.
            }

            var img = document.querySelector('#images img.img_dragging');

            var newImage = new fabric.Image(img, {
                width: img.width,
                height: img.height,
                // Set the center of the new object based on the event coordinates relative
                // to the canvas container.
                left: e.layerX,
                top: e.layerY
            });
            newImage.hasControls = newImage.hasBorders = false;
            canvas.add(newImage);

            return false;
        }

        function handleDragEnd(e) {
            // this/e.target is the source node.
            [].forEach.call(images, function (img) {
                img.classList.remove('img_dragging');
            });
        }

        if (Modernizr.draganddrop) {



            var images = document.querySelectorAll('#images img');
            [].forEach.call(images, function (img) {
                img.addEventListener('dragstart', handleDragStart, false);
                img.addEventListener('dragend', handleDragEnd, false);
            });

            var canvasContainer = document.getElementById("canvas-container");
            canvasContainer.addEventListener('dragenter', handleDragEnter, false);
            canvasContainer.addEventListener('dragover', handleDragOver, false);
            canvasContainer.addEventListener('dragleave', handleDragLeave, false);
            canvasContainer.addEventListener('drop', handleDrop, false);
        } else {

            alert("This browser doesn't support the HTML5 Drag and Drop API.");
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢

  • 感谢您更新jsfiddle它适用于Chrome,但在Firefox中,它会在浏览器中打开图像,而不是在画布上. (3认同)
  • @ AhammadaliPK的答案有效,除了我需要在handleDrop函数中调用preventDefault以使其在firefox上正常工作. (2认同)