I have a simple drawing I created using Inkscape, this is the Inkscape file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="847.18634"
height="635.83612"
viewBox="0 0 224.15139 168.23164"
version="1.1"
id="svg5"
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
sodipodi:docname="drawing.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<script
xlink:href="script.js"
id="script2" />
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="false"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="px"
showgrid="false"
showborder="true"
shape-rendering="auto"
inkscape:zoom="0.69947917"
inkscape:cx="711.24348"
inkscape:cy="274.48995"
inkscape:window-width="1920"
inkscape:window-height="1054"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-66.199001,-70.460732)">
<circle
style="fill:#ff0000;stroke-width:1;stroke-linejoin:round;paint-order:markers fill stroke"
id="circle"
cx="97.842422"
cy="117.80233"
r="31.643421" />
<rect
style="fill:#ff0000;stroke-width:1;stroke-linejoin:round;paint-order:markers fill stroke"
id="square"
width="58.322342"
height="58.322342"
x="197.28148"
y="70.460732" />
<path
sodipodi:type="star"
style="fill:#ff0000;stroke-width:1;stroke-linejoin:round;paint-order:markers fill stroke"
id="star"
inkscape:flatsided="false"
sodipodi:sides="7"
sodipodi:cx="246.21613"
sodipodi:cy="196.8262"
sodipodi:r1="44.441872"
sodipodi:r2="23.465311"
sodipodi:arg1="-1.6774691"
sodipodi:arg2="-1.2286702"
inkscape:rounded="-3.469447e-18"
inkscape:randomized="0"
d="m 241.48437,152.63694 12.60415,22.08392 23.72596,-9.14564 -9.40734,23.62341 21.94324,12.84749 -24.33491,7.374 3.63682,25.1662 -20.9378,-14.42819 -17.4082,18.53425 -1.7741,-25.36566 -25.34449,-2.05437 18.72554,-17.20226 -14.19587,-21.09601 25.12446,3.91478 z"
inkscape:transform-center-x="2.9669026"
inkscape:transform-center-y="-4.1349791" />
</g>
</svg>
I want to do things with those elements using a JavaScript script, similarly as you would do in an HTML file. I created the following script:
console.log("I am alive!");
var circle = document.getElementById('circle');
circle.style.fill = "#0000ff"; // Make it blue.
console.log(circle);
and embedded it in the SVG file using Inkscape→File→Document properties→Scripting→External scripts→my_script.js
. It prints I am alive!
but then circle
is null
. Inspired by this link I also tried
console.log("I am alive!");
console.log(svgDocument.getElementById("circle"));
which prints Uncaught ReferenceError: svgDocument is not defined
. Following this link I tried
console.log("I am alive!");
var svgObject = document.getElementById('svg-object').contentDocument;
var element = svgObject.getElementById('circle');
console.log(element);
and
console.log("I am alive!");
var svgObject = document.getElementById('svg5').contentDocument;
var element = svgObject.getElementById('circle');
console.log(element);
and
console.log("I am alive!");
var svgObject = document.getElementById('svg5');
var element = svgObject.getElementById('circle');
console.log(element);
but they all fail.
What is the way of writing this JavaScript such that when I open the SVG with a web browser this works?
Make sure that you wait for the DOM to load. I inserted the following script as an embedded script in Inkscape:
document.addEventListener('DOMContentLoaded', e => {
document.getElementById('path1').style.fill = 'blue';
});
And got the following result, saving the document as a plain SVG document:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="200"
height="200"
viewBox="0 0 200 200"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<script
id="script1">document.addEventListener('DOMContentLoaded', e => {
document.getElementById('path1').style.fill = 'blue';
});</script>
<defs
id="defs1" />
<g
id="layer1">
<path
style="fill:#ff0000;stroke-width:14.844;stroke-linecap:round"
id="path1"
d="M 90.234723,183.97224 A 82.22879,83.852211 0 0 1 11.095695,100.59093 82.22879,83.852211 0 0 1 89.427955,16.421145 82.22879,83.852211 0 0 1 175.22041,92.6532 82.22879,83.852211 0 0 1 104.17524,183.29802" />
</g>
</svg>
For some reason Inkscape is not escaping the JavaScript code in a CDATA element, but only escaping characters like the >
that becomes >
. In my book a proper script element containing JavaScript in a SVG document would look like this:
<script>
//<![CDATA[
document.addEventListener('DOMContentLoaded', e => {
document.getElementById('path1').style.fill = 'blue';
});
//]]>
</script>