Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an option to selection objects only when 100% intersect #4508

Merged
merged 5 commits into from
Nov 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/canvas.class.js
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@
*/
selectionLineWidth: 1,

/**
* Select only shapes that are fully contained in the dragged selection rectangle.
* @type Boolean
* @default
*/
selectionFullyContained: false,

/**
* Default cursor value used when hovering over an object on canvas
* @type String
Expand Down
7 changes: 4 additions & 3 deletions src/mixins/canvas_grouping.mixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
y2 = y1 + this._groupSelector.top,
selectionX1Y1 = new fabric.Point(min(x1, x2), min(y1, y2)),
selectionX2Y2 = new fabric.Point(max(x1, x2), max(y1, y2)),
allowIntersect = !this.selectionFullyContained,
isClick = x1 === x2 && y1 === y2;
// we iterate reverse order to collect top first in case of click.
for (var i = this._objects.length; i--; ) {
Expand All @@ -133,10 +134,10 @@
continue;
}

if (currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2) ||
if ((allowIntersect && currentObject.intersectsWithRect(selectionX1Y1, selectionX2Y2)) ||
currentObject.isContainedWithinRect(selectionX1Y1, selectionX2Y2) ||
currentObject.containsPoint(selectionX1Y1) ||
currentObject.containsPoint(selectionX2Y2)
(allowIntersect && currentObject.containsPoint(selectionX1Y1)) ||
(allowIntersect && currentObject.containsPoint(selectionX2Y2))
) {
group.push(currentObject);

Expand Down
41 changes: 41 additions & 0 deletions test/unit/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,47 @@
assert.equal(collected[2], rect1, 'rect1 is collected');
});

QUnit.test('_collectObjects collects object fully contained in area', function(assert) {
canvas.selectionFullyContained = true;
var rect1 = new fabric.Rect({ width: 10, height: 10, top: 0, left: 0 });
var rect2 = new fabric.Rect({ width: 10, height: 10, top: 0, left: 10 });
var rect3 = new fabric.Rect({ width: 10, height: 10, top: 10, left: 0 });
var rect4 = new fabric.Rect({ width: 10, height: 10, top: 10, left: 10 });
canvas.add(rect1, rect2, rect3, rect4);
canvas._groupSelector = {
top: 30,
left: 30,
ex: -1,
ey: -1
};
var collected = canvas._collectObjects();
assert.equal(collected.length, 4, 'a rect that contains all objects collects them all');
assert.equal(collected[3], rect1, 'contains rect1 as last object');
assert.equal(collected[2], rect2, 'contains rect2');
assert.equal(collected[1], rect3, 'contains rect3');
assert.equal(collected[0], rect4, 'contains rect4 as first object');
canvas.selectionFullyContained = false;
});

QUnit.test('_collectObjects does not collect objects not fully contained', function(assert) {
canvas.selectionFullyContained = true;
var rect1 = new fabric.Rect({ width: 10, height: 10, top: 0, left: 0 });
var rect2 = new fabric.Rect({ width: 10, height: 10, top: 0, left: 10 });
var rect3 = new fabric.Rect({ width: 10, height: 10, top: 10, left: 0 });
var rect4 = new fabric.Rect({ width: 10, height: 10, top: 10, left: 10 });
canvas.add(rect1, rect2, rect3, rect4);
canvas._groupSelector = {
top: 20,
left: 20,
ex: 5,
ey: 5
};
var collected = canvas._collectObjects();
assert.equal(collected.length, 1, 'a rect intersecting objects does not collect those');
assert.equal(collected[0], rect4, 'contains rect1 as only one fully contained');
canvas.selectionFullyContained = false;
});

QUnit.test('_fireSelectionEvents fires multiple things', function(assert) {
var rect1Deselected = false;
var rect3Selected = false;
Expand Down