How to convert one element of an SVG path to another in a click command?

I am trying to make a play and stop button. I do not know how to convert the shape of a triangle (this is the way) to the square shape (this is the way) when it was pressed. Show only 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> 
+5
source share
2 answers

I think one way is to define your two paths in defs and then use use xlink:href="#shapeName" with an onclick handler that switches this attribute or the corresponding DOM property, if supported ..

An object

A use with a fully implemented SVG DOM has a href property with a baseVal property that can be read and set, so inside the browsers, as far as I tested (with Firefox, Chrome, IE and Edge on Window), we can simply switch this property, see https : //jsfiddle.net/4x0gnkob/ for the 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 switch the DOM attribute, it seems a little complicated in the HTML5 environment, since I thought I could solve it with setAttributeNS and getAttributeNS in one line, after some testing, it seems that getAttribute('xlink:href') works better in HTML5, therefore, the full code tries to check which function returns the 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 https://jsfiddle.net/w36k21uz/1/ .

+3
source

You cannot do anything; you can use SMIL , which should become obsolete or use a dedicated animation engine. I developed KUTE.js with the SVG Plugin , which does most of the things you probably need for SVG.

Quick demo (should work in Firefox just because of some kind of problem with XStackoverflow):

 <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> 
0
source

Source: https://habr.com/ru/post/1239671/


All Articles