I have this code to render SVG image with 2 layers:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 175.94 315.65" style="enable-background:new 0 0 175.94 315.65;" xml:space="preserve">
<g id="Layer_1">
<path class="st0" d="M18.87,132.57c5.5-2.4,10.1-6.46,15.56-8.94c5.93,1.66,11.11,5.28,17.02,7.01c2.66,0.73,5.6-1.75,5.27-4.51
c-0.89-6.06-2.93-11.91-3.89-17.97c3.87-4.32,8.15-8.29,11.65-12.92c2.13-2.28,0.96-6.65-2.25-7.12
c-5.91-1.21-12.12-0.48-17.95-1.96c-3.5-4.67-5.59-10.22-8.91-15c-1.61-2.73-6.41-2.77-7.73,0.25c-2.78,5.11-4.1,10.9-7.05,15.92
c-5.59,2.4-11.92,2.4-17.68,4.34c-2.4,0.74-3.66,3.97-2.44,6.15c3.86,5.26,10.4,8.04,14,13.44c-0.05,6.01-1.73,11.89-1.57,17.9
C13.08,132.03,16.35,133.61,18.87,132.57z M7.97,96.55c5.1-1.26,10.39-1.74,15.38-3.44c1.78-0.5,2.43-2.4,3.2-3.88
c1.77-4.04,3.31-8.18,5.21-12.16c2.46,3.85,4.56,7.91,6.92,11.83c0.92,1.41,1.95,3.14,3.85,3.24c5.06,0.73,10.2,0.83,15.28,1.47
c-3.21,4.07-7,7.64-10.26,11.67c-1.36,1.43-0.77,3.5-0.47,5.21c0.97,4.39,2.16,8.73,3.09,13.14c-4.08-1.6-8.02-3.51-12-5.3
c-1.86-0.84-4.12-1.53-6.03-0.46c-4.41,2.33-8.47,5.26-12.92,7.5c0.34-5.1,1.15-10.16,1.45-15.26c0.29-2-1.44-3.33-2.67-4.59
C14.69,102.49,11.04,99.84,7.97,96.55z"/>
<path class="st0" d="M91.31,36.4c-0.28,3.26-0.71,6.5-0.99,9.76c3.01-1.2,5.73-3.46,8.98-3.83c2.91,0.96,5.53,2.62,8.37,3.79
c-0.35-3.28-0.86-6.53-1.32-9.79c2.23-2.23,4.46-4.48,6.41-6.96c-2.97-0.59-6.01-0.83-8.92-1.64c-2.22-2.39-3.3-5.57-4.94-8.35
c-1.91,2.64-3.34,5.56-4.7,8.5c-3.1,0.53-6.2,0.97-9.28,1.58C86.77,32.01,89,34.26,91.31,36.4z"/>
</g>
<g id="Layer_2">
<path class="st0" d="M131.76,6.63c-4.41-2.49-8.64-6.53-13.79-6.63c-3.51-0.07-3.26,4.66-1.31,6.69
c11.46,16.14,17.89,35.91,17.57,55.74c-0.11,31.34-16.95,62.09-43.45,78.87c-16.18,10.43-35.6,15.92-54.87,14.88
c-5.34,0.24-11.48-3.97-15.92-0.97c-1.16,0.78-1.2,3.01,0.04,4.1c2.29,2.42,5.11,4.24,7.8,6.19c-0.06,37.67-0.08,75.34,0.01,113
c0.06,4.19-2.57,7.7-4.24,11.36c-4.12,0.73-8.31,1.1-12.38,2.07c-0.09,0.36-0.29,1.08-0.38,1.44c2.63,3.25,6.28,5.59,8.65,9.05
c-0.23,4.44-1.44,8.77-1.54,13.23c4.23-1.58,8.16-3.83,12.08-6.04c4.13,2.01,8.13,4.35,12.5,5.83c-0.34-4.45-1.19-8.83-2.11-13.18
c3.1-3.45,6.57-6.55,9.5-10.15c-4.38-1.22-8.9-1.75-13.4-2.27c-1.79-3.61-4.57-7.09-4.3-11.34c0.05-36.71-0.03-73.43,0.04-110.14
c13.71,7.75,29.09,12.61,44.88,13.24c0.09,5.62,0.04,11.23,0.11,16.85c-0.08,2.38,0.32,5.05-1.26,7.07
c-3.67,5.49-5.56,11.88-8.18,17.88c-5.89,1.57-11.95,2.38-17.8,4.05c-3.11,0.8-3.82,5.35-1.48,7.39c4,4.19,9.07,7.27,12.89,11.66
c0.36,6.3-1.72,12.49-1.31,18.79c0.23,2.84,4.14,4.25,6.43,2.86c5.2-2.8,10.04-6.25,15.27-9.04c5.47,2.35,10.67,5.38,16.36,7.21
c2.26,0.79,5.06-0.8,5.49-3.14c0.25-6.63-3.46-12.78-3.39-19.34c3.36-4.62,7.94-8.22,11.32-12.83c1.92-2.2,1-6.45-2.06-7.04
c-6.02-1.29-12.24-0.91-18.32-1.84c-3.07-5.8-6.85-11.23-9.61-17.17c-0.54-7.72,0.07-15.49-0.29-23.23
c26.26-0.27,52.18-11.62,69.93-31.01c13.2-14.35,21.7-32.94,23.98-52.3C179.8,62.89,162.27,25.51,131.76,6.63z M86.98,226.42
c0.83,1.39,2.55,1.47,3.99,1.68c4.65,0.49,9.33,0.76,13.99,1.32c-2.79,3.22-5.67,6.36-8.55,9.49c-1.29,1.53-3.06,3.25-2.55,5.47
c0.78,5.06,2.33,9.96,3.26,15c-4.81-1.94-9.41-4.4-14.29-6.15c-1.76-0.9-3.45,0.31-4.96,1.1c-3.96,2.3-7.78,4.81-11.75,7.08
c0.35-5.28,1.44-10.5,1.59-15.79c0.2-1.9-1.47-3.11-2.64-4.3c-3.3-2.95-6.84-5.63-9.83-8.9c5.02-1.43,10.28-1.87,15.24-3.52
c1.74-0.51,2.35-2.39,3.09-3.85c1.74-4.07,3.37-8.2,5.28-12.2C81.77,217.25,83.92,222.12,86.98,226.42z"/>
</g>
</svg>
Now I have a span element with background color and class "check" assigned:
<span class="check" style="background-color: #4d1b18">Brown</span>
and the JS code:
<script type="text/javascript">
var svg = document.querySelector('span.check');
var layer1 = document.querySelector('#Layer_1');
var matches = layer1.querySelector('path');
matches.style.fill = svg.style.backgroundColor;
</script>
You can check the fiddle here.
As you can see, the fill is applied only to the first path of #layer_1 the second path in same ID as well (there may be even more).
How to inline the style to all path inside the Layer_1 ID ?
Try this:
var svg = document.querySelector('span.check');
var layer1 = document.querySelector('#Layer_1');
var matches = layer1.querySelectorAll('path');
matches.forEach(fillColor);
function fillColor(item, index) {
matches[index].style.fill = svg.style.backgroundColor;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 175.94 315.65" style="enable-background:new 0 0 175.94 315.65;" xml:space="preserve">
<g id="Layer_1">
<path class="st0" d="M18.87,132.57c5.5-2.4,10.1-6.46,15.56-8.94c5.93,1.66,11.11,5.28,17.02,7.01c2.66,0.73,5.6-1.75,5.27-4.51
c-0.89-6.06-2.93-11.91-3.89-17.97c3.87-4.32,8.15-8.29,11.65-12.92c2.13-2.28,0.96-6.65-2.25-7.12
c-5.91-1.21-12.12-0.48-17.95-1.96c-3.5-4.67-5.59-10.22-8.91-15c-1.61-2.73-6.41-2.77-7.73,0.25c-2.78,5.11-4.1,10.9-7.05,15.92
c-5.59,2.4-11.92,2.4-17.68,4.34c-2.4,0.74-3.66,3.97-2.44,6.15c3.86,5.26,10.4,8.04,14,13.44c-0.05,6.01-1.73,11.89-1.57,17.9
C13.08,132.03,16.35,133.61,18.87,132.57z M7.97,96.55c5.1-1.26,10.39-1.74,15.38-3.44c1.78-0.5,2.43-2.4,3.2-3.88
c1.77-4.04,3.31-8.18,5.21-12.16c2.46,3.85,4.56,7.91,6.92,11.83c0.92,1.41,1.95,3.14,3.85,3.24c5.06,0.73,10.2,0.83,15.28,1.47
c-3.21,4.07-7,7.64-10.26,11.67c-1.36,1.43-0.77,3.5-0.47,5.21c0.97,4.39,2.16,8.73,3.09,13.14c-4.08-1.6-8.02-3.51-12-5.3
c-1.86-0.84-4.12-1.53-6.03-0.46c-4.41,2.33-8.47,5.26-12.92,7.5c0.34-5.1,1.15-10.16,1.45-15.26c0.29-2-1.44-3.33-2.67-4.59
C14.69,102.49,11.04,99.84,7.97,96.55z"/>
<path class="st0" d="M91.31,36.4c-0.28,3.26-0.71,6.5-0.99,9.76c3.01-1.2,5.73-3.46,8.98-3.83c2.91,0.96,5.53,2.62,8.37,3.79
c-0.35-3.28-0.86-6.53-1.32-9.79c2.23-2.23,4.46-4.48,6.41-6.96c-2.97-0.59-6.01-0.83-8.92-1.64c-2.22-2.39-3.3-5.57-4.94-8.35
c-1.91,2.64-3.34,5.56-4.7,8.5c-3.1,0.53-6.2,0.97-9.28,1.58C86.77,32.01,89,34.26,91.31,36.4z"/>
</g>
<g id="Layer_2">
<path class="st0" d="M131.76,6.63c-4.41-2.49-8.64-6.53-13.79-6.63c-3.51-0.07-3.26,4.66-1.31,6.69
c11.46,16.14,17.89,35.91,17.57,55.74c-0.11,31.34-16.95,62.09-43.45,78.87c-16.18,10.43-35.6,15.92-54.87,14.88
c-5.34,0.24-11.48-3.97-15.92-0.97c-1.16,0.78-1.2,3.01,0.04,4.1c2.29,2.42,5.11,4.24,7.8,6.19c-0.06,37.67-0.08,75.34,0.01,113
c0.06,4.19-2.57,7.7-4.24,11.36c-4.12,0.73-8.31,1.1-12.38,2.07c-0.09,0.36-0.29,1.08-0.38,1.44c2.63,3.25,6.28,5.59,8.65,9.05
c-0.23,4.44-1.44,8.77-1.54,13.23c4.23-1.58,8.16-3.83,12.08-6.04c4.13,2.01,8.13,4.35,12.5,5.83c-0.34-4.45-1.19-8.83-2.11-13.18
c3.1-3.45,6.57-6.55,9.5-10.15c-4.38-1.22-8.9-1.75-13.4-2.27c-1.79-3.61-4.57-7.09-4.3-11.34c0.05-36.71-0.03-73.43,0.04-110.14
c13.71,7.75,29.09,12.61,44.88,13.24c0.09,5.62,0.04,11.23,0.11,16.85c-0.08,2.38,0.32,5.05-1.26,7.07
c-3.67,5.49-5.56,11.88-8.18,17.88c-5.89,1.57-11.95,2.38-17.8,4.05c-3.11,0.8-3.82,5.35-1.48,7.39c4,4.19,9.07,7.27,12.89,11.66
c0.36,6.3-1.72,12.49-1.31,18.79c0.23,2.84,4.14,4.25,6.43,2.86c5.2-2.8,10.04-6.25,15.27-9.04c5.47,2.35,10.67,5.38,16.36,7.21
c2.26,0.79,5.06-0.8,5.49-3.14c0.25-6.63-3.46-12.78-3.39-19.34c3.36-4.62,7.94-8.22,11.32-12.83c1.92-2.2,1-6.45-2.06-7.04
c-6.02-1.29-12.24-0.91-18.32-1.84c-3.07-5.8-6.85-11.23-9.61-17.17c-0.54-7.72,0.07-15.49-0.29-23.23
c26.26-0.27,52.18-11.62,69.93-31.01c13.2-14.35,21.7-32.94,23.98-52.3C179.8,62.89,162.27,25.51,131.76,6.63z M86.98,226.42
c0.83,1.39,2.55,1.47,3.99,1.68c4.65,0.49,9.33,0.76,13.99,1.32c-2.79,3.22-5.67,6.36-8.55,9.49c-1.29,1.53-3.06,3.25-2.55,5.47
c0.78,5.06,2.33,9.96,3.26,15c-4.81-1.94-9.41-4.4-14.29-6.15c-1.76-0.9-3.45,0.31-4.96,1.1c-3.96,2.3-7.78,4.81-11.75,7.08
c0.35-5.28,1.44-10.5,1.59-15.79c0.2-1.9-1.47-3.11-2.64-4.3c-3.3-2.95-6.84-5.63-9.83-8.9c5.02-1.43,10.28-1.87,15.24-3.52
c1.74-0.51,2.35-2.39,3.09-3.85c1.74-4.07,3.37-8.2,5.28-12.2C81.77,217.25,83.92,222.12,86.98,226.42z"/>
</g>
</svg>
<span class="check" style="background-color: #0f0">Green</span>
Is there a way to fill SVG images with Javascript code, for example if you had a button with an id of myButton and you had a SVG inside it and used the document.getElementById("myButton").style to fill in the SVG, how could you do it? This is the code I tried:
document.getElementById("myButton").style.svg.fill="yellow";
<button id="myButton" type="submit">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<path d="M281.1,0c-127.318,0-230.9,103.582-230.9,230.9c0,45.12,13.019,87.25,35.483,122.853l-70.654,70.654
c-20.039,20.039-20.039,52.527,0,72.564c20.039,20.039,52.527,20.039,72.564,0l70.654-70.654
c35.605,22.464,77.735,35.483,122.853,35.483c127.318,0,230.9-103.582,230.9-230.9S408.42,0,281.1,0z M281.1,410.489
c-99.025,0-179.589-80.564-179.589-179.589S182.074,51.311,281.1,51.311S460.689,131.875,460.689,230.9
S380.127,410.489,281.1,410.489z"/>
</g>
</g>
</svg>
</button>
Get the SVG element and set the fill style.
let svg = document.getElementById("myButton").getElementsByTagName('svg')[0];
svg.style.fill = "yellow";
<button id="myButton" type="submit">
<svg width="32px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<path d="M281.1,0c-127.318,0-230.9,103.582-230.9,230.9c0,45.12,13.019,87.25,35.483,122.853l-70.654,70.654
c-20.039,20.039-20.039,52.527,0,72.564c20.039,20.039,52.527,20.039,72.564,0l70.654-70.654
c35.605,22.464,77.735,35.483,122.853,35.483c127.318,0,230.9-103.582,230.9-230.9S408.42,0,281.1,0z M281.1,410.489
c-99.025,0-179.589-80.564-179.589-179.589S182.074,51.311,281.1,51.311S460.689,131.875,460.689,230.9
S380.127,410.489,281.1,410.489z"/>
</g>
</g>
</svg>
</button>
document.getElementById("Layer_1").style.fill="yellow";
you must target the svg element not the parent div.and write it like this.
document.getElementById('myButton').querySelector('svg').style.fill = 'yellow';
Or you can eliminate the call to getElementById
document.querySelector('#myButton svg').style.fill = 'yellow';
In this example, the color is assigned by clicking on the button. And you had a mistake - instead of style.svg.fill, you need to write style.fill.
var button_svg = document.querySelector("#myButton");
button_svg.onclick = function (){
this.style.fill="yellow";
}
button {
width: 100px;
}
<button id="myButton" type="submit">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<path d="M281.1,0c-127.318,0-230.9,103.582-230.9,230.9c0,45.12,13.019,87.25,35.483,122.853l-70.654,70.654
c-20.039,20.039-20.039,52.527,0,72.564c20.039,20.039,52.527,20.039,72.564,0l70.654-70.654
c35.605,22.464,77.735,35.483,122.853,35.483c127.318,0,230.9-103.582,230.9-230.9S408.42,0,281.1,0z M281.1,410.489
c-99.025,0-179.589-80.564-179.589-179.589S182.074,51.311,281.1,51.311S460.689,131.875,460.689,230.9
S380.127,410.489,281.1,410.489z"/>
</g>
</g>
</svg>
</button>
It's toggle.
var button_svg = document.querySelector("#myButton");
button_svg.onclick = function (){
this.classList.toggle('svg_yellow');;
}
button {
width: 100px;
}
.svg_yellow {
fill: yellow;
}
<button id="myButton" type="submit">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<path d="M281.1,0c-127.318,0-230.9,103.582-230.9,230.9c0,45.12,13.019,87.25,35.483,122.853l-70.654,70.654
c-20.039,20.039-20.039,52.527,0,72.564c20.039,20.039,52.527,20.039,72.564,0l70.654-70.654
c35.605,22.464,77.735,35.483,122.853,35.483c127.318,0,230.9-103.582,230.9-230.9S408.42,0,281.1,0z M281.1,410.489
c-99.025,0-179.589-80.564-179.589-179.589S182.074,51.311,281.1,51.311S460.689,131.875,460.689,230.9
S380.127,410.489,281.1,410.489z"/>
</g>
</g>
</svg>
</button>
It's no click.
document.querySelector("#myButton").style.fill="yellow";
button {
width: 100px;
}
<button id="myButton" type="submit">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 512 512" xml:space="preserve">
<g>
<g>
<path d="M281.1,0c-127.318,0-230.9,103.582-230.9,230.9c0,45.12,13.019,87.25,35.483,122.853l-70.654,70.654
c-20.039,20.039-20.039,52.527,0,72.564c20.039,20.039,52.527,20.039,72.564,0l70.654-70.654
c35.605,22.464,77.735,35.483,122.853,35.483c127.318,0,230.9-103.582,230.9-230.9S408.42,0,281.1,0z M281.1,410.489
c-99.025,0-179.589-80.564-179.589-179.589S182.074,51.311,281.1,51.311S460.689,131.875,460.689,230.9
S380.127,410.489,281.1,410.489z"/>
</g>
</g>
</svg>
</button>
I am trying to make a play and stop button. I don't know how to morph the triangle shape (it is a path) into the square shape (it is a path) when it has been clicked. Only showing one shape at a time. Can anyone help?
<svg class="playStop" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 971 530" style="enable-background:new 0 0 971 530;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;
stroke:#000000;
stroke-width:4;
stroke-miterlimit:10;}
</style>
<path id="playTriangle" class="st0" d="M432,290.7V187.8c0-11.4,9.2-20.7,20.6-20.8c3.2,0,6.3,0.7,9.2,2.2l86.9,43.3l16.2,8.1c10.2,5,14.5,17.5,9.4,27.7c-2,4.1-5.3,7.5-9.4,9.5l-13.4,6.7l-89.8,44.8c-10.2,5-22.6,0.8-27.6-9.5C432.7,297,432,293.9,432,290.7z"/>
<path id="stopSquare" class="st0" d="M458.6,167h91.3c14.7,0,26.6,11.9,26.6,26.6v91.3c0,14.7-11.9,26.6-26.6,26.6h-91.3c-14.7,0-26.6-11.9-26.6-26.6v-91.3C432,178.9,443.9,167,458.6,167z"/>
</svg>
I think one way is to define your two paths in defs and then use a use xlink:href="#shapeName" with an onclick handler that toggles that attribute or the corresponding DOM property, if supported..
A use element object with fully implemented SVG DOM has a href property with a baseVal property that can be read and set, so inside browsers as far as I have tested (with Firefox, Chrome, IE and Edge on Window) we can simply toggle that property, see https://jsfiddle.net/4x0gnkob/ for an online sample.
.st0{fill:none;
stroke:#000000;
stroke-width:4;
stroke-miterlimit:10;}
<svg class="playStop" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 971 530" style="enable-background:new 0 0 971 530;" xml:space="preserve">
<defs>
<path id="playTriangle" class="st0" d="M432,290.7V187.8c0-11.4,9.2-20.7,20.6-20.8c3.2,0,6.3,0.7,9.2,2.2l86.9,43.3l16.2,8.1c10.2,5,14.5,17.5,9.4,27.7c-2,4.1-5.3,7.5-9.4,9.5l-13.4,6.7l-89.8,44.8c-10.2,5-22.6,0.8-27.6-9.5C432.7,297,432,293.9,432,290.7z"/>
<path id="stopSquare" class="st0" d="M458.6,167h91.3c14.7,0,26.6,11.9,26.6,26.6v91.3c0,14.7-11.9,26.6-26.6,26.6h-91.3c-14.7,0-26.6-11.9-26.6-26.6v-91.3C432,178.9,443.9,167,458.6,167z"/>
</defs>
<use xlink:href="#playTriangle" pointer-events="all" onclick="this.href.baseVal = this.href.baseVal == '#playTriangle' ? '#stopSquare' : '#playTriangle';"></use>
</svg>
An alternative is to toggle the DOM attribute, it seems a bit complicated in an HTML5 environment as I thought I could solve it with setAttributeNS and getAttributeNS in one line, after some testing it seems that within HTML5 getAttribute('xlink:href') works better, so the full code tries to test which function returns a value.
function toggleLink(element, value1, value2) {
var xlinkNS = 'http://www.w3.org/1999/xlink';
var linkName = 'xlink:href';
var oldValue = element.getAttributeNS(xlinkNS, linkName) || element.getAttribute(linkName);
if (element.hasAttributeNS(xlinkNS, 'href')) {
element.setAttributeNS(xlinkNS, linkName, oldValue == value1 ? value2 : value1)
}
else {
element.setAttribute(linkName, oldValue == value1 ? value2 : value1);
}
}
.st0{fill:none;
stroke:#000000;
stroke-width:4;
stroke-miterlimit:10;}
<svg class="playStop" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 971 530" style="enable-background:new 0 0 971 530;" xml:space="preserve">
<defs>
<path id="playTriangle" class="st0" d="M432,290.7V187.8c0-11.4,9.2-20.7,20.6-20.8c3.2,0,6.3,0.7,9.2,2.2l86.9,43.3l16.2,8.1c10.2,5,14.5,17.5,9.4,27.7c-2,4.1-5.3,7.5-9.4,9.5l-13.4,6.7l-89.8,44.8c-10.2,5-22.6,0.8-27.6-9.5C432.7,297,432,293.9,432,290.7z"/>
<path id="stopSquare" class="st0" d="M458.6,167h91.3c14.7,0,26.6,11.9,26.6,26.6v91.3c0,14.7-11.9,26.6-26.6,26.6h-91.3c-14.7,0-26.6-11.9-26.6-26.6v-91.3C432,178.9,443.9,167,458.6,167z"/>
</defs>
<use xlink:href="#playTriangle" pointer-events="all" onclick="toggleLink(this, '#stopSquare', '#playTriangle')"></use>
</svg>
Online at https://jsfiddle.net/w36k21uz/1/.
You cannot do all the things just like that, you can either use SMIL, which is to become deprecated, or use a dedicated animation engine. I developed KUTE.js with a SVG Plugin that does most of the things you probably need for SVG.
A quick demo (should work in Firefox only due to some Stackoverflow XSS issue):
<div style="width: 220px">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 600">
<path id="rectangle" fill="indigo" d="M38.01,5.653h526.531c17.905,0,32.422,14.516,32.422,32.422v526.531
c0,17.905-14.517,32.422-32.422,32.422H38.01c-17.906,0-32.422-14.517-32.422-32.422V38.075C5.588,20.169,20.104,5.653,38.01,5.653z"></path>
<path id="star" style="visibility:hidden" d="M301.113,12.011l99.25,179.996l201.864,38.778L461.706,380.808
l25.508,203.958l-186.101-87.287L115.01,584.766l25.507-203.958L0,230.785l201.86-38.778L301.113,12.011"></path>
</svg>
</div>
<script id="core" src="https://cdn.jsdelivr.net/kute.js/1.5.5/kute.min.js"></script>
<script id="svg" src="https://cdn.jsdelivr.net/kute.js/1.5.5/kute-svg.min.js"></script>
<script>
var tween = KUTE.to('#rectangle', { path: '#star' }, {duration: 1500, yoyo: true, repeat: 1}).start();
document.addEventListener('click', function(){
!tween.playing && tween.start();
}, false);
</script>