2016-11-20 14 views
3

Кто-нибудь создал инструмент для ручной или лассо-выбора для бумаги, как у вас в Adobe Illustartor?Paper.js инструмент для выбора лассо

Я пытался использовать для этого , но это работает только в том случае, если мой путь выбора попадает в любые другие пути напрямую, а не в том случае, если есть элементы внутри выделения, даже если я делаю это раньше на onMouseUp.

isInside(rect) выглядит многообещающим, но он может только проверить, что-то внутри прямоугольника, а не свободного пути.

Вот несколько примеров:

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)); 
+1

Вы ищете субтрактивную булевую операцию. В последнее время была проведена большая работа, связанная с BoolOps, которая включена в Paper.js. Но только для того, чтобы прояснить ситуацию, что вы пытаетесь вытащить? Растеры или векторы? Они работают по-другому –

+0

BoolOps сделал это, см. Ответ ниже. Я не сто процентов удовлетворен, так как они создают и рисуют дополнительную геометрию в Paper.js. Возможно, мне придется добавить предварительную проверку ограничительного прямоугольника по соображениям производительности. Только векторы. Не могу себе представить, как что-то подобное будет работать для растровой графики. –

+0

Если Растровое изображение является прямоугольным (как это обычно бывает), вы можете отрубить (вычесть), используя BoolOps, часть векторного прямоугольника, равную ширине/высоте вашего растрового изображения. Затем установите растровое изображение как mask/background-image вычитаемой формы. –

ответ

0

Вы можете использовать jsclipper пересекаться многоугольники.

This is the original Clipper library и its documentation.

Функция PointInPolygon() может вам помочь.

+0

Невозможно найти геометрический тест «путь внутри пути». Похоже, что этот lib поставляется с 150kb функциональности, которая в основном включает paper.js. Поднять его в моем рабочем процессе webpack было бы нелегко, так как у него нет package.json. У вас есть идея функции или алгоритма, которые я могу оттуда оттуда? –

+0

Я отредактировал свой ответ, надеюсь, что помогает –

+0

Я ищу функцию «PolygonInPolygon» –

1

Булевые операции работали для меня. Они не являются геометрическими тестами и создают дополнительные элементы, которые нужно удалить, но это похоже на лучшее решение, которое я могу получить. isEmpty() проверяет, если форма результата содержит любые сегменты после вычитания.

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