Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop the animation and freeze the image when pressing the `Stop` button

I created a layout of the working planetary gear.

When you click on the Stop button, the animation of the rotation of the gears should stop and the image “freeze”.

But in reality the image returns to its original state. This can be seen on the yellow markers on the gears.

Below is the code I’ve made at the moment:

<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" >
  <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>
    
    <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,160)">
      <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>

Question:

How to make it so that when you click the Stop button the image stops in the current state and the next time you press the GO button, the animation does not start from the beginning, but from the locked state.

I could not do it. I will be grateful for any solution.

like image 968
Alexandr_TT Avatar asked Feb 25 '19 06:02

Alexandr_TT


People also ask

How do you stop animation?

To remove more than one animation effect from text or an object, in the Animation Pane, press Ctrl, click each animation effect that you want to remove, and then press Delete. To remove all animation effects from text or an object, click the object that you want to stop animating.

How to stop an animation JavaScript?

pause() The pause() method of the Web Animations API's Animation interface suspends playback of the animation.

How do you wait for an animation to finish CSS?

Use a transition time of 0.6s when you hover and an animation time of 0.01 when you hover off. This way, the animation will reset itself to its original position pretty much immediately and stop the funky behaviour. Remember, you can have different animation effects on hovered and unhovered elements.


2 Answers

I have made some changes in the snippet. Please have a look and let me know if this is what you want.

<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" onload='Init(evt)' id = "SVGRoot">
  <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" dur="14s" id = "innerCircle" begin="click" 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" id = "smallerCircle" begin="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>
    
    <g id="planetar">
      <g>
        <animateTransform attributeName="transform" type="rotate" from="0 100 100" to="-360 100 100" id = "outerCircle" begin="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,160)">
      <g id="gO1" onclick='Play()'>
        <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" 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>
<script>
  var SVGDocument = null;
  var SVGRoot = null;
  var pauseButton = null;
  var playButton = null;
  var innerCircle = null;
  var outerCircle = null;
  var smallerCircle = null;

  function Init(evt)
  {  
     SVGDocument = evt.target.ownerDocument;
     SVGRoot = SVGDocument.getElementById('SVGRoot')

     pauseButton = SVGDocument.getElementById('stop1');
     playButton = SVGDocument.getElementById('gO1');
     innerCircle = SVGDocument.getElementById('innerCircle');;
     outerCircle = SVGDocument.getElementById('outerCircle');;
     smallerCircle = SVGDocument.getElementById('smallerCircle');;
  };

  function Pause()
  {  
     SVGRoot.pauseAnimations();
  };

  function Play()
  {
     if(SVGRoot.animationsPaused()){
        SVGRoot.unpauseAnimations();
     }
     else{
         innerCircle.beginElement();
         outerCircle.beginElement();
         smallerCircle.beginElement();
     }
  };

   </script>
like image 184
Kumar Aman Avatar answered Oct 12 '22 19:10

Kumar Aman


This is my solution, very similar to the @Duannx solution. However, when it comes to cogs I like to see them fitting. (no overlapping teeth). So what I've made was trying to recalculate the size of the teeth. I hope you will like it.

The animation starts and begins on clicking the svg canvas

c1r = 140;//the radius of the _c1 circle
c1perim = 2*Math.PI * c1r;// the perimeter of the _c1 circle

let sda = c1perim / 120;//sda = value for stroke-dasharray
// a css variable used to set the value for stroke-dasharray
cogs.style.setProperty("--foo", sda);
// the perimeter of _c2. This is the smaller circle used for the 3 identical cogs
c2perim = c1perim / Math.PI;
c2r = c1r/4; //the radius of the c2 circle
// the value  of the cx attribute of the _c2
c2cx = 150 + c1r - c2r;// 150 = center.x of the cogs
//the radius of the 3-rd circle, the one in the middle
c3r = c1r - c2r*2


// setting attributes
c1.setAttributeNS(null,"r",(c1r + sda));
_c1.setAttributeNS(null,"r",c1r);


_c2.setAttributeNS(null,"cx",c2cx);
c2.setAttributeNS(null,"cx",c2cx);
_c2.setAttributeNS(null,"r",c2r);
c2.setAttributeNS(null,"r",(c2r-sda));
g2.style.transformOrigin=`${c2cx}px 150px`;

_c3.setAttributeNS(null,"r",c3r);
c3.setAttributeNS(null,"r",(c3r-sda));


//event listener to toggle the class animated of the svg element
cogs.addEventListener("click",()=>{cogs.classList.toggle("animated")})
svg {
  width: 300px;
  border: 1px solid;
}
circle {
  
  stroke-width: var(--foo);
  fill: none;
}

g {
  transform-origin: 150px 150px;
  animation: rotate 80s linear infinite;
  stroke: black;
}

.animated g{animation-play-state: paused;}
#g2 {
  animation-duration:20s;
  stroke:#444;
}
#g3 {
  animation-duration:40s;
  animation-direction: reverse;
}

[id ^="_"] {
  stroke-dasharray: var(--foo);
}
#_c2 {
  stroke-dashoffset: var(--foo);
}

@keyframes rotate {
  to {
    transform: rotate(360deg);
  }
}
<svg id="cogs" class="animated" viewBox="-20 -20 340 340">
  <g id="g1">
  <circle id="c1" cx="150" cy="150" r="" />
  <circle id="_c1" cx="150" cy="150" r="" />
  </g>
  <g id="g2">
  <circle id="c2" cx="" cy="150" r="" />
  <circle id="_c2" cx="" cy="150" r="" />
  </g>
  <g id="g3">
  <circle id="c3" cx="150" cy="150" r=""  />
  <circle id="_c3" cx="150" cy="150" r=""  />
  </g>
 
  <use xlink:href="#g2" transform="rotate(120 150 150 )" />
  <use xlink:href="#g2" transform="rotate(240 150 150 )" />
</svg>
like image 21
enxaneta Avatar answered Oct 12 '22 21:10

enxaneta