javascript – How to stop the animation and freeze the image when you press the `Stop` button

Question:

Animation of the planetary gear .

When you press the Stop button, the animation of the rotation of the gears should stop and the image should "freeze". But in reality, the image returns to its original state. This can be seen from the yellow markers on the gears. How to achieve that when you press the Stop button, the image freezes in the current state and when you press the GO button again, the animation starts not from the beginning, but from the fixed state.

Answer – you need to remove the yellow markers is not accepted 🙂

<style>
.container {
width:35vw;
height:35vh;
}
</style>
<div class="container">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink'  viewBox="0 0 400 400" >
  <title>animation planetary mechanism</title>
  <defs>
    <marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
      <rect width="14" height="10" rx="2" fill="#22211D" />
    </marker>
    <line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none;
                 marker-end: url(#MarkerArrow);
                 marker-start: url(#MarkerArrow);
               stroke:#22211D; stroke-width:6; ">
    </line>
    <marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20">
      <rect width="7" height="3.5" rx="2" fill="#22211D" />
    </marker>
    <line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none;
             marker-end: url(#MarkerArrow-s1);
             marker-start: url(#MarkerArrow-s);
           stroke:#22211D; stroke-width:2; ">

    </line>
    <linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad">
      <stop offset="0%" stop-color="powderblue" />
      <stop offset="100%" stop-color="lightgreen" />
    </linearGradient>

  </defs>
  <rect width="100%" height="100%" fill="url(#vertical)" />
  <g transform="translate(90,50)">

    <g id="wheel">
      <g>
        <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" begin="gO1.click" end="stop1.click" dur="14s" repeatCount="indefinite" />
        <use xlink:href="#line1" transform="rotate(0 100 100)" />
        <use xlink:href="#line1" transform="rotate(120 100 100)" />
        <use xlink:href="#line1" transform="rotate(240 100 100)" />


        <circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none;   stroke-width: 4px;" />
        <circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none;   stroke-width: 15px;" />
        <circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6;  stroke-width: 10px;" />
        <circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
      </g>
    </g>

    <g id="col-small">

      <g>
        <animateTransform attributeName="transform" type="rotate" from="0 188 100" to="-360 188 100" begin="gO1.click" end="stop1.click" dur="3.5s" repeatCount="indefinite" />
        <use xlink:href="#line-s" transform="rotate(0 188 100)" />
        <use xlink:href="#line-s" transform="rotate(120 188 100)" />
        <use xlink:href="#line-s" transform="rotate(240 188 100)" />

        <circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none;   stroke-width: 4px;" />
        <circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none;   stroke-width: 7px;" />
        <circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5;  stroke-width: 10px;" />
        <circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />

      </g>
    </g>
    <desc>animation planetary mechanism https://svg-art.ru in pure svg</desc>
    <g id="planetar">
      <g>
        <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-360 100 100" begin="gO1.click" end="stop1.click" dur="28s" repeatCount="indefinite" />

        <circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none;   stroke-dasharray: 5 5;  stroke-width: 10px;" />
        <circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none;   stroke-width: 12px;" />
        <circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " />
      </g>
    </g>

    <g>
      <use xlink:href="#col-small" transform="rotate(240 100 100)" />
      <use xlink:href="#col-small" transform="rotate(120 100 100)" />
    </g>

    <g transform="translate(-10,180)">
      <g id="gO1">
        <rect x="45" y="85" height="22" width="60" rx="5" fill="#0080B8" stroke="dodgerblue" />
        <text x="62" y="102" font-size="16" fill="yellow">GO</text>
      </g>
      <g id="stop1">
        <rect x="110" y="85" height="22" width="60" rx="5" fill="crimson" stroke="red" />
        <text x="120" y="102" font-size="16" fill="yellow">STOP</text>
      </g>
    </g>

  </g>
</svg> 
</div>

Answer:

I didn't really work with svg , so here's what I googled:
The animation can be started / stopped through the unpauseAnimations / pauseAnimations respectively.

You can do this:

 let flag = 0, svg = document.querySelector('svg'); // Необходимо поймать второй клик (если на первом удалить атрибуты, анимация не начнётся), потом подменяем функцию на вызов по "разморозке" анимации let start = function(){ if(flag === 1){ // Убираем у animateTransform триггер, чтобы не сбрасывалась анимация на ноль Array.from(svg.querySelectorAll('animateTransform')).forEach(e => e.removeAttribute('begin')); start = _ => svg.unpauseAnimations(); start(); } flag++; } const pause = function(){ svg.pauseAnimations(); }
 <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink='http://www.w3.org/1999/xlink' width="400" height="400" viewBox="0 0 400 400" style="border:1px solid red;"> <title>animation planetary mechanism</title> <defs> <marker id="MarkerArrow" viewBox="0 0 20 20" refX="2" refY="5" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20"> <rect width="14" height="10" rx="2" fill="#22211D" /> </marker> <line id="line1" x1="150" y1="100" x2="60" y2="100" style=" fill:none; marker-end: url(#MarkerArrow); marker-start: url(#MarkerArrow); stroke:#22211D; stroke-width:6; "> </line> <marker id="MarkerArrow-s" viewBox="0 0 20 20" refX="3" refY="1.7" markerUnits="userSpaceOnUse" orient="auto" markerWidth="20" markerHeight="20"> <rect width="7" height="3.5" rx="2" fill="#22211D" /> </marker> <line id="line-s" x1="175" y1="100" x2="202" y2="100" style=" fill:none; marker-end: url(#MarkerArrow-s1); marker-start: url(#MarkerArrow-s); stroke:#22211D; stroke-width:2; "> </line> <linearGradient id="vertical" x2="0%" y2="100%" spreadMethod="pad"> <stop offset="0%" stop-color="powderblue" /> <stop offset="100%" stop-color="lightgreen" /> </linearGradient> </defs> <rect width="100%" height="100%" fill="url(#vertical)" /> <g transform="translate(90,50)"> <g id="wheel"> <g> <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="360 100 100" begin="gO1.click" dur="14s" repeatCount="indefinite" /> <use xlink:href="#line1" transform="rotate(0 100 100)" /> <use xlink:href="#line1" transform="rotate(120 100 100)" /> <use xlink:href="#line1" transform="rotate(240 100 100)" /> <circle cx="100" cy="100" r="15" style="stroke: #22211D; fill:none; stroke-width: 4px;" /> <circle cx="100" cy="100" r="50" style="stroke: #22211D; fill:none; stroke-width: 15px;" /> <circle cx="100" cy="100" r="60" style="stroke: #22211D; fill:none; stroke-dasharray: 5 6; stroke-width: 10px;" /> <circle cx="150" cy="100" r="3" style="stroke: #22211D; fill:yellow; " /> </g> </g> <g id="col-small"> <g> <animateTransform attributeName="transform" type="rotate" from="0 188 100" to="-360 188 100" begin="gO1.click" dur="3.5s" repeatCount="indefinite" /> <use xlink:href="#line-s" transform="rotate(0 188 100)" /> <use xlink:href="#line-s" transform="rotate(120 188 100)" /> <use xlink:href="#line-s" transform="rotate(240 188 100)" /> <circle cx="188" cy="100" r="8" style="stroke: #22211D; fill:none; stroke-width: 4px;" /> <circle cx="188" cy="100" r="18" style="stroke: #22211D; fill:none; stroke-width: 7px;" /> <circle cx="188" cy="100" r="24" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" /> <circle cx="206" cy="100" r="3" style="stroke: #22211D; fill:yellow; " /> </g> </g> <desc>animation planetary mechanism https://svg-art.ru in pure svg</desc> <g id="planetar"> <g> <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-360 100 100" begin="gO1.click" dur="28s" repeatCount="indefinite" /> <circle cx="100" cy="100" r="116" style="stroke: #22211D; fill:none; stroke-dasharray: 5 5; stroke-width: 10px;" /> <circle cx="100" cy="100" r="124" style="stroke: #22211D; fill:none; stroke-width: 12px;" /> <circle cx="224" cy="100" r="3" style="stroke: #22211D; fill:yellow; " /> </g> </g> <g> <use xlink:href="#col-small" transform="rotate(240 100 100)" /> <use xlink:href="#col-small" transform="rotate(120 100 100)" /> </g> <g transform="translate(-10,180)"> <g id="gO1" onclick='start();'> <rect x="45" y="85" height="22" width="60" rx="5" fill="#0080B8" stroke="dodgerblue" /> <text x="62" y="102" font-size="16" fill="yellow">GO</text> </g> <g onclick='pause();'> <rect x="110" y="85" height="22" width="60" rx="5" fill="crimson" stroke="red" /> <text x="120" y="102" font-size="16" fill="yellow">STOP</text> </g> </g> </g> </svg>
Scroll to Top