Search code examples
javascripthtmlanimationsvgsvg-animate

How to stop SVG animation on click?


I have an svg animation, I want to be able to stop/pause the animation on click but I can't figure out how and I need help, I tried to toggle but I think I have to toggle each line which I don't know how to.

<div class="loader">
      <svg id="wave" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 38.05">
        <path id="Line_1" class="t" data-name="Line 1" d="M0.91,15L0.78,15A1,1,0,0,0,0,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H0.91Z"/>
        <path id="Line_1" class="t" data-name="Line 2" d="M6.91,9L6.78,9A1,1,0,0,0,6,10V28a1,1,0,1,0,2,0s0,0,0,0V10A1,1,0,0,0,7,9H6.91Z"/>
        <path id="Line_1" class="t" data-name="Line 3" d="M12.91,0L12.78,0A1,1,0,0,0,12,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H12.91Z"/>
        <path id="Line_1" class="t" data-name="Line 4" d="M18.91,10l-0.12,0A1,1,0,0,0,18,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H18.91Z"/>
        <path id="Line_1" class="t" data-name="Line 5" d="M24.91,15l-0.12,0A1,1,0,0,0,24,16v6a1,1,0,0,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H24.91Z"/>
        <path id="Line_1" class="t" data-name="Line 6" d="M30.91,10l-0.12,0A1,1,0,0,0,30,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H30.91Z"/>
        <path id="Line_1" class="t" data-name="Line 7" d="M36.91,0L36.78,0A1,1,0,0,0,36,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H36.91Z"/>
        <path id="Line_1" class="t" data-name="Line 8" d="M42.91,9L42.78,9A1,1,0,0,0,42,10V28a1,1,0,1,0,2,0s0,0,0,0V10a1,1,0,0,0-1-1H42.91Z"/>
        <path id="Line_1" class="t" data-name="Line 9" d="M48.91,15l-0.12,0A1,1,0,0,0,48,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H48.91Z"/>
      </svg>
      </div>

css

.loader {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
#wave {
  height: 70px;
  width: 70px;
  fill: black;
}
#wave.stop {
  animation-play-state: paused;
}

#Line_1 {
  animation: pulse 1s infinite;
  animation-delay: 0.15s;
}
#Line_2 {
  animation: pulse 1s infinite;
  animation-delay: 0.3s;
}
#Line_3 {
  animation: pulse 1s infinite;
  animation-delay: 0.45s;
}
#Line_4 {
  animation: pulse 1s infinite;
  animation-delay: 0.6s;
}
#Line_5 {
  animation: pulse 1s infinite;
  animation-delay: 0.75s;
}
#Line_6 {
  animation: pulse 1s infinite;
  animation-delay: 0.9s;
}
#Line_7 {
  animation: pulse 1s infinite;
  animation-delay: 1.05s;
}
#Line_8 {
  animation: pulse 1s infinite;
  animation-delay: 1.2s;
}
#Line_9 {
  animation: pulse 1s infinite;
  animation-delay: 1.35s;
}

js

  var vawe = document.getElementById("vawe")
  vawe.addEventListener('click',function() {
    vawe.classList.toggle('stop');
     })

when I click on the svg I want to stop pause the animation, so that the music stop, and then click again the animation starts again.


Solution

  • #wave.stop {
      animation-play-state: paused;
    }
    

    Doesn't apply the animation-play-state to the actually animated (line) elements.
    The css rule should rather look something like this:

    #wave.stop .t {
      animation-play-state: paused;
    }
    

    I also recommend to use class selectors to avoid unnecessarily high specificity
    (introduced by id selectors in your css rules).

    var wave = document.getElementById("wave")
    wave.addEventListener('click', function(e) {
      e.currentTarget.classList.toggle('stop');
    })
    .loader {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
    }
    
    #wave {
      height: 10em;
      fill: black;
    }
    
    .stop {
      border: 1px solid red;
    }
    
    .stop .t {
      animation-play-state: paused;
    }
    
    .t {
      transform-origin: center;
      animation: pulse 1s infinite forwards;
      transform: scale(1, 0.5)
    }
    
    .Line_1 {
      animation-delay: 0.15s;
    }
    
    .Line_2 {
      animation-delay: 0.3s;
    }
    
    .Line_3 {
      animation-delay: 0.45s;
    }
    
    .Line_4 {
      animation-delay: 0.6s;
    }
    
    .Line_5 {
      animation-delay: 0.75s;
    }
    
    .Line_6 {
      animation-delay: 0.9s;
    }
    
    .Line_7 {
      animation-delay: 1.05s;
    }
    
    .Line_8 {
      animation-delay: 1.2s;
    }
    
    .Line_9 {
      animation-delay: 1.35s;
    }
    
    @keyframes pulse {
      0% {
        transform: scale(1, 0.5)
      }
      50% {
        transform: scale(1, 1)
      }
      100% {
        transform: scale(1, 0.5)
      }
    }
    <div class="loader">
      <svg class="wave" id="wave" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 38.05">
            <path id="Line_1" class="t Line_1" data-name="Line 1" d="M0.91,15L0.78,15A1,1,0,0,0,0,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H0.91Z"/>
            <path id="Line_2" class="t Line_2" data-name="Line 2" d="M6.91,9L6.78,9A1,1,0,0,0,6,10V28a1,1,0,1,0,2,0s0,0,0,0V10A1,1,0,0,0,7,9H6.91Z"/>
            <path id="Line_3" class="t Line_3" data-name="Line 3" d="M12.91,0L12.78,0A1,1,0,0,0,12,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H12.91Z"/>
            <path id="Line_4" class="t Line_4" data-name="Line 4" d="M18.91,10l-0.12,0A1,1,0,0,0,18,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H18.91Z"/>
            <path id="Line_5" class="t Line_5" data-name="Line 5" d="M24.91,15l-0.12,0A1,1,0,0,0,24,16v6a1,1,0,0,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H24.91Z"/>
            <path id="Line_6" class="t Line_6" data-name="Line 6" d="M30.91,10l-0.12,0A1,1,0,0,0,30,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H30.91Z"/>
            <path id="Line_7" class="t Line_7" data-name="Line 7" d="M36.91,0L36.78,0A1,1,0,0,0,36,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H36.91Z"/>
            <path id="Line_8" class="t Line_8" data-name="Line 8" d="M42.91,9L42.78,9A1,1,0,0,0,42,10V28a1,1,0,1,0,2,0s0,0,0,0V10a1,1,0,0,0-1-1H42.91Z"/>
            <path id="Line_9" class="t Line_9" data-name="Line 9" d="M48.91,15l-0.12,0A1,1,0,0,0,48,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H48.91Z"/>
          </svg>
    </div>