TypeMismatchError in drawImage() - javascript

I'm using drawImage(). This is my code. imDiv holds an inline svg.
var c =document.getElementById( 'cvs' );
var ctx =c.getContext( '2d' );
var img =document.getElementById( 'imDiv' );
ctx.drawImage( img, 0, 0 ); //TypeMismatchError
I'm getting a TypeMismatchError error. What might be the reason and How can I fix this?

You must convert the SVG to an image first, then draw the image to canvas.
There are some things you need to take into consideration:
The SVG must be well-formed (think XML)
The first element in the SVG must be xmlns attributed
There are variable security restrictions depending on browser when it comes to foreignObject (to embed HTML etc.). It will work in some (Firefox, without external references), others not so much (f.ex. Chrome). This is currently in a state of vacuum, and we can't do much about it on client side
Here is one way of doing this:
// Inline SVG:
var svg = document.querySelector('svg').outerHTML, // make sure SVG tags are included
canvas = document.querySelector('canvas'), // target canvas
ctx = canvas.getContext('2d');
// convert to image (see function below)
// converting to image is an asynchronous process, so we need a callback
svgToImage(svg, function(img) {
// HERE you could insert the image to DOM:
// var myElement = document.getElementById(elementID);
// myElement.appendChild(img);
// set canvas size = image
canvas.width = img.width;
canvas.height = img.height;
// draw SVG-image to canvas
ctx.drawImage(img, 0, 0);
});
// this will convert an inline SVG to a DATA-URI
function svgToImage(svg, callback) {
var url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg),
img = new Image;
// handle image loading, when done invoke callback
img.onload = function() {
callback(this);
};
img.src = url;
}
<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">
<linearGradient id="gradient">
<stop offset="0%" stop-color="#00f" />
<stop offset="100%" stop-color="#f70" />
</linearGradient>
<rect fill="url(#gradient)" x="0" y="0" width="100%" height="100%" />
</svg>
<br>
<canvas></canvas><br>

As of now, it's impossible to draw div or svg elements onto the canvas. The first argument passed to context.drawImage() must be an Image, canvas, or even a video element (using the svg is probably causing the TypeMismatchError).
So you'll have retrieve an actual Image on the document with getElementById() or create one with new Image().

Related

Convert a SVG to PNG react

I've an SVG image that includes two PNG images that makes them one SVG image, now I want to convert this image into PNG/JPG. I've the following code of SVG in react:
import P1 from "../../assets/P1.png";
import P2 from "../../assets/P2.png";
<canvas id="imageCanvas" width="321" height="469"></canvas>
<img id="imageR" ></img>
<svg id="imageCard" name="imageCard" width="321" height="469" xmlns="http://www.w3.org/2000/svg">
<image href={P2} width="321" height="469" />
<image href={P1} x="93" y="151" width="48" height="48" />
</svg>
It showing the proper result in the browser, now I want to convert this svg image to PNG/JPG format, I've tried an solution to convert this image to canvas first and then to PNG:
var svg = document.querySelector('svg');
var img = document.querySelector('#imageR');
var canvas = document.querySelector('#imageCanvas');
// get svg data
var xml = new XMLSerializer().serializeToString(svg);
// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64;charset=utf-8,';
// prepend a "header"
var image64 = b64Start + svg64;
// set it as the source of the img element
img.onload = function () {
// draw the image onto the canvas
canvas.getContext('2d').drawImage(img, 0, 0);
}
ImageBase64 = image64;
img.src = image64;
but it is not work properly, it only works if I don't use image tag inside the SVG, please guide me, thank you.

While Drawing svg on canvas font is not getting applied on the canvas preview [duplicate]

This question already has answers here:
Custom font not displaying in SVG pattern used as background-image
(1 answer)
How to use Google fonts in Canvas when Drawing DOM objects in SVG?
(2 answers)
Closed 10 months ago.
This post was edited and submitted for review 10 months ago and failed to reopen the post:
Original close reason(s) were not resolved
I draw an SVG image onto a canvas element. The SVG image is using a certain font, but when drawing the SVG on canvas the font is not getting applied on canvas preview.
HTML
<h3>Original Svg</h3>
<svg id="svgData" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" text-anchor="middle" viewBox="0 0 1584 648">
<style>
#import url("https://fonts.googleapis.com/css2?family=Ms+Madi&family=PT+Sans&Roboto+Condensed");
.Rrrrr { fill: red; }
</style>
<text font-family="Ms Madi" x="987" y="90" font-size="40" class="personalization personalization_text_1">Font to be changed</text>
<text font-family="Ms Madi" x="987" y="350">
</text>
<g id="MAIN_PIC" xmlns:zcc="http://www.zund.com/ZCC" zcc:date="2022-03-16T17:10:52" zcc:version="3.1.6.28469">
<rect style="fill:none;stroke:#000000;stroke-miterlimit:10;" width="1584" height="648"></rect>
</g>
</svg>
<hr>
<h3>Canvas preview</h3>
<canvas id="canvas1" ></canvas>
JS
drawPrevCanvas();
function drawPrevCanvas() {
var svg = document.getElementById('svgData');
var xml = new XMLSerializer().serializeToString(svg);
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';
var image64 = b64Start + svg64;
var hcanvas_prev_3 = document.getElementById('canvas1');
var ctx3 = hcanvas_prev_3.getContext("2d");
var svgImgPrev = new Image();
svgImgPrev.crossOrigin = "Anonymous";
hcanvas_prev_3.width = 400;
hcanvas_prev_3.height = 164;
svgImgPrev.onload = function() {
ctx3.drawImage(svgImgPrev, 0, 0, 400, 164);
}
svgImgPrev.src = image64;
}
Image
JSFiddle
I'm currently working on this and trying to get an answer. Usually with it you want to use this in your JavaScript:
hcanvas_prev_3.font = 'font name';
This usually should replace the font within the preview. However, it seems to be not loading the font.
However I decided to see if the font was the issue here, and I changed it to Raleway provided by Google Fonts. It seems to load on the original svg.
Here is a photo to show:
Weirdly when I assign it in the JavaScript like so:
hcanvas_prev_3.font = "Raleway";
Then log the font like so:
console.log(hcanvas_prev_3.font)
It prints out that the font is active see screenshot:
I've been looking around to see how to fix it, and I've tried a lot of different options:
That this can also happen if you reset the size of the canvas. At least, I saw this in Chrome 23 today.
context.font = 'bold 20px arial';
canvas.width = 100;
canvas.height = 100;
console.log(context.font); // gives '10px sans-serif'
Referenced Here!
So, I've not fixed it just yet but I am working on it!

Javascript memory leaks when using canvas and blobs

I'm writing an SVG editor. I have placed a kind of 'Magic Eye' on the page where the user can see the entire SVG draw and the zoomed area around the mouse cursor. Of course the problem is Memory usage and fast rendering. For this reason, step of modification or zooming the software create a reduced Image of the svg draw and it will use it for the Magic Eye rendering. The result is very nice but.... I am facing a problem, I discovered that the garbage collector doesn't free the images created and also the blobs. So after a few time I have the memory filled with Images. This is the routine I wrote for this job:
var RenderPosition = function(obj) {
try{
var clearCanvas = function(context, canvas) {
context.clearRect(0, 0, canvas.width, canvas.height);
var w = canvas.width;
canvas.width = 1;
canvas.width = w;
};
var PrepareBlob = function(blob){
glb._ThumbUrl = glb._DOMURL.createObjectURL(blob);
glb._MagicImg = new Image();
glb._MagicImg.src = glb._ThumbUrl;
};
var PosizViewFilling = function(e){
obj.pDC.drawImage(this,
obj.srt.x,
obj.srt.y,
obj.dms.width,
obj.dms.height);
obj.canvas.toBlob(PrepareBlob);
this.removeEventListener('load',PosizViewFilling,true);
this.src='';
delete this;
};
clearCanvas(obj.pDC,obj.canvas);
if (glb._MagicImg!==null) delete(glb._MagicImg);
glb._DOMURL.revokeObjectURL(glb._ThumbUrl);
var Big_img = new Image();
Big_img.addEventListener('load',PosizViewFilling, true);
Big_img.src = 'data:image/svg+xml;base64,'+btoa(obj.dw); //data from a svg draw
}
catch(err){
console.log(err.message);
}
};
As you can see the routine creates in first the Big_image with the SVG draw. After it creates a resized image in memory. I tried a different approach but also the only Big_image and the obj.dw is enough to live memory leaks. What is wrong? It may be I'm not able to see my bug. I hope I can get a suggestion from different perspectives.
You may also want to consider letting the SVG scale itself.
#main {
width: 400px;
height: 400px;
}
svg {
width: 100%;
height: 100%;
}
#thumb, #zoom {
width: 40px;
height: 40px;
border: solid 1px black;
overflow: hidden;
}
#zoom svg {
width: 400px;
height: 400px;
position: relative;
top: -140px;
left: -210px
}
<div id="main">
<svg id="mainsvg" viewBox="0 0 1000 1000">
<rect x="100" y="100" width="500" height="500" fill="green"
transform="rotate(10,350,350)"/>
<rect x="400" y="400" width="500" height="500" fill="orange"
transform="rotate(-10,650,650)"/>
</svg>
</div>
<div id="thumb">
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#mainsvg" />
</svg>
</div>
<div id="zoom">
<svg xmlns:xlink="http://www.w3.org/1999/xlink">
<use xlink:href="#mainsvg" />
</svg>
</div>
You need to have an explicit
delete glb._MagicImg;
When you no longer require this object.
Also see:
Deleting Objects in JavaScript
For further info.
To get the best out of javascript it is always to good idea to reuse resources if you can.
Your code is exceedingly wasteful.
As I see it you want to create a smaller version of a large (complex?) SVG image. It looks like you dump any previous copies when you create the new one.
A possible Solution for you that will not chew memory.
You need two images. One for the SVG and one for the magicEye (thumb). The thumb image can be a canvas, create it once and draw the SVG to it when needed. The other image for the SVG also only needs to be created once, only add the load listener once set its URL = "" when you don't need it any more. Keep it for next time you need it.
The following code will load one of 3 SVG images and convert it to an image (canvas) then do it again in 100ms.
It will not chew more resources than what is required for the two images (ignoring pending GC dumps).
var thumbImage = {
width:100,
height:100,
}
var SVG_images = [
'<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256" id="testSVG" ><defs></defs><path d="M169.5,9Q184.7,10.5,186,23Q187.9,7.2,250,16.5Q252.5,29.3,243.5,36Q238.9,38.5,228,35Q227.1,86.5,231.5,107Q198.9,110.6,198,104.5Q211.3,64.1,209,34.5Q189.3,31.3,187,25Q189.3,39.3,176.5,38Q179.3,24.7,171.5,21Q154.2,20.1,156,39.5Q156.6,50.9,187,63.5Q194,79.1,191,92.5Q183.8,107.2,167.5,110Q147.1,112.3,142,101.5Q137.6,87,147.5,82Q159.4,95.9,160.5,95Q169.1,96,173,86.5Q178.2,73.6,140,48.5Q138.7,29.4,144,20.5Q155.2,7.7,169.5,9Z M37.5,13Q54.2,14.8,75,15.5Q76.1,30.5,49,30Q62.5,97.7,58.5,102Q48.5,102.7,24,98.5Q40.5,60.1,30,33Q6.7,36.9,4,27.5Q.8,8.8,37.5,13Z M91.5,15Q136.5,14.6,136,19.5Q138,38.5,104,31L104,49Q126.7,40.1,127,58.5Q97.6,72.3,101,83Q118.5,80.7,128.5,83Q139.4,95,126.5,104Q81.5,107.5,79,97.5Q84.9,14,91.5,15Z M121.5,130Q141,128.2,157,153.5Q178.3,206,162.5,232Q155.3,234.7,150,227.5Q147.7,219.5,149,192Q124.5,197.1,106.5,191Q102.8,198.8,96,225.5Q86.5,237.5,78,224.5Q90.4,147.8,121.5,130Z M124,149.5Q120.7,154.4,112,172.5Q120,176.9,143,174Q140.8,156.3,124,149.5Z" fill="#000000" fill-rule="evenodd" ></path></svg>',
'<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256" id="testSVG" ><defs></defs><path d="M162.5,9Q171.4,8.5,179.5,12Q186.2,17.8,186,23Q186.8,14,191.5,13Q192,13.6,250,16.5Q252.5,29.3,243.5,36Q238.9,38.5,228,35Q227.1,86.5,231.5,107Q198.9,110.6,198,104.5Q211.3,64.1,209,34.5Q189.3,31.3,187,25Q189.3,39.3,176.5,38Q179.3,24.7,171.5,21Q162.8,20.1,159,25.5Q155.2,30.4,156,39.5Q156.6,50.9,187,63.5Q194,79.1,191,92.5Q185.4,104,172.5,109Q151.2,113.2,144,104.5Q135.6,89.6,147.5,82Q159.4,95.9,160.5,95Q169.1,96,173,86.5Q173.8,80.1,169,70.5Q157.6,60.5,146.5,63Q141.6,57.7,140,48.5Q138.7,29.4,144,20.5Q153.2,11.1,162.5,9Z M37.5,13Q54.2,14.8,75,15.5Q74.6,21.7,71.5,25Q58.8,29.6,49,30Q62.5,97.7,58.5,102Q48.5,102.7,24,98.5Q23,97.5,35,60.5Q36.2,59.8,30,33Q6.7,36.9,4,27.5Q2.9,17.9,9.5,15Q37.6,13.9,37.5,13Z M91.5,15Q136.5,14.6,136,19.5Q136.6,28.8,129.5,32Q129.5,32.2,104,31L104,49Q113.1,46.7,120.5,47Q127.7,50.6,127,58.5Q125,67.9,103.5,69Q101.4,70.3,101,83Q118.5,80.7,128.5,83Q139.4,95,126.5,104Q81.5,107.5,79,97.5Q84.9,14,91.5,15Z M78.5,117Q97.7,121.6,159.5,129Q164.2,130.1,174,144.5Q176.2,144.4,176,212.5Q170,236.9,163.5,244Q113.5,247.9,65,241.5Q58.3,227.7,76,214.5Q72.8,199.7,72,144Q57,146.3,59,131.5Q58.8,128.3,78.5,117Z M106,146.5Q95.5,150.6,98,170Q132.5,179.7,150,168.5L149.5,153Q128.8,145.8,106,146.5Z M98,193.5Q102.4,222.6,106.5,225Q122.3,231.2,133.5,233Q148.3,229.2,153,222.5Q157.6,207.3,152.5,196Q130.7,198.5,98,193.5Z" fill="#000000" fill-rule="evenodd" ></path></svg>',
'<?xml version="1.0"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256" id="testSVG" ><defs></defs><path d="M162.5,9Q183.7,7.2,186,23Q187.9,7.2,250,16.5Q252.5,29.3,243.5,36Q238.9,38.5,228,35Q227.1,86.5,231.5,107Q198.9,110.6,198,104.5Q211.3,64.1,209,34.5Q189.3,31.3,187,25Q189.3,39.3,176.5,38Q179.3,24.7,171.5,21Q154.2,20.1,156,39.5Q156.6,50.9,187,63.5Q194,79.1,191,92.5Q185.4,104,172.5,109Q151.2,113.2,144,104.5Q135.6,89.6,147.5,82Q159.4,95.9,160.5,95Q169.1,96,173,86.5Q178.2,73.6,140,48.5Q135.3,15.1,162.5,9Z M37.5,13Q54.2,14.8,75,15.5Q76.1,30.5,49,30Q62.5,97.7,58.5,102Q48.5,102.7,24,98.5Q40.5,60.1,30,33Q6.7,36.9,4,27.5Q.8,8.8,37.5,13Z M91.5,15Q136.5,14.6,136,19.5Q138,38.5,104,31L104,49Q126.7,40.1,127,58.5Q97.6,72.3,101,83Q118.5,80.7,128.5,83Q139.4,95,126.5,104Q81.5,107.5,79,97.5Q84.9,14,91.5,15Z M121.5,129Q151.9,129.3,159.5,135Q167.3,139.1,165,163.5Q164,172.2,143.5,177Q131.8,176.1,134.5,151Q124.6,153.1,107.5,155Q89.6,186.1,98,210.5Q113.7,214.2,136.5,210Q141,195.7,146.5,194Q168.3,192.4,168,210.5Q165.1,227.3,147.5,237Q125.6,242.4,103.5,242Q85.1,237.3,73,212.5Q67,196.5,70,173.5Q75,154.4,88.5,138Q98.1,130.5,121.5,129Z" fill="#000000" fill-rule="evenodd" ></path></svg>',
]
var createThumb = function(svgData) {
var loadImg = function(){
if(thumbImage.image === undefined){ // check if the image exists?
thumbImage.image = document.createElement("canvas"); // create it if not
}
// resize it. Could test if this is neede but keeping it simple.
thumbImage.width = thumbImage.width;
thumbImage.height = thumbImage.height;
// is there a 2d context
if(thumbImage.image.ctx === undefined){
// no context so create it.
thumbImage.image.ctx = thumbImage.image.getContext("2d");
}
// the resize may be the same and thus no free clear so clear
thumbImage.image.ctx.clearRect(0,0,thumbImage.width,thumbImage.height);
// draw the SVG image onto the magicImg.
thumbImage.image.ctx.drawImage(this, 0,0,thumbImage.width,thumbImage.height);
this.src = "";
};
// does the thumb image exist.
if( thumbImage.tempImage === undefined){
thumbImage.tempImage = new Image(); // create it
// add listener that can be reused for all other loads.
thumbImage.tempImage.addEventListener('load',loadImg);
}
thumbImage.tempImage.src = 'data:image/svg+xml;base64,'+btoa(svgData);
};
var currentSvg = 0;
function justDoIt(){
createThumb(SVG_images[currentSvg % SVG_images.length]);
currentSvg += 1;
setTimeout(justDoIt,100);
}
justDoIt();
It only creates the canvas and image once when first needed, then reuses them while they exist. When the first original SVG is rasterized to the canvas there is no extra memory needed as the already allocated canvas is has its memory (Unless the thumb size changes).
I have run it for an hour now (10 images a second), and gave it the full suit of Dev tool checks. Everything it allocates end up back in the GC so no memory leaks.
You should be able to adapt it to your needs. Remember reuse rather than delete and reasign. Also the Canvas is an image so there is no need to convert anything to a dataURL unless you need to transport it outside the Javascript immediate context.

SVG element inserted into DOM is ignored (its type is changed)

I am using the VivaGraph.js library to render a graph in SVG. I am trying to display an image cropped to a circle, for which I am using a clipPath element - as recommended in this post.
However, when I create a new SVG element of type that has a capital letter in it, e.g. clipPath in my case, the element that is inserted into the DOM is lowercase, i.e. clippath, even though the string I pass in to the constructor is camelCase. Since SVG is case sensitive, this element is ignored. Everything else seems to be okay.
I also tried to change the order in which I append the child elements, in hopes of changing the 'z-index', but it didn't have an impact on this.
I am using the following code inside of the function that creates the visual representation of the node in the graph (the 'addNode' callback) to create the node:
var clipPhotoId = 'clipPhoto';
var clipPath = Viva.Graph.svg('clipPath').attr('id', clipPhotoId);
var ui = Viva.Graph.svg('g');
var photo = Viva.Graph.svg('image').attr('width', 20).attr('height', 20).link(url).attr('clip-path', 'url(#' + clipPhotoId + ')');
var photoShape = Viva.Graph.svg('circle').attr('r', 10).attr('cx', 10).attr('cy', 10);
clipPath.append(photoShape);
ui.append(clipPath);
ui.append(photo);
return ui;
Thank you!
There is a bit of tweaking needed on top of the post you provided.
General idea to solve your issue is this one:
We create a VivaGraph svg graphics (which will create an svg element in the dom)
Into this svg graphic we create only once a clip path with relative coordinates
When we create a node we refer to the clip path
Code is:
var graph = Viva.Graph.graph();
graph.addNode('a', { img : 'a.jpg' });
graph.addNode('b', { img : 'b.jpg' });
graph.addLink('a', 'b');
var graphics = Viva.Graph.View.svgGraphics();
// Create the clipPath node
var clipPath = Viva.Graph.svg('clipPath').attr('id', 'clipCircle').attr('clipPathUnits', 'objectBoundingBox');
var circle = Viva.Graph.svg('circle').attr('r', .5).attr('cx', .5).attr('cy', .5);
clipPath.appendChild(circle);
// Add the clipPath to the svg root
graphics.getSvgRoot().appendChild(clipPath);
graphics.node(function(node) {
return Viva.Graph.svg('image')
.attr('width', 30)
.attr('height', 30)
// I refer to the same clip path for each node
.attr('clip-path', 'url(#clipCircle)')
.link(node.data.img);
})
.placeNode(function(nodeUI, pos){
nodeUI.attr('x', pos.x - 15).attr('y', pos.y - 15);
});
var renderer = Viva.Graph.View.renderer(graph, { graphics : graphics });
renderer.run();
The result in the dom will be like this:
<svg>
<g buffered-rendering="dynamic" transform="matrix(1, 0, 0,1,720,230.5)">
<line stroke="#999" x1="-77.49251279562495" y1="-44.795726056131116" x2="6.447213894549255" y2="-56.29464520347651"></line>
<image width="30" height="30" clip-path="url(#clipCircle)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="a.jpg" x="-92.49251279562495" y="-59.795726056131116"></image>
<image width="30" height="30" clip-path="url(#clipCircle)" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="b.jpg" x="-8.552786105450746" y="-71.2946452034765"></image>
</g>
<clipPath id="clipCircle" clipPathUnits="objectBoundingBox">
<circle r="0.5" cx="0.5" cy="0.5"></circle>
</clipPath>
</svg>
Notice the clipPathUnits="objectBoundingBox", since it's the main trick for this solution.

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

Categories

Resources