PaperJS how to find the nearest item to a mouse event within a Group item
I am currently trying to make an interactive editor for a complex & large SVG item with PaperJS. All the paths of the SVG are nested inside of a Group
object, in fact children of the Group
object are CompoundPaths
.
I want to be able to select a specific Path
within the Group
via mouse click, but I don't want my script to be (even more) computationally heavy, so I don't want to have to iterate all of the path items (just less than 1000 Path items, yes I know) or to have to try and add event handlers to all path items within the Group.
I have seen another answer which talks about selecting the nearest point but this method is not available for a Group item unfortunately, so what is the workaround? (if any)
javascript svg paperjs
add a comment |
I am currently trying to make an interactive editor for a complex & large SVG item with PaperJS. All the paths of the SVG are nested inside of a Group
object, in fact children of the Group
object are CompoundPaths
.
I want to be able to select a specific Path
within the Group
via mouse click, but I don't want my script to be (even more) computationally heavy, so I don't want to have to iterate all of the path items (just less than 1000 Path items, yes I know) or to have to try and add event handlers to all path items within the Group.
I have seen another answer which talks about selecting the nearest point but this method is not available for a Group item unfortunately, so what is the workaround? (if any)
javascript svg paperjs
1
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code thatPaper.js
uses for the path.getNearestPoint() method you wished to use on aGroup
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?
– sasensi
Nov 20 '18 at 7:52
Other than iteration in that case, no. I had been looking at theMouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method
– Scott Anderson
Nov 20 '18 at 21:06
add a comment |
I am currently trying to make an interactive editor for a complex & large SVG item with PaperJS. All the paths of the SVG are nested inside of a Group
object, in fact children of the Group
object are CompoundPaths
.
I want to be able to select a specific Path
within the Group
via mouse click, but I don't want my script to be (even more) computationally heavy, so I don't want to have to iterate all of the path items (just less than 1000 Path items, yes I know) or to have to try and add event handlers to all path items within the Group.
I have seen another answer which talks about selecting the nearest point but this method is not available for a Group item unfortunately, so what is the workaround? (if any)
javascript svg paperjs
I am currently trying to make an interactive editor for a complex & large SVG item with PaperJS. All the paths of the SVG are nested inside of a Group
object, in fact children of the Group
object are CompoundPaths
.
I want to be able to select a specific Path
within the Group
via mouse click, but I don't want my script to be (even more) computationally heavy, so I don't want to have to iterate all of the path items (just less than 1000 Path items, yes I know) or to have to try and add event handlers to all path items within the Group.
I have seen another answer which talks about selecting the nearest point but this method is not available for a Group item unfortunately, so what is the workaround? (if any)
javascript svg paperjs
javascript svg paperjs
asked Nov 19 '18 at 19:40
Scott AndersonScott Anderson
12410
12410
1
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code thatPaper.js
uses for the path.getNearestPoint() method you wished to use on aGroup
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?
– sasensi
Nov 20 '18 at 7:52
Other than iteration in that case, no. I had been looking at theMouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method
– Scott Anderson
Nov 20 '18 at 21:06
add a comment |
1
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code thatPaper.js
uses for the path.getNearestPoint() method you wished to use on aGroup
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?
– sasensi
Nov 20 '18 at 7:52
Other than iteration in that case, no. I had been looking at theMouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method
– Scott Anderson
Nov 20 '18 at 21:06
1
1
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code that
Paper.js
uses for the path.getNearestPoint() method you wished to use on a Group
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?– sasensi
Nov 20 '18 at 7:52
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code that
Paper.js
uses for the path.getNearestPoint() method you wished to use on a Group
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?– sasensi
Nov 20 '18 at 7:52
Other than iteration in that case, no. I had been looking at the
MouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method– Scott Anderson
Nov 20 '18 at 21:06
Other than iteration in that case, no. I had been looking at the
MouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method– Scott Anderson
Nov 20 '18 at 21:06
add a comment |
1 Answer
1
active
oldest
votes
This question can be resolved with the .hitTest()
function which is also applicable to a Group
object.
When using a mouse event such as 'click', within the callback function simply use the point from the event and feed it into the <groupName>.hitTest()
.
Note that the options here can be quite crucial, make sure to specify the 'class' option as path (or another suitable paperJS Item
derivative that you are looking for. In terms of additional options I resolved for the hit-test to only detect fill as all the items I am selecting are filled, if your items are not filled then set 'stroke' to true instead of 'fill' and then make sure to click on the path boundary not the body of the shape. Below is an example of code to implement a mouse event followed by a hit-test:
tool.onMouseDown = function(event) {
var result = groupItem.hitTest(event.point, {fill: true, stroke: false, segments: false, class: Path});
console.log(result);
result.item.selected = true;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381546%2fpaperjs-how-to-find-the-nearest-item-to-a-mouse-event-within-a-group-item%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
This question can be resolved with the .hitTest()
function which is also applicable to a Group
object.
When using a mouse event such as 'click', within the callback function simply use the point from the event and feed it into the <groupName>.hitTest()
.
Note that the options here can be quite crucial, make sure to specify the 'class' option as path (or another suitable paperJS Item
derivative that you are looking for. In terms of additional options I resolved for the hit-test to only detect fill as all the items I am selecting are filled, if your items are not filled then set 'stroke' to true instead of 'fill' and then make sure to click on the path boundary not the body of the shape. Below is an example of code to implement a mouse event followed by a hit-test:
tool.onMouseDown = function(event) {
var result = groupItem.hitTest(event.point, {fill: true, stroke: false, segments: false, class: Path});
console.log(result);
result.item.selected = true;
add a comment |
This question can be resolved with the .hitTest()
function which is also applicable to a Group
object.
When using a mouse event such as 'click', within the callback function simply use the point from the event and feed it into the <groupName>.hitTest()
.
Note that the options here can be quite crucial, make sure to specify the 'class' option as path (or another suitable paperJS Item
derivative that you are looking for. In terms of additional options I resolved for the hit-test to only detect fill as all the items I am selecting are filled, if your items are not filled then set 'stroke' to true instead of 'fill' and then make sure to click on the path boundary not the body of the shape. Below is an example of code to implement a mouse event followed by a hit-test:
tool.onMouseDown = function(event) {
var result = groupItem.hitTest(event.point, {fill: true, stroke: false, segments: false, class: Path});
console.log(result);
result.item.selected = true;
add a comment |
This question can be resolved with the .hitTest()
function which is also applicable to a Group
object.
When using a mouse event such as 'click', within the callback function simply use the point from the event and feed it into the <groupName>.hitTest()
.
Note that the options here can be quite crucial, make sure to specify the 'class' option as path (or another suitable paperJS Item
derivative that you are looking for. In terms of additional options I resolved for the hit-test to only detect fill as all the items I am selecting are filled, if your items are not filled then set 'stroke' to true instead of 'fill' and then make sure to click on the path boundary not the body of the shape. Below is an example of code to implement a mouse event followed by a hit-test:
tool.onMouseDown = function(event) {
var result = groupItem.hitTest(event.point, {fill: true, stroke: false, segments: false, class: Path});
console.log(result);
result.item.selected = true;
This question can be resolved with the .hitTest()
function which is also applicable to a Group
object.
When using a mouse event such as 'click', within the callback function simply use the point from the event and feed it into the <groupName>.hitTest()
.
Note that the options here can be quite crucial, make sure to specify the 'class' option as path (or another suitable paperJS Item
derivative that you are looking for. In terms of additional options I resolved for the hit-test to only detect fill as all the items I am selecting are filled, if your items are not filled then set 'stroke' to true instead of 'fill' and then make sure to click on the path boundary not the body of the shape. Below is an example of code to implement a mouse event followed by a hit-test:
tool.onMouseDown = function(event) {
var result = groupItem.hitTest(event.point, {fill: true, stroke: false, segments: false, class: Path});
console.log(result);
result.item.selected = true;
answered Nov 20 '18 at 22:32
Scott AndersonScott Anderson
12410
12410
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53381546%2fpaperjs-how-to-find-the-nearest-item-to-a-mouse-event-within-a-group-item%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
I don't think that it is even conceptually possible to compare multiple items distances to a point without iterating through them. If you look at the internal code that
Paper.js
uses for the path.getNearestPoint() method you wished to use on aGroup
, you will see that it it what it does: it iterates through all the path curves and search the closest one to the point... Do you have another algorithm idea than using a loop to do that ?– sasensi
Nov 20 '18 at 7:52
Other than iteration in that case, no. I had been looking at the
MouseEvent.target
property though as I thought it would give me more specificity as to what was targeted on the mouse event, but it returns the canvas, even when using the .stopPropagation() method– Scott Anderson
Nov 20 '18 at 21:06