我想在画布上拖动外部图像并且它与该画布对象相交时,找到画布中已存在的对象。这是我用于拖放的代码:
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.");
}
上面提到的回调函数是相应定义的。
我已经知道的是,当两个对象存在于画布中时,我们可以找到它们之间的交集。链接:http://fabricjs.com/intersection/
但我的问题是,当我将画布从画布外部拖到画布区域并且它与画布对象相交时,我需要捕捉对象。
非常感谢任何帮助。感谢。
答案 0 :(得分:6)
关于碰撞测试
基本形状往往有两种形式:矩形和圆形的。
您需要进行这些测试,看看是否有任何这些基本形状发生碰撞:
function rectsColliding(r1,r2){
return(!(
r1.x > r2.x+r2.width ||
r1.x+r1.width < r2.x ||
r1.y > r2.y+r2.height ||
r1.y+r1.height < r2.y
));
}
function circlesColliding(c1,c2){
var dx=c2.x-c1.x;
var dy=c2.y-c1.y;
var sumR=c1.radius+c2.radius;
return( dx*dx+dy*dy <= sumR*sumR );
}
function rectCircleColliding(circle,rect){
var distX = Math.abs(circle.x - rect.x-rect.w/2);
var distY = Math.abs(circle.y - rect.y-rect.h/2);
if (distX > (rect.w/2 + circle.r)) { return false; }
if (distY > (rect.h/2 + circle.r)) { return false; }
if (distX <= (rect.w/2)) { return true; }
if (distY <= (rect.h/2)) { return true; }
var dx=distX-rect.w/2;
var dy=distY-rect.h/2;
return (dx*dx+dy*dy<=(circle.r*circle.r));
}
有关draggable
原生html5 draggable
系统仍然存在一些跨浏览器的不一致性。当拖动拖拽时,很难获得准确的[x,y]位置。相反,您可以使用jQueryUI可拖动系统来平滑浏览器之间的不一致。
测试拖动的DOM元素是否与FabricJS形状碰撞的计划
dragmove
事件,rectsColliding
函数来测试2个边界框是否发生碰撞,以下是示例代码和演示:
// attach the canvas's bounding box to itself
var canvasElement=document.getElementById("c");
canvasElement.bb=canvasElement.getBoundingClientRect();
// create a wrapper around native canvas element (with id="c")
var canvas = new fabric.Canvas('c');
var rect;
// load an image and begin...
var image1=new Image();
image1.onload=function(){
createFabrics();
createDraggables();
}
image1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png";
// create a fabric rect and add it to the stage
function createFabrics(){
// create a rectangle object
rect = new fabric.Rect({
left: 100,
top: 20,
fill: 'green',
width: 100,
height: 75,
lockMovementX:true,
lockMovementY:true,
lockScalingX:true,
lockScalingY:true,
lockRotation:true,
hasControls:false,
});
rect.bb=rect.getBoundingRect();
// "add" rectangle onto canvas
canvas.add(rect);
canvas.renderAll();
}
// Make the previously created image draggable
// Detect collisions between the image and the FabricJS rect
function createDraggables(){
var $house=$("#house");
var $canvas=$("#c");
// make the canvas element a dropzone
$canvas.droppable({ drop:dragDrop, hoverClass:'drop-hover' });
// make the house draggable
$house.draggable({
helper:'clone',
// optional event handlers are...
start:dragstart,
drag:dragmove,
stop:dragend,
});
// set the data payload
$house.data("image",image1); // key-value pair
function dragstart(e,ui){}
function dragend(e,ui){}
function dragDrop(e,ui){}
function dragmove(e,ui){
var target=e.target;
var tbb={
left:ui.offset.left-canvasElement.bb.left,
top:ui.offset.top-canvasElement.bb.top,
width:target.width,
height:target.height
}
if( rectsColliding(tbb,rect.bb) ){
rect.fill='red';
canvas.renderAll();
}else{
rect.fill='green';
canvas.renderAll();
}
}
function rectsColliding(r1,r2){
return(!(
r1.left > r2.left+r2.width ||
r1.left+r1.width < r2.left ||
r1.top > r2.top+r2.height ||
r1.top+r1.height < r2.top
));
}
} // end createDraggables
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="http://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<h4 id=hit>Drag house over green FabricJS rect.<br>Rect will turn red during collisions.</h4>
<img id="house" width=32 height=32 src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png"><br>
<canvas id='c' width=300 height=150></canvas>