如何精确查询Paper.js中的选中项?
How to query exactly selected items in Paper.js?
根据我的理解,project.getItems({selected: true})
returns 错误的结果:我正在选择一条曲线,它 returns 父路径:Sketch
尝试单击曲线或线段。整个路径将被移动。然后尝试通过将 var workaround = false
设置为 var workaround = true
来更改行为以观察所需的行为。
我怎样才能准确地知道真正选中的是什么?
当前解决方法
我目前正在选择将这些对象添加到数组中并使用这些项目而不是 project.getItems({selected: true})
。
问题是在 Paper.js
体系结构中,curves and segments are not items (they are part of a specific item
which is the path
). So you shouldn't expect project.getItems() 到 return 除了 items
。
您必须知道的另一件事是,如果选择了路径的任何部分(curves
、segments
、points
、handles
,则假定选择了路径position
、bounds
、...)。如果选择了曲线的所有部分(points
和 handles
),则假定选择了曲线。
考虑到这一点,您可以创建一个算法来检索基于 project.getItems({selected: true})
作为其第一部分的 "what is really selected"。然后,你需要遍历 curves
和 segments
来检查它们是否被选中。
这里 sketch 展示了一个可能的解决方案。
var vector = new Point(10, 10);
// Create path.
var path = new Path({
segments: [
[100, 100],
[200, 100],
[260, 170],
[360, 170],
[420, 250]
],
strokeColor: 'red',
strokeWidth: 10
});
// Translate given thing along global vector.
function translateThing(thing) {
switch (thing.getClassName()) {
case 'Path':
thing.position += vector;
break;
case 'Curve':
thing.segment1.point += vector;
thing.segment2.point += vector;
break;
case 'Segment':
thing.point += vector;
break;
}
}
// On mouse down...
function onMouseDown(event) {
// ...only select what was clicked.
path.selected = false;
hit = paper.project.hitTest(event.point);
if (hit && hit.location) {
hit.location.curve.selected = true;
}
else if (hit && hit.segment) {
hit.segment.selected = true;
}
// We check all items for demo purpose.
// Move all selected things.
// First get selected items in active layer...
project.activeLayer.getItems({ selected: true })
// ...then map them to what is really selected...
.map(getSelectedThing)
// ...then translate them.
.forEach(translateThing);
}
// This method returns what is really selected in a given item.
// Here we assume that only one thing can be selected at the same time.
// Returned thing can be either a Curve, a Segment or an Item.
function getSelectedThing(item) {
// Only check curves and segments if item is a path.
if (item.getClassName() === 'Path') {
// Check curves.
for (var i = 0, l = item.curves.length; i < l; i++) {
if (item.curves[i].selected) {
return item.curves[i];
}
}
// Check segments.
for (var i = 0, l = item.segments.length; i < l; i++) {
if (item.segments[i].selected) {
return item.segments[i];
}
}
}
// return item by default.
return item;
}
也就是说,根据您的实际用例,您当前的解决方法可能比这种方法更合适。
根据我的理解,project.getItems({selected: true})
returns 错误的结果:我正在选择一条曲线,它 returns 父路径:Sketch
尝试单击曲线或线段。整个路径将被移动。然后尝试通过将 var workaround = false
设置为 var workaround = true
来更改行为以观察所需的行为。
我怎样才能准确地知道真正选中的是什么?
当前解决方法
我目前正在选择将这些对象添加到数组中并使用这些项目而不是 project.getItems({selected: true})
。
问题是在 Paper.js
体系结构中,curves and segments are not items (they are part of a specific item
which is the path
). So you shouldn't expect project.getItems() 到 return 除了 items
。
您必须知道的另一件事是,如果选择了路径的任何部分(curves
、segments
、points
、handles
,则假定选择了路径position
、bounds
、...)。如果选择了曲线的所有部分(points
和 handles
),则假定选择了曲线。
考虑到这一点,您可以创建一个算法来检索基于 project.getItems({selected: true})
作为其第一部分的 "what is really selected"。然后,你需要遍历 curves
和 segments
来检查它们是否被选中。
这里 sketch 展示了一个可能的解决方案。
var vector = new Point(10, 10);
// Create path.
var path = new Path({
segments: [
[100, 100],
[200, 100],
[260, 170],
[360, 170],
[420, 250]
],
strokeColor: 'red',
strokeWidth: 10
});
// Translate given thing along global vector.
function translateThing(thing) {
switch (thing.getClassName()) {
case 'Path':
thing.position += vector;
break;
case 'Curve':
thing.segment1.point += vector;
thing.segment2.point += vector;
break;
case 'Segment':
thing.point += vector;
break;
}
}
// On mouse down...
function onMouseDown(event) {
// ...only select what was clicked.
path.selected = false;
hit = paper.project.hitTest(event.point);
if (hit && hit.location) {
hit.location.curve.selected = true;
}
else if (hit && hit.segment) {
hit.segment.selected = true;
}
// We check all items for demo purpose.
// Move all selected things.
// First get selected items in active layer...
project.activeLayer.getItems({ selected: true })
// ...then map them to what is really selected...
.map(getSelectedThing)
// ...then translate them.
.forEach(translateThing);
}
// This method returns what is really selected in a given item.
// Here we assume that only one thing can be selected at the same time.
// Returned thing can be either a Curve, a Segment or an Item.
function getSelectedThing(item) {
// Only check curves and segments if item is a path.
if (item.getClassName() === 'Path') {
// Check curves.
for (var i = 0, l = item.curves.length; i < l; i++) {
if (item.curves[i].selected) {
return item.curves[i];
}
}
// Check segments.
for (var i = 0, l = item.segments.length; i < l; i++) {
if (item.segments[i].selected) {
return item.segments[i];
}
}
}
// return item by default.
return item;
}
也就是说,根据您的实际用例,您当前的解决方法可能比这种方法更合适。