How to stop and start animation using Javascript?

Viewed 148

I'm trying to stop this animation by using vanilla Javascript. I've tried to use the classList.remove property but it didn't work. When I opened the Chrome Dev Tool, it says it cannot read the property remove of undefined. I didn't understand what it's trying to say. Is there a way to remove the animation with vanilla JS and can someone show the solution?

const circle = document.getElementsByClassName('circle')
const red = document.getElementsByClassName('red')
const blue = document.getElementsByClassName('blue')
const yellow = document.getElementsByClassName('yellow')
const green = document.getElementsByClassName('green')
const button = document.getElementById('btn')

button.addEventListener('click', function() {
 circle.classList.remove('red');
 circle.classList.remove('blue');
 circle.classList.remove('yellow');
 circle.classList.remove('green');
})
* {
  box-sizing: border-box;

}

body {
  background: rgb(25, 21, 26);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  overflow: hidden;
}
.utilities {
  position: absolute;
  top : 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 1rem;
  display: flex;
  justify-content: center;
  align-items: center;
}

.utilities button {
  height: 50px;
  width: 100px;
  background: none;
  color: white;
  outline: none;
  border: 2px solid rgb(184, 134, 222);
  border-radius: 25px;
}

button:hover {
  background: rgb(184, 134, 222);
  cursor: pointer;
  transition: 0.5s ease;
}

.main {
  background:rgb(57, 53, 75);
  border-radius: 25px;
  height: 20vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

 .circle {
  display: flex;
  margin: 1rem;
  border-radius: 50%;
  height: 50px;
  width: 50px;
  background: rgba(0,0,0,0.3);
  position: relative;
  transition: 1s all ease;
}

.circle:before {
  position: absolute;
  content: '';
  height: 15px;
  width: 15px;
  left: 17.5px;
  top: -15px;
  margin: 0;
  padding: 0;
  display: block;
  background: rgb(68, 53, 73);
  border-radius: 2px;
  display:inline-block;
  border-bottom: 2px solid rgb(97, 81, 107);
}

.circle:after{
  position: absolute;
  content: "";
  top: -20px;
  left: 30px;
  position: absolute;
  width: 70px;
  height: 18.6666666667px;
  border-bottom: solid #222 2px;
  border-radius: 50%;
}

.circle:last-child::after{
  content: '';
  position: absolute;
  border: none;
}

.red {
 background-color: #c0392b;
  animation: glow-1 2s infinite;
}


.yellow {
 background-color: #f1c40f;
  animation: glow-2 2s infinite;
}

.blue {
 background-color: #64fcfe;
 animation: glow-3  2s infinite;
}

.green {
 background-color: #2ecc71;
  animation: glow-4 2s infinite;
}

@keyframes glow-1 {
  0%, 100% {
 box-shadow: 0 0 20px 5px #c0392b;
  }

  50% {
    box-shadow: none;
  }
}

@keyframes glow-2 {
  0%, 100% {
    box-shadow: none;
  }

  50% {
    box-shadow: 0 0 20px 5px #f1c40f;
  }
}

@keyframes glow-3 {
  0%, 100% {
    box-shadow: 0 0 20px 5px #74f7e1;
  }

  50% {
    box-shadow: none;
  }
}

@keyframes glow-4 {
  0%, 100% {
 box-shadow: none;
  }

  50% {
    box-shadow: 0 0 20px 5px #2ecc71;
  }
}
  <!DOCTYPE html>
  <html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>RayaLights</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="main">
      <div  class="circle red"></div>
      <div  class="circle yellow"></div>
      <div  class="circle blue"></div>
      <div  class="circle green"></div>
      <div  class="circle red"></div>
      <div  class="circle yellow"></div>
      <div  class="circle blue"></div>
      <div  class="circle green"></div>
    </div>
    <div class="utilities">
      <button id="btn">Stop</button>
    </div>


    <script src="app.js" charset="utf-8"></script>
  </body>
  </html>

3 Answers

The circle variable is referring to an HTMLCollection or a nodeList in older versions. Unfortunately you cannot apply a single operation to all the collection in vanilla JavaScript.

What you can do is to convert the collection into an array, then loop over it.

const circle = document.getElementsByClassName('circle')
...
const button = document.getElementById('btn')

button.addEventListener('click', function() {
 Array.from(circle).forEach((c) => {
   c.classList.remove('red');
   c.classList.remove('blue');
   c.classList.remove('yellow');
   c.classList.remove('green');
 });
});

Note that this will remove the colors at all, leaving the lamp bulbs empty.

If what you need is to only remove the glow animation, you would want to do use c.styles.animation = none;

const circle = document.getElementsByClassName('circle')
const pause = document.getElementById('pause')
const play = document.getElementById('play')
const stop = document.getElementById('stop')
var len = circle.length;

pause.addEventListener('click', function() {
  for (var i = 0; i < len; i++) {
    circle[i].style.animationPlayState = "paused";
    circle[i].style.WebkitAnimationPlayState = "paused";
  }
})
play.addEventListener('click', function() {
  for (var i = 0; i < len; i++) {
    circle[i].removeAttribute("style");
    circle[i].style.animationPlayState = "running";
    circle[i].style.WebkitAnimationPlayState = "running";
  }
})
stop.addEventListener('click', function() {
  for (var i = 0; i < len; i++) {
    circle[i].style.animation = "none";
  }
})
* {
  box-sizing: border-box;
}

body {
  background: rgb(25, 21, 26);
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  margin: 0;
  overflow: hidden;
}

.utilities {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  margin: 1rem;
  display: flex;
  justify-content: center;
  align-items: center;
}

.utilities button {
  height: 50px;
  width: 100px;
  background: none;
  color: white;
  outline: none;
  border: 2px solid rgb(184, 134, 222);
  border-radius: 25px;
  margin: 0 12px;
}

button:hover {
  background: rgb(184, 134, 222);
  cursor: pointer;
  transition: 0.5s ease;
}

.main {
  background: rgb(57, 53, 75);
  border-radius: 25px;
  height: 20vh;
  width: 100vw;
  display: flex;
  justify-content: center;
  align-items: center;
}

.circle {
  display: flex;
  margin: 1rem;
  border-radius: 50%;
  height: 50px;
  width: 50px;
  background: rgba(0, 0, 0, 0.3);
  position: relative;
  transition: 1s all ease;
}

.circle:before {
  position: absolute;
  content: '';
  height: 15px;
  width: 15px;
  left: 17.5px;
  top: -15px;
  margin: 0;
  padding: 0;
  display: block;
  background: rgb(68, 53, 73);
  border-radius: 2px;
  display: inline-block;
  border-bottom: 2px solid rgb(97, 81, 107);
}

.circle:after {
  position: absolute;
  content: "";
  top: -20px;
  left: 30px;
  position: absolute;
  width: 70px;
  height: 18.6666666667px;
  border-bottom: solid #222 2px;
  border-radius: 50%;
}

.circle:last-child::after {
  content: '';
  position: absolute;
  border: none;
}

.red {
  background-color: #c0392b;
  animation: glow-1 2s infinite;
}

.yellow {
  background-color: #f1c40f;
  animation: glow-2 2s infinite;
}

.blue {
  background-color: #64fcfe;
  animation: glow-3 2s infinite;
}

.green {
  background-color: #2ecc71;
  animation: glow-4 2s infinite;
}

@keyframes glow-1 {
  0%,
  100% {
    box-shadow: 0 0 20px 5px #c0392b;
  }
  50% {
    box-shadow: none;
  }
}

@keyframes glow-2 {
  0%,
  100% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0 20px 5px #f1c40f;
  }
}

@keyframes glow-3 {
  0%,
  100% {
    box-shadow: 0 0 20px 5px #74f7e1;
  }
  50% {
    box-shadow: none;
  }
}

@keyframes glow-4 {
  0%,
  100% {
    box-shadow: none;
  }
  50% {
    box-shadow: 0 0 20px 5px #2ecc71;
  }
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>RayaLights</title>
  <link rel="stylesheet" href="style.css">
</head>

<body>
  <div class="main">
    <div class="circle red"></div>
    <div class="circle yellow"></div>
    <div class="circle blue"></div>
    <div class="circle green"></div>
    <div class="circle red"></div>
    <div class="circle yellow"></div>
    <div class="circle blue"></div>
    <div class="circle green"></div>
  </div>
  <div class="utilities">
    <button id="pause">Pause</button>
    <button id="play">Play</button>
    <button id="stop">Stop</button>
  </div>

</body>

</html>

Change your addEventListener function to that:

button.addEventListener('click', function() {
  Array.prototype.forEach.call(circle, function(el) {
    el.style.animation = "none";
  });
})

https://jsfiddle.net/kv2qc50n/

Related