如何将物品(如图像或其他来自外部画布的对象)放入由fabricjs管理的画布中?我找到了许多在画布内移动物品的示例,但我想从外部元素中拖放物品到画布中。
如何将物品(如图像或其他来自外部画布的对象)放入由fabricjs管理的画布中?我找到了许多在画布内移动物品的示例,但我想从外部元素中拖放物品到画布中。
既然您要求一个例子,而我自己还没有尝试过,那么这里就是:
<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>
Fabric.canvas
实例首先,我们当然需要我们的画布:
var canvas = new fabric.Canvas('c');
不确定这是否必要,因为您拥有画布意味着浏览器很可能也支持拖放功能。如果您决定使用它,可以像这样使用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.");
}
与下面的源文章不同,此处的源元素和目标元素是不同的(在该文章的示例中,您只需在同一父容器中移动
注意:我知道这实际上是关于Fabric.js的问题,但在向
对于<img>
dragstart
(我在这里添加了一个类来降低不透明度)dragend
(并在此处删除了该类)对于#canvas-container
:
dragenter
(添加了一个类来给画布容器带来漂亮的虚线)dragover
:在这里,您可以设置event.dataTransfer.dropEffect
属性以显示本机光标类型之一。默认情况下,这里应为'move'
,但由于我实际上没有删除<img>
元素(事实上,在fiddle中,您可以创建多个McClures),因此我将其设置为'copy'
。dragleave
(在此处删除了虚线)drop
:此事件的处理程序创建并添加fabric.Image
对象(请参见fiddle)。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.");
}
参考资料:
我已经查看了@natchiketa的fiddle,并解决了问题,只需检查这个fiddle即可。
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.");
}
}
谢谢
嗯,这个问题相当古老^^
我已经更新了这个代码片段,在Firefox中也可以正常工作。
function handleDrop(e) {
// this / e.target is current target element.
e.preventDefault(); //I've altert this line for FireFox
接受的答案已经不再适用。
这是用于从桌面拖放的dataTransfer接口。
canvas.on('drop', function(event) {
// prevent the file to open in new tab
event.e.stopPropagation();
event.e.stopImmediatePropagation();
event.e.preventDefault();
// Use DataTransfer interface to access the file(s)
if(event.e.dataTransfer.files.length > 0){
var files = event.e.dataTransfer.files;
for (var i = 0, f; f = files[i]; i++) {
// Only process image files.
if (f.type.match('image.*')) {
// Read the File objects in this FileList.
var reader = new FileReader();
// listener for the onload event
reader.onload = function(evt) {
// put image on canvas
fabric.Image.fromURL(evt.target.result, function(obj) {
obj.scaleToHeight(canvas.height);
obj.set('strokeWidth',0);
canvas.add(obj);
});
};
// Read in the image file as a data URL.
reader.readAsDataURL(f);
}
}
}
});
资源
https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop
<div class="img_cont">
<img class="img" id="ele1" draggable="true" ondragstart="dragElement(event)" src="https://webkit.org/wp-content/uploads/STP-300x300.png">
<img class="img" id="ele2" draggable="true" ondragstart="dragElement(event)" src="https://webkit.org/wp-content/uploads/ephy-webkit-graphic.png">
<img class="img" id="ele3" draggable="true" ondragstart="dragElement(event)" src="https://res.cloudinary.com/css-tricks/image/upload/w_600,q_auto,f_auto/buysellads/uu/7/112766/1646327381-MC_CSSTricks_Logo_600x600-_1_.png">
<img class="img" id="ele4" draggable="true" ondragstart="dragElement(event)" src="https://miro.medium.com/max/1400/1*9hd_8qR0CMZ8L0pVbFLjDw.png">
</div>
<br>
<div id="canvas_cont" ondragover="allowDrop(event)" ondrop="dropElement(event)">
<canvas id="canvas" width="650" height="350" ></canvas>
</div>
JavaScript 代码
// allowDrop function called on ondragover event.
function allowDrop(e) {
e.preventDefault();
}
//dragElement function called on ondrag event.
function dragElement(e) {
e.dataTransfer.setData("id", e.target.id); //transfer the "data" i.e. id of the target dragged.
}
//Initializing fabric canvas on window load event.
var canvas;
window.onload = function(){
canvas = new fabric.Canvas(document.getElementById("canvas"));
}
//dropElement function called on ondrop event.
function dropElement(e) {
e.preventDefault();
var data = e.dataTransfer.getData("id"); //receiving the "data" i.e. id of the target dropped.
var imag = document.getElementById(data); //getting the target image info through its id.
var img = new fabric.Image(imag, { //initializing the fabric image.
left: e.layerX - 80, //positioning the target on exact position of mouse event drop through event.layerX,Y.
top: e.layerY - 40,
});
img.scaleToWidth(imag.width); //scaling the image height and width with target height and width, scaleToWidth, scaleToHeight fabric inbuilt function.
img.scaleToHeight(imag.height);
canvas.add(img);
}