Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the SVG checkintersection() function correctly?

I'm having a problem with the SVG checkintersection() function. All I want to do is to check whether a small SVG-rectangle intersects the area of an SVG-path, but I can't figure out what to call the function on (I already tried to call it on the SVG DOM object, among several other things google turned up).

So what I need to know is what to put in for the placeholder ("foo") in this snippet:

var closedPath = document.getElementById(closedPath);
var rectangle = document.getElementById(rectangle);

if (foo.checkIntersection(closedPath, rectangle)) {
    //do stuff
};

with the HTML being something along the lines of

<html>
  <body>
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svgroot">
      <g>
        <path id="closedPath" fill="{$c5}" d="M-250179-46928l-5051 1351l-867-1760l-33-146l-12-99l-82-678l-17-249l86-644l305-1800l158-2882l75-1425l-47-280l-22-131l-137-411l-300-892l1273 620l931-109l1957-734l1860-1096l292-192l884 547l2690 2153l480 963l36 244l-948 1878l-376 591l-60 567l-72 1147l97 847l-222 334l-122 117l-2403 2093l-353 76z"/>
        <rect id="rectangle" fill="white" x="-126828" y="0" width="45000" height="45000"/>
      </g>
    </svg>
  </body>
</html>

Any help would be much appreciated!

Edit: Just wanted to add that I now use a workaround, which consists of converting the SVG path to an array of point coordinates using a parser function I wrote, which is then put into a simple coordinate-test function. Also this may have been a solution Hit-testing SVG shapes?

like image 224
Tim Winfield Avatar asked Sep 21 '13 16:09

Tim Winfield


2 Answers

checkIntersection is a method on the <svg> element so you'd want something like this...

var svg = document.getElementById("svgroot");

var closedPath = document.getElementById(closedPath);
var rectangle = document.getElementById(rectangle);

var rect = svg.createSVGRect();
rect.x = rectangle.animVal.x;
rect.y = rectangle.animVal.y;
rect.height = rectangle.animVal.height;
rect.width = rectangle.animVal.width;

svg.checkIntersection(closedPath, rect) {
    // do stuff
}

Note also how the second argument has to be an SVGRect and not an element.

SVG elements support SMIL animation, you could equally well write rectangle.baseVal.x etc but that wouldn't necessarily reflect the rectangle's current position if you were animating the rectangle. If you're not using SMIL then rectangle.baseVal.x = rectangle.animVal.x

Because a <rect> can have things like rounded corners it doesn't have an SVGRect interface so you have to convert from the interface it does have (SVGRectElement) to the one you need (SVGRect)

like image 138
Robert Longson Avatar answered Nov 10 '22 05:11

Robert Longson


<svg width="390" height="248" viewBox="-266600, -68800, 195000, 124000" version="1.1" xmlns="http://www.w3.org/2000/svg">
  <path id="closedPath" fill="#ff9966" d="M-250179-46928l-5051 1351l-867-1760l-33-146l-12-99l-82-678l-17-249l86-644l305-1800l158-2882l75-1425l-47-280l-22-131l-137-411l-300-892l1273 620l931-109l1957-734l1860-1096l292-192l884 547l2690 2153l480 963l36 244l-948 1878l-376 591l-60 567l-72 1147l97 847l-222 334l-122 117l-2403 2093l-353 76z"/>
  <rect id="rectangle" fill="#66ff66" x="-126828" y="0" width="45000" height="45000"/>
</svg>

<script>
var rectangle = document.getElementById('rectangle');
var closedPath = document.getElementById('closedPath');
var svgRoot = closedPath.farthestViewportElement;
var rect = svgRoot.createSVGRect();
rect.x = rectangle.x.animVal.value;
rect.y = rectangle.y.animVal.value;
rect.height = rectangle.height.animVal.value;
rect.width = rectangle.width.animVal.value;
var hasIntersection = svgRoot.checkIntersection(closedPath, rect);
console.log(hasIntersection);

</script>
like image 28
cuixiping Avatar answered Nov 10 '22 05:11

cuixiping