Loading ...
Sorry, an error occurred while loading the content.

how to identify all elements at a point?

Expand Messages
  • simonshutter
    Hi folks, Is there a way that I can use the event model to identify all elements that overlap a specific point on a mouse down/move event? Or, do I have to
    Message 1 of 7 , Jul 31, 2007
    • 0 Attachment
      Hi folks,

      Is there a way that I can use the event model to identify all elements
      that overlap a specific point on a mouse down/move event? Or, do I
      have to use clientX/Y and then test each element in turn?

      Thanks, Simon
    • Andreas Neumann
      Hi Simon, SVGSVGElement.getIntersectionList( rect, referenceElement ) or .getEnclosureList(rect, referenceElement) would theoretically do the job.
      Message 2 of 7 , Aug 2, 2007
      • 0 Attachment
        Hi Simon,

        SVGSVGElement.getIntersectionList( rect, referenceElement ) or
        .getEnclosureList(rect, referenceElement) would theoretically do the
        job.

        Unfortuanetly it is only implemented in Batik ;-( It takes a
        rectangle as input, but you can specify a very small rectangle.

        You can also ping the viewer developers to implement this very useful
        method.

        Here is a very simple example:

        <?xml version="1.0" encoding="UTF-8"?>
        <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://
        www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 1024
        768" onload="testGetIntersectionList()">
        <script type="text/ecmascript">
        <![CDATA[
        function testGetIntersectionList() {
        var svgroot = document.documentElement;
        var myRect = svgroot.createSVGRect();
        myRect.x = 460;
        myRect.y = 460;
        myRect.width = 1;
        myRect.height = 1;
        var intersectList =
        svgroot.getIntersectionList(myRect,null);
        for (var i=0;i<intersectList.length;i++) {
        alert("id of intersected
        element="+intersectList.item(i).getAttributeNS(null,"id"));
        }
        }
        ]]>
        </script>
        <title>Demonstration of the method
        SVGSVGElement.getIntersectionList()</title>
        <rect id="redRectangle" x="400" y="400" width="200" height="200"
        fill="red" />
        <rect id="blueRectangle" x="450" y="450" width="200" height="200"
        fill="blue" />
        <rect id="yellowRectangle" x="50" y="50" width="100" height="100"
        fill="yellow" />
        <rect pointer-events="none" x="458" y="458" width="4" height="4"
        fill="green" />
        </svg>

        --- In svg-developers@yahoogroups.com, "simonshutter" <simon@...>
        wrote:
        >
        > Hi folks,
        >
        > Is there a way that I can use the event model to identify all
        elements
        > that overlap a specific point on a mouse down/move event? Or, do
        I
        > have to use clientX/Y and then test each element in turn?
        >
        > Thanks, Simon
        >
      • ddailey
        ... I started to reply yesterday with a JavaScript approach: find all the graphical elements and determe whether the (x,y) point was inside or outside each.
        Message 3 of 7 , Aug 2, 2007
        • 0 Attachment
          Andreas wrote:

          >SVGSVGElement.getIntersectionList( rect, referenceElement ) or
          >.getEnclosureList(rect, referenceElement) would theoretically do the
          >job.

          >Unfortuanetly it is only implemented in Batik ;-( It takes a
          >rectangle as input, but you can specify a very small rectangle.

          I started to reply yesterday with a JavaScript approach: find all the graphical elements and determe whether the (x,y) point was inside or outside each. but it was so cumbersome I backed out. An alternative I thought of was the following:

          Suppose we could prevent an object from blocking the percolation of the mouse event through to objects that are "behind" it.
          That is, suppose we could allow the mouse event to intercept both the front most object and the objects behind it. I couldn't find any javascript event definition that would redefine event bubble/trickle in this way though (sort of across z-indexes rather than across DOM levels), so I considered an alternative: on mouseover have the front-most object recognize the mouse is over it and remember that, thence becoming invisible or hidden (perhaps with a ghost-like boundary); each subsequent element which is under the mouse behaves accordingly, until the last such element (which knows it is last since nothing underneath receives a mousemove event) a click is then intercepted and passed to a function which keeps track of all the now transparent objects on top.

          I don't think it'll really work though -- too many mouseover, mouseout, mouseclick events to handle and manage just properly. But it did seem like an approach which would take advantage of the fact that objects already know enough about their own geometry to know when the mouse is or isn't over them (without a lot of JavaScript geometry being built).
          David



          [Non-text portions of this message have been removed]
        • simonshutter
          David and Andreas, Thank you both for your responses. I am away right now but will read with interest and reply in more detail when I can. Simon ... elements
          Message 4 of 7 , Aug 2, 2007
          • 0 Attachment
            David and Andreas,


            Thank you both for your responses. I am away right now but will read
            with interest and reply in more detail when I can.

            Simon


            --- In svg-developers@yahoogroups.com, "simonshutter" <simon@...> wrote:
            >
            > Hi folks,
            >
            > Is there a way that I can use the event model to identify all
            elements
            > that overlap a specific point on a mouse down/move event? Or, do I
            > have to use clientX/Y and then test each element in turn?
            >
            > Thanks, Simon
            >
          • simonshutter
            ... the graphical elements and determe whether the (x,y) point was inside or outside each. but it was so cumbersome I backed out. An ... the mouse event
            Message 5 of 7 , Aug 5, 2007
            • 0 Attachment
              --- In svg-developers@yahoogroups.com, "ddailey" <ddailey@...> wrote:

              > I started to reply yesterday with a JavaScript approach: find all
              the graphical elements and determe whether the (x,y) point was inside
              or outside each. but it was so cumbersome I backed out. An
              alternative I thought of was the following:
              >
              > Suppose we could prevent an object from blocking the percolation of
              the mouse event through to objects that are "behind" it.
              > That is, suppose we could allow the mouse event to intercept both
              the front most object and the objects behind it. I couldn't find any
              javascript event definition that would redefine event bubble/trickle
              in this way though (sort of across z-indexes rather than across DOM
              levels), so I considered an alternative: on mouseover have the front-
              most object recognize the mouse is over it and remember that, thence
              becoming invisible or hidden (perhaps with a ghost-like boundary);
              each subsequent element which is under the mouse behaves accordingly,
              until the last such element (which knows it is last since nothing
              underneath receives a mousemove event) a click is then intercepted
              and passed to a function which keeps track of all the now transparent
              objects on top.
              >
              > I don't think it'll really work though -- too many mouseover,
              mouseout, mouseclick events to handle and manage just properly. But
              it did seem like an approach which would take advantage of the fact
              that objects already know enough about their own geometry to know
              when the mouse is or isn't over them (without a lot of JavaScript
              geometry being built).
              > David
              >

              Hi David,

              Before I wrote my original post I considered both approaches you
              describe. With your response I started to develop solutions to both
              in parallel. I had some success with the approach of artificially
              bringing all elements at a point to the front by setting the pointer-
              events attribute of the front-most element to null (and tracking each
              element with a temporary id attribute so I could later remove this
              and the pointer-events attributes). However, I ran into some event
              conflicts and reverted to the brute force approach of identifying
              each element by its coordinates. In my specific case, what makes the
              peformance acceptable and not cumbersome is that my 'canvas' is
              spatially divided into nested chunks so I can quite quickly locate
              elements instead of iterating over hundreds of them.

              Thank you again for your input - it was very helpful. Let's hope the
              developers of SVG implementations add this to their feature lists.

              Simon
            • Andreas Neumann
              Hi Simon, yes, spatial subdivision and then a bounding box test before actually testing the bounding box really helps to speed up things. Kevin Lindsey has a
              Message 6 of 7 , Aug 6, 2007
              • 0 Attachment
                Hi Simon,

                yes, spatial subdivision and then a bounding box test before actually
                testing the bounding box really helps to speed up things. Kevin
                Lindsey has a number of useful geometry libraries on his website
                www.kevlindev.com - amongst them a polygon inside/outside and
                intersection tests. Depending on the element types you use his
                scripts might work fine for you. I am also using his <path/> element
                geometry parser.

                But really, the implementors should implement
                SVGSVGElement.getIntersectionList()

                Andreas

                > Hi David,
                >
                > Before I wrote my original post I considered both approaches you
                > describe. With your response I started to develop solutions to
                both
                > in parallel. I had some success with the approach of artificially
                > bringing all elements at a point to the front by setting the
                pointer-
                > events attribute of the front-most element to null (and tracking
                each
                > element with a temporary id attribute so I could later remove this
                > and the pointer-events attributes). However, I ran into some
                event
                > conflicts and reverted to the brute force approach of identifying
                > each element by its coordinates. In my specific case, what makes
                the
                > peformance acceptable and not cumbersome is that my 'canvas' is
                > spatially divided into nested chunks so I can quite quickly locate
                > elements instead of iterating over hundreds of them.
                >
                > Thank you again for your input - it was very helpful. Let's hope
                the
                > developers of SVG implementations add this to their feature lists.
                >
                > Simon
                >
              • simonshutter
                ... Hi Andreas, Thanks for the pointers! Simon
                Message 7 of 7 , Aug 6, 2007
                • 0 Attachment
                  --- In svg-developers@yahoogroups.com, "Andreas Neumann" <neumann@...>
                  wrote:
                  >
                  > Hi Simon,
                  >
                  > yes, spatial subdivision and then a bounding box test before actually
                  > testing the bounding box really helps to speed up things. Kevin
                  > Lindsey has a number of useful geometry libraries on his website
                  > www.kevlindev.com - amongst them a polygon inside/outside and
                  > intersection tests. Depending on the element types you use his
                  > scripts might work fine for you. I am also using his <path/> element
                  > geometry parser.

                  Hi Andreas,

                  Thanks for the pointers!

                  Simon
                Your message has been successfully submitted and would be delivered to recipients shortly.