Inkscape.org
Beyond the Basics Get element by ID and change its color in SVG Inkscape
  1. #1
    inx_cape inx_cape @inx_cape
     

    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>
    

    and looks like this: enter image description here

    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?

  2. #2
    Tyler Durden Tyler Durden @TylerDurden

    There is an extension that may be useful: Extensions>Web>Javascript>Set Attributes.

  3. #3
    inklinea inklinea @inklinea⛰️

    I am very rusty with javascript ( I wasn't very good in the first place )

    Javascript is event driven.

    If the script is not linked to an event, -- or is being triggered before the svg has fully loaded it will not work.

    I've added an onload to the <svg> tag of the attached svg. ( You could do this by attaching events handlers instead )

    Also I have used CDATA, because svg rejects < characters in the code and crashes.

    I can't remember the scope of javascript in an svg ( whether or no document.GetElementById applies to the parent html or not )

    ------------------------------------------

    If you hit F5 to reload the document, each time the circle fills with randomly change.

     

     

    Studiofibonacci Cartoon Peacock Random Colours
  4. #4
    inklinea inklinea @inklinea⛰️

    Ahh seems like the Inkscape website will not allow me to attach an svg with a script in it. 

    https://www.raincloud.co.uk/test/StudioFibonacci-Cartoon-peacock_random_colours.svg

       <script>
           
       <![CDATA[
       
       function randomColorCircles() {
       
       circleCollection = document.getElementsByTagName("circle");
       
       console.log(document)
       
       
       for (var i=0; i < circleCollection.length; i++) {
       
       randomRGB = `rgb(${(Math.floor(Math.random() * 256))}, ${(Math.floor(Math.random() * 256))}, ${(Math.floor(Math.random() * 256))})`;
             
       circleCollection[i].style.fill = randomRGB;
        
       
       }
       
       }
       
       ]]>
       
       </script>

Inkscape Inkscape.org Inkscape Forum Beyond the Basics Get element by ID and change its color in SVG Inkscape