如何将 SVG 文件拖放到 Fabricjs canvas?

How to drag and drop SVG file to Fabricjs canvas?

我正在尝试将 canvas 之外的 svg img 拖放到 canvas 本身,它确实适用于简单图像(png、jpg、gif),但不适用于 svg文件,因为我是 fabricJS 的新手,所以我想知道如何配置它以便它也适用于 SVG。 我不想从 SVG 创建 fabric.Image 对象,我想将它们作为 fabric.PathGroup 删除,以便它们保留矢量信息和编辑功能。

您可以在这个 link 上发现该项目:

http://jsfiddle.net/w8kkc/309/

HTML

<div id="images">
    <img draggable="true" src="http://i.imgur.com/8rmMZI3.jpg" width="100" height="100">
    <object draggable="true" type="image/svg+xml" data="http://fabricjs.com/assets/1.svg" width="100" height="100"></object>
</div>

<div id="canvas-container">
    <canvas id="canvas" width="400" height="250"></canvas>
</div>

Javascript (FabricJS)

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

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(); // Necessary. Allows us to drop.
    }

    e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
    // NOTE: comment above refers to the article (see top) -natchiketa

    return false;
}

function handleDragEnter(e) {
    // this / e.target is the current hover target.
    this.classList.add('over');
}

function handleDragLeave(e) {
    this.classList.remove('over'); // this / e.target is previous target element.
}

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

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

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

    // console.log('event: ', e);

    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
    });
    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) {
    // 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.");
}

关于我如何接受将 SVG 拖放到 canvas 中的任何建议?

这是更新后的 fiddle:http://jsfiddle.net/sunny001/43zvqq2g/2/

我为 svg 使用 img 标签:

   <img draggable="true" src="http://i.imgur.com/8rmMZI3.jpg" width="100" height="100">
   <img draggable="true" src="http://fabricjs.com/assets/1.svg" width="100" height="100"/>

您所有的 "drag" 代码都需要一个 img 标记,而不是 object(您拥有的)。我尝试调整代码以也与 object 标签一起使用,但它不起作用——不知道为什么,或者它是否应该。

http://jsfiddle.net/w8kkc/336/ 已更新 fiddle

JAVASCRIPT

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

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

function handleDragOver(e) {
    if (e.preventDefault) {
        e.preventDefault(); // Necessary. Allows us to drop.
    }

    e.dataTransfer.dropEffect = 'copy'; // See the section on the DataTransfer object.
    // NOTE: comment above refers to the article (see top) -natchiketa

    return false;
}

function handleDragEnter(e) {
    // this / e.target is the current hover target.
    this.classList.add('over');
}

function handleDragLeave(e) {
    this.classList.remove('over'); // this / e.target is previous target element.
}

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

 
        
    // console.log('event: ', e);
    var ext = currentlyDragging.src.substr(-3);
    if (ext === 'svg') {
      fabric.loadSVGFromURL(currentlyDragging.src, function(objects, options) {
        var svg = fabric.util.groupSVGElements(objects, options);
        svg.left = e.layerX;
        svg.top = e.layerY;
        canvas.add(svg); 
      });
    } else {
       var newImage = new fabric.Image(currentlyDragging, {
          width: currentlyDragging.width,
          height: currentlyDragging.height,
          // Set the center of the new object based on the event coordinates relative
          // to the canvas container.
          left: e.layerX,
          top: e.layerY
      });
      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) {
    // Browser supports HTML5 DnD.

    // Bind the event listeners for the image elements
    var images = document.querySelectorAll('#images img');
    var objects = document.querySelectorAll('#images object');
    [].forEach.call(images, function (img) {
        img.addEventListener('dragstart', handleDragStart, false);
        img.addEventListener('dragend', handleDragEnd, false);
    });
    [].forEach.call(objects, function (obj) {
        obj.addEventListener('dragstart', handleDragStart, false);
        obj.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.");
}