SVG pause/play Can not figure out why this isn't working…?

Issue

I need code to work just like on this page.

Play and pausing of an SVG. I went into inspect and pulled all the code I could, which seemed to be HTML. I could not see or find CSS or Javascript. Not sure if that is normal.

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="80 0 1024 768" onload="t=setInterval(updateTimer, 100)">
  
<script>
  var time = 0;
  function updateTimer() {
    //document.getElementById("t").textContent = document.documentElement.getCurrentTime().toFixed(0) + "s";
  }
  function pause() {
    time = document.documentElement.getCurrentTime();
    document.documentElement.pauseAnimations();
    clearInterval(t);
  }
  function play() {
    if(time &gt; 0)
      document.documentElement.setCurrentTime(time);

    clearInterval(t);
    t=setInterval(updateTimer, 100);    
    document.documentElement.unpauseAnimations();
  }
  function stop() {
    time = 0;
    clearInterval(t);
    document.documentElement.setCurrentTime(0); 
    document.documentElement.pauseAnimations();
  }
  </script>
  
<linearGradient id="grad">
    <stop stop-color="rgb(10%,80%,10%)" offset="0"/>
    <stop stop-color="rgb(10%,40%,20%)" offset="0.4"/>
    <stop stop-color="rgb(10%,90%,30%)" offset="0.7"/>
    <stop stop-color="rgb(10%,50%,40%)" offset="1"/>
  </linearGradient>
  
<rect fill="url(#grad)" width="0%" height="50" x="100" y="300" rx="5">
    <animate attributeName="width" to="100%" begin="0s" dur="30s"/>
  </rect>
  
<text id="t" style="font:24px Arial Black;fill:white;stroke:black" transform="translate(100 334)"/>
  
<animateTransform type="translate" attributeName="transform" xlink:href="#t" begin="1s" dur="29s" from="100 334" to="1024 334"/>
  
<g transform="translate(100 500)">
    
<!-- Play -->
  	<g onclick="play()">
  	  <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5"/>
  	  <path id="play" d="M12 5l20 15l-20 15Z" fill="white" pointer-events="none"/>
  	</g>
  	
<!-- Pause -->
  	<g transform="translate(50 0)">
  	  <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5" onclick="pause();"/>
  	  <path id="pause" d="M14 10l0 20M26 10l0 20" stroke="white" fill="none" stroke-width="8" pointer-events="none"/>
  	</g>
  	
<!-- Stop (rewind and pause) -->
  	<g transform="translate(100 0)">
  	  <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5" onclick="stop()"/>
  	  <rect x="10" y="10" width="20" height="20" fill="white" pointer-events="none"/>
  	</g>
  </g>
</svg>

When I attempt playback on Code pen, the SVG plays but buttons don’t work. At all. I thought the “onclick” would do it…?

Is this because the JS isn’t accessible/applied? I don’t see any “DIV” or “DOM” so I assume its not a CSS thing…

I have a basic knowledge of HTML, less of CSS and know NOTHING about JavaScript

Solution

Short version: getCurrentTime & setCurrentTime must be called on the SVG node.

const mySvg = document.getElementById("mySvg")

function updateTimer() {
  const t = `${mySvg.getCurrentTime().toFixed(0)}s`;
  document.getElementById("t").textContent = t;
}

function setCurrentTime(t) {
  mySvg.setCurrentTime(t)
}

function pause() {
  mySvg.pauseAnimations()
}

function play() {
  mySvg.unpauseAnimations()
}

function stop() {
  clearInterval();
  setCurrentTime(0);
  mySvg.pauseAnimations()
  updateTimer();
}
<svg id="mySvg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="80 0 1024 768" onload="t=setInterval(updateTimer, 100)">
  <linearGradient id="grad">
    <stop stop-color="rgb(10%,80%,10%)" offset="0"/>
    <stop stop-color="rgb(10%,40%,20%)" offset="0.4"/>
    <stop stop-color="rgb(10%,90%,30%)" offset="0.7"/>
    <stop stop-color="rgb(10%,50%,40%)" offset="1"/>
  </linearGradient>
  <rect fill="url(#grad)" width="0%" height="50" x="100" y="300" rx="5">
    <animate attributeName="width" to="100%" begin="0s" dur="30s"/>
  </rect>
  <text id="t" style="font:24px Arial Black;fill:white;stroke:black" transform="translate(100 334)"/>
  <animateTransform type="translate" attributeName="transform" xlink:href="#t" begin="1s" dur="29s" from="100 334" to="1024 334"/>
  <g transform="translate(100 500)">
    <!-- Play -->
    <g onclick="play()">
     <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5"/>
     <path id="play" d="M12 5l20 15l-20 15Z" fill="white" pointer-events="none"/>
   </g>
   <!-- Pause -->
   <g transform="translate(50 0)">
     <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5" onclick="pause();"/>
     <path id="pause" d="M14 10l0 20M26 10l0 20" stroke="white" fill="none" stroke-width="8" pointer-events="none"/>
   </g>
   <!-- Stop (rewind and pause) -->
   <g transform="translate(100 0)">
     <rect width="40" height="40" rx="10" stroke="black" fill-opacity="0.5" onclick="stop()"/>
     <rect x="10" y="10" width="20" height="20" fill="white" pointer-events="none"/>
   </g>
 </g>
</svg>

Long version: After all that, why wasn’t it working in Codepen?
I can see that the link you posted is to an SVG document with it’s own inline JavaScript (in the script tag).

The script calls some SVGElement methods on the SVG root element with document.documentElement.pauseAnimations();.
But what exactly is document element?

Document.documentElement returns the Element that is the root element of the document (for example, the element for HTML documents).

Because this code was called inside an SVG document, document.documentElement returns the SVG root node. However, because codepen is an HTML document, document.documentElement will return the HTML root node.

And you can’t call methods like pauseAnimations() on an HTML root node because the HTML root node doesn’t understand those methods.

So modern browsers can display SVG documents, HTML documents (and more) but here’s the kicker: SVG documents can live inside of HTML documents.

You can see how document.documentElement could refer to two potential things depending on what type of document the JavaScript code was run from.

Answered By – ksav

Answer Checked By – Robin (AngularFixing Admin)

Leave a Reply

Your email address will not be published.