Reputation: 765
Any suggestion on select multi objects on canvas mouse click? not all object, I want to select objects that overlay on the point.
For my knowledge, the target on mouse event is always the top most object only. I had tried to bind event on object, but it wont fired for those at the back side. I had tried select based on item size and height, but it is not working perfectly after rotate.
var canvas = this.__canvas = new fabric.Canvas('c', {
enableRetinaScaling: false
});
function LoopOnObjects(e) {
var mouse = canvas.getPointer(e.e, false);
var x = Math.ceil(mouse.x);
var y = Math.ceil(mouse.y);
var count = 0;
canvas.getObjects().forEach(function(object, index){
if(CheckObjectWithin(object, x, y)) {
count++;
}
});
alert("ya, there is " + count + " objects touch on click");
}
function CheckObjectWithin(object, x, y) {
var objectBoundRect = object.getBoundingRect(true);
var widthRange = objectBoundRect.width;
var heightRange = objectBoundRect.height;
if (x > objectBoundRect.left && x < objectBoundRect.left + widthRange) {
if (y > objectBoundRect.top && y < objectBoundRect.top + heightRange) {
return true;
}
}
return false;
}
function GetElement(e) {
LoopOnObjects(e);
}
canvas.on("mouse:up", GetElement);
canvas.add(new fabric.Rect({
width: 100, height: 100, left: 100, top: 20, angle: -10,
fill: 'rgba(0,200,0,0.5)'
}));
canvas.add(new fabric.Rect({
width: 50, height: 100, left: 220, top: 80, angle: 45,
stroke: '#eee', strokeWidth: 10,
fill: 'rgba(0,0,200,0.5)'
}));
canvas.add(new fabric.Circle({
radius: 50, left: 220, top: 175, fill: '#aac'
}));
Upvotes: 1
Views: 3125
Reputation: 5018
Actually, there is already a library method for that: fabric.Object.prototype.containsPoint(). It works with rotate, but keep in mind that the point is checked against the bounding box, not the visible shape (e.g. circle shape still has a rectangular bounding box).
var canvas = this.__canvas = new fabric.Canvas('c');
function loopOnObjects(e) {
var mouse = canvas.getPointer(e.e, false);
var point = new fabric.Point(mouse.x, mouse.y)
var count = 0;
canvas.getObjects().forEach(function(object, index){
if (object.containsPoint(point)) {
count++;
}
});
}
function getElement(e) {
loopOnObjects(e);
}
canvas.on("mouse:down", getElement);
canvas.add(new fabric.Rect({
width: 100, height: 100, left: 100, top: 20, angle: -10,
fill: 'rgba(0,200,0,0.5)'
}));
canvas.add(new fabric.Rect({
width: 50, height: 100, left: 220, top: 80, angle: 45,
stroke: '#eee', strokeWidth: 10,
fill: 'rgba(0,0,200,0.5)'
}));
canvas.add(new fabric.Circle({
radius: 50, left: 220, top: 175, fill: '#aac'
}));
#c {
border: 1px black solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.22/fabric.min.js"></script>
<canvas id="c" width="500" height="300"></canvas>
Upvotes: 6