PaperJS how to find the nearest item to a mouse event within a Group item












0















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)










share|improve this question


















  • 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













  • 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
















0















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)










share|improve this question


















  • 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













  • 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














0












0








0








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)










share|improve this question














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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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














  • 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













  • 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








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












1 Answer
1






active

oldest

votes


















0














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;





share|improve this answer























    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
    });


    }
    });














    draft saved

    draft discarded


















    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









    0














    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;





    share|improve this answer




























      0














      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;





      share|improve this answer


























        0












        0








        0







        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;





        share|improve this answer













        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;






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 20 '18 at 22:32









        Scott AndersonScott Anderson

        12410




        12410






























            draft saved

            draft discarded




















































            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.




            draft saved


            draft discarded














            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





















































            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







            Popular posts from this blog

            Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

            ComboBox Display Member on multiple fields

            Is it possible to collect Nectar points via Trainline?