Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Paper.js lasso-select tool

Has anyone built a free-hand or lasso-select tool for paperjs like you have in Adobe Illustartor?

I was trying to use intersects(item) for that, but this only seems to work if my selection path hits any other paths directly and not if there are items inside the selection, even if I colse it before on onMouseUp.

isInside(rect) looked promising but it can only check if something is inside a rectangle and not free-hand path.

Here is some example:

var item1 = Path.Circle(new Point(180, 100), 20);
item1.fillColor = "black";

var item2 = Path.Rectangle(new Point(150, 180), new Size(50, 50));
item2.fillColor = "black";

var selection = new Path([
    new Point(50, 50),
    new Point(50, 250),
    new Point(250, 250),
    new Point(250, 150),
    new Point(150, 150)
]);
selection.closed = true;

selection.strokeColor = "blue";
selection.fillColor = new Color(0, 0, 50, 0.5);

function selectionContains(item) {
    // does not work as expected
    return selection.intersects(item);
}

// should be false
console.log(selectionContains(item1));

// should be true but is false
console.log(selectionContains(item2));
like image 582
Andreas Neumann Avatar asked Jan 17 '26 05:01

Andreas Neumann


1 Answers

Boolean operations worked for me. They are not geometric tests and create extra items that have to be removed but it looks like the best solution I can get. isEmpty() tests if the result shape contains any segments after the subtraction.

var red = Path.Circle(new Point(180, 100), 20);
red.fillColor = "red";
red.name = "red";

var green = Path.Rectangle(new Point(150, 180), new Size(50, 50));
green.fillColor = "green";
green.name = "green";

var yellow = Path.Circle(new Point(90, 100), 20);
yellow.fillColor = "yellow";
yellow.name = "yellow";

var purple = Path.Rectangle(new Point(160, 190), new Size(30, 30));
purple.fillColor = "purple";
purple.name = "purple";

var selection = new Path([
    new Point(50, 50),
    new Point(50, 250),
    new Point(250, 250),
    new Point(250, 150),
    new Point(150, 150)
]);
selection.closed = true;
selection.strokeColor = "blue";
selection.fillColor = new Color(0, 0, 50, 0.2);


function isInside(_selection, _item) {

    var result = _item.subtract(_selection);
    var insideSelection = result.isEmpty();
    result.remove();

    return insideSelection;
}

function test(_item) {
    console.log(_item.name, isInside(selection, _item) ? " inside" : " outside");
}

test(red); // red  outside
test(green); // green  inside
test(yellow); // yellow  outside
test(purple); // purple  inside
like image 178
Andreas Neumann Avatar answered Jan 19 '26 19:01

Andreas Neumann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!