Search code examples
javascriptcssanimationsvgsvg-animate

How to make the equalizer start button work correctly?


I have developed an application that simulates the work of an equalizer in terms of showing changes in audio frequencies.

enter image description here

Animation problems occur when you press the "Start" button again.
The animation results are reset and start over from the beginning.
Of course, this can be avoided by putting protection against repeated clicks while the animation is active
restart =" whenNotactive "

But this is an incomplete solution to the problem.

I tried to hang the begin ="start.click" event on the "Start" button and
on the "Pause" button end ="pause.click"

my code is below:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
    xmlns:xlink="http://www.w3.org/1999/xlink"
       width="100%" height="100%" viewBox="0 0 400 150" preserveAspectRatio="xMinYMin meet" >  

 <defs>  
     <!-- Mask for forming the display of a part of the active line (with stroke = "white") -->
   <mask id="msk">
      <rect width="100%" height="100%" fill="black" /> 
     <rect x="15" y="0" width="60" height="160" fill="white" stroke="white" /> 
</mask> 
 </defs>  
       <!-- Black background -->
      <rect width="22%" height="100%" fill="black" /> 
   <!-- Colored line markers to show equalizer frequency levels  -->
 <polyline  points="10,0 10,139" stroke="#4C4C50" />     
     <polyline  points="80,0 80,139" stroke="#4C4C50" />       
  <polyline id="grey" points="20,0 20,139" stroke="#2A2A2C" /> 
    <use xlink:href="#grey" x="10" />
     <use xlink:href="#grey" x="20" />
      <use xlink:href="#grey" x="30" />
        <use xlink:href="#grey" x="40" />
          <use xlink:href="#grey" x="50" />
   <polyline points="15,2 74,2" stroke-width="2" stroke="#2A2A2C" />          
    <polyline points="15,19 74,19" stroke="red" />    
     <polyline points="15,44 74,44" stroke="green" />     
      <polyline points="15,69 74,69" stroke="dodgerblue" />
       <polyline points="15,94 74,94" stroke="green" /> 
        <polyline points="15,119 74,119" stroke="gold" /> 
         <polyline points="15,139 74,139" stroke-width="2" stroke="#2A2A2C" />
       <!-- Frequency labeling text -->
    <text x="12" y="15" font-size="6px" fill="yellow">16K</text>    
     <text x="12" y="40" font-size="6px" fill="yellow">6K</text>    
      <text x="12" y="67" font-size="6px" fill="yellow">1K</text>  
        <text x="12" y="92" font-size="6px" fill="yellow">310</text> 
          <text x="12" y="117" font-size="6px" fill="yellow">170</text> 
           <!-- Button to start animation -->
        <g id="start" transform="translate(60,0)" cursor="pointer">
          <text x="2" y="147" font-size="8px" fill="yellow">Start</text> 
          <circle cx="23" cy="145" r="3" fill="greenyellow" />
        </g>   
            <g id="pause" transform="translate(10,0)" cursor="pointer">
          <text x="2" y="147" font-size="8px" fill="yellow">Pause</text> 
          <circle cx="25" cy="145" r="3" fill="red" />
        </g>
        <!-- Trajectory of line movement showing audio frequency -->
 <g stroke-linecap="round" stroke-linejoin="round" mask="url(#msk)"> 
 <path id="trace" transform="translate(348, 0)"  
     fill="none" stroke="cyan" stroke-width="1.5" d="m-246 68.4c0 0 32.6 0 47.8 0 9.2 0 12.9-30.8 16.4-22.3 4.8 11.5 6 43.3 6 43.3l7.9-26.6 5 35.9 8.9-63.5 3.7 80.9 5.2-93.7 4.8 108.2 6.6-125.2 2.6 84 4.8-31.8 5 23.3 2-18.1 5.5 12.1 4-12.1 2.8 26.6 3.3-31.8 3.6 43.1 5.5-55.5 2.2 70.8 6.5-80.9 3.2 95.4 6-112.9 2.7 125.7 7-131.5 2.6 131.5 5.9-131.6 5.1 118.8 8.7-108.2 5 93.7 10.1-87.9 3.4 76.1 11.8-69.2 3.1 54.3L-5.6 44.1 0 74.9 4 57.7 8.6 74.9 13.7 51l4.3 23.9 4.7-35.2 8.2 53.5 6.3-58.1 5.7 54.3 9-54.3 5.9 54.3 6.2-54.3 8.6 54.3 5.9-67.1 8.6 81.9 7.3-89.6 5.5 95.4 6.6-100.6 6.2 115.5 6.9-115.1 4.1 128.6 7.3-127.6 2.8 132.4 8.3-133.8 4.1 121 4.8-108.2 4.8 101.7 4.8-96.5 5.9 94.4 2.8-86.8 4.8 73 4.1-62.9 6.9 59.1 2.8-50.1 4.8 42.2 2.4-37.7 4.1 27 2.1-22.8 2.4 20.4 1.7-24.9 2.4 22.5 2.4-21.4 1.7 15.6 3.1-12.1 2.8 67.8 3.8-95.4 2.8 89.9 9.7-102.7 4.1 102 6.2-102 4.1 93.7 4.8-80.9 4.8 69.2 4.5-61.2 3.8 53.9 4.1-41.1 3.8 27.7 3.1-20.7 4.1 12.1 2.8-12.1 3.5 12.1 2.4-12.1 4.5 26.6 2.4-42.1 6.6 57 4.8-69.2 7.3 80.9 5.5-93.7 10.4 108.2 2.1-114.5 8 127.2 2.8-130.7 8 122.4 4.8-124.5 8 114.5 3.5-98.2 7.3 83 5.5-79.5 4.8 68.8 6.9-53.1V80.8l4.5-18 5.2 17.2 3-22.4 3.4 27 5.1-27 2.4 46.7 7.5-69.2 2.9 76.5c0 0 2.8-66.4 7.3-84.8 5.3-21.4 6.6 103.7 6.6 103.7l7-116.8 10 129.6 3.2-112.6 8.8 112.6 2.8-94.6 8 48.3 1.9-44 2.9 29.7 3.6-25 4.7 21.5 3.6-16.3 3.1 14.8 6.5-64.2 5.2 102.7 7.5-101.1 5.6 101.1 6.2-97.9 5.9 92.8 5.5-82.9 5.2 80.7 4.3-70.7 2.7 66.3 6-54.4 4.1 46 6.2-83.1 6.9 117.8 4.6-116.1 10 101.6 0.4-78.3 8 60.5c0 0 3.1-34.2 6.8-51 2.7-12.1 2 16.9 8.2 21.1 4.2 2.9 15.4 0.1 15.4 0.1h19.7" > 
         <!-- Equalizer line animation -->
       <animateTransform
        id="at1"
        attributeName="transform"
        type="translate"
        begin="start.click"
        end="pause.click"
        dur="22s"
        values="250 0;-650 0"
        fill="freeze"
        repeatCount="3" />
 </path> 
  </g>   
</svg>   

But this is not what you need. The animation starts again from the beginning when you press the Start button.
I need that when the Pause button is pressed, the animation stops, and when the Start button is pressed again, it starts from the point of stopping.

Question:

How to get the animation to start from where the previous animation stopped when you press the Start button again?

Apparently purely in SVG, this task is impossible. Therefore CSS and JS solutions will be helpful.


Solution

  • Option JS Solution

    Javascript methods are used:

    SVGRoot.animationsPaused()
    SVGRoot.unpauseAnimations()

    function Init(evt)
      {  
         SVGDocument = evt.target.ownerDocument;
         SVGRoot = SVGDocument.getElementById('SVGRoot');
    
         pauseButton = SVGDocument.getElementById('pause1');
         playButton = SVGDocument.getElementById('start1');
         equalizer = SVGDocument.getElementById('equalizer');
      };
    
      function Pause()
      {  
         SVGRoot.pauseAnimations();
      };
    
      function Start()
      {
         if(SVGRoot.animationsPaused()){
            SVGRoot.unpauseAnimations();
         }
         else{
             equalizer.beginElement();
             
         }
      };
    text.yellow {
    fill:yellow;
    font-size:6px;
    }
    g#gr1 {
    stroke-linecap:round;
    stroke-linejoin:round;
     mask:url(#msk);
     transform:translate(348, 0);  
    }
    #trace{
    fill:none;
    stroke:cyan;
    stroke-width:1.5;
    }
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" 
        xmlns:xlink="http://www.w3.org/1999/xlink"
           width="100%" height="100%" viewBox="0 0 400 150" preserveAspectRatio="xMinYMin meet" 
           onload='Init(evt)' id = "SVGRoot" >  
    
     <defs>  
         <!-- Mask for forming the display of a part of the active line (with stroke = "white") -->
       <mask id="msk">
          <rect width="100%" height="100%" fill="black" /> 
         <rect x="15" y="0" width="60" height="160" fill="white" stroke="white" /> 
    </mask> 
     </defs>  
           <!-- Black background -->
          <rect width="22%" height="100%" fill="black" /> 
       <!-- Colored line markers to show equalizer frequency levels  -->
     <polyline  points="10,0 10,139" stroke="#4C4C50" />     
         <polyline  points="80,0 80,139" stroke="#4C4C50" />       
      <polyline id="grey" points="20,0 20,139" stroke="#2A2A2C" /> 
        <use xlink:href="#grey" x="10" />
         <use xlink:href="#grey" x="20" />
          <use xlink:href="#grey" x="30" />
            <use xlink:href="#grey" x="40" />
              <use xlink:href="#grey" x="50" />
       <polyline points="15,2 74,2" stroke-width="2" stroke="#2A2A2C" />          
        <polyline points="15,19 74,19" stroke="red" />    
         <polyline points="15,44 74,44" stroke="green" />     
          <polyline points="15,69 74,69" stroke="dodgerblue" />
           <polyline points="15,94 74,94" stroke="green" /> 
            <polyline points="15,119 74,119" stroke="gold" /> 
             <polyline points="15,139 74,139" stroke-width="2" stroke="#2A2A2C" />
           <!-- Frequency labeling text -->
        
        <text class="yellow" x="12" y="15"  >16K</text>     
         <text class="yellow" x="12" y="40" >6K</text>  
          <text class="yellow" x="12" y="67"  >1K</text>  
            <text class="yellow" x="12" y="92"  >310</text> 
              <text class="yellow" x="12" y="117"  >170</text> 
               <!-- Button to start animation -->
            <g id="start1" transform="translate(60,0)" cursor="pointer" onclick='Start()'>
              <text x="2" y="147" font-size="8px" fill="yellow">Start</text> 
              <circle cx="23" cy="145" r="3" fill="greenyellow" />
            </g>   
                <g id="pause1" transform="translate(10,0)" cursor="pointer" onclick='Pause()'>
              <text x="2" y="147" font-size="8px" fill="yellow">Pause</text> 
              <circle cx="25" cy="145" r="3" fill="red" />
            </g>
            <!-- Trajectory of line movement showing audio frequency -->
     <g id="gr1"> 
     <path id="trace" transform="translate(348, 0)"  
         fill="none" stroke="cyan" stroke-width="1.5" d="m-246 68.4c0 0 32.6 0 47.8 0 9.2 0 12.9-30.8 16.4-22.3 4.8 11.5 6 43.3 6 43.3l7.9-26.6 5 35.9 8.9-63.5 3.7 80.9 5.2-93.7 4.8 108.2 6.6-125.2 2.6 84 4.8-31.8 5 23.3 2-18.1 5.5 12.1 4-12.1 2.8 26.6 3.3-31.8 3.6 43.1 5.5-55.5 2.2 70.8 6.5-80.9 3.2 95.4 6-112.9 2.7 125.7 7-131.5 2.6 131.5 5.9-131.6 5.1 118.8 8.7-108.2 5 93.7 10.1-87.9 3.4 76.1 11.8-69.2 3.1 54.3L-5.6 44.1 0 74.9 4 57.7 8.6 74.9 13.7 51l4.3 23.9 4.7-35.2 8.2 53.5 6.3-58.1 5.7 54.3 9-54.3 5.9 54.3 6.2-54.3 8.6 54.3 5.9-67.1 8.6 81.9 7.3-89.6 5.5 95.4 6.6-100.6 6.2 115.5 6.9-115.1 4.1 128.6 7.3-127.6 2.8 132.4 8.3-133.8 4.1 121 4.8-108.2 4.8 101.7 4.8-96.5 5.9 94.4 2.8-86.8 4.8 73 4.1-62.9 6.9 59.1 2.8-50.1 4.8 42.2 2.4-37.7 4.1 27 2.1-22.8 2.4 20.4 1.7-24.9 2.4 22.5 2.4-21.4 1.7 15.6 3.1-12.1 2.8 67.8 3.8-95.4 2.8 89.9 9.7-102.7 4.1 102 6.2-102 4.1 93.7 4.8-80.9 4.8 69.2 4.5-61.2 3.8 53.9 4.1-41.1 3.8 27.7 3.1-20.7 4.1 12.1 2.8-12.1 3.5 12.1 2.4-12.1 4.5 26.6 2.4-42.1 6.6 57 4.8-69.2 7.3 80.9 5.5-93.7 10.4 108.2 2.1-114.5 8 127.2 2.8-130.7 8 122.4 4.8-124.5 8 114.5 3.5-98.2 7.3 83 5.5-79.5 4.8 68.8 6.9-53.1V80.8l4.5-18 5.2 17.2 3-22.4 3.4 27 5.1-27 2.4 46.7 7.5-69.2 2.9 76.5c0 0 2.8-66.4 7.3-84.8 5.3-21.4 6.6 103.7 6.6 103.7l7-116.8 10 129.6 3.2-112.6 8.8 112.6 2.8-94.6 8 48.3 1.9-44 2.9 29.7 3.6-25 4.7 21.5 3.6-16.3 3.1 14.8 6.5-64.2 5.2 102.7 7.5-101.1 5.6 101.1 6.2-97.9 5.9 92.8 5.5-82.9 5.2 80.7 4.3-70.7 2.7 66.3 6-54.4 4.1 46 6.2-83.1 6.9 117.8 4.6-116.1 10 101.6 0.4-78.3 8 60.5c0 0 3.1-34.2 6.8-51 2.7-12.1 2 16.9 8.2 21.1 4.2 2.9 15.4 0.1 15.4 0.1h19.7" > 
             <!-- Equalizer line animation -->
           <animateTransform
            id="equalizer"
            attributeName="transform"
            type="translate"
            dur="22s"
            values="250 0;-650 0"
            fill="freeze"
            repeatCount="indefinite"
            restart="whenNotActive"
            />
     </path> 
      </g>   
    </svg>  

    UPDATE

    LIVE DEMO