Run css animation back and forth on clicks
I would consider using the animation-play-state
property and also use infinite
and alternate
. The idea is to run the animation and stop it when it ends, then run it again and so on:
const div = document.querySelector('.target')
div.addEventListener('click', (e) => {
div.classList.add('play');
setTimeout(function() {
div.classList.remove('play');
},2000)
})
.target {
width: 100px;
height: 100px;
background-color: gray;
cursor: pointer;
animation: action 2s linear alternate infinite;
animation-play-state:paused;
}
.play {
animation-play-state:running;
}
@keyframes action {
0% {
background-color: gray;
}
50% {
background-color: red;
}
100% {
background-color: green;
}
}
<div class="target">
</div>
Handling this kind of on/off changes with animations is always tricky, and it is very difficult to handle the repeated changes smoothly and seamlessly.
For your case, I would suggest to change it to a single transition. Browser handle much better the on/off part in this case. To achieve a double change in the background color with a transition, create a gradient with 3 colors, and change the gradient position:
const div = document.querySelector('.test')
div.addEventListener('click', (e) => {
div.classList.toggle('play');
})
.test {
border: solid 1px black;
margin: 10px;
height: 100px;
width: 100px;
background-image: linear-gradient(gray 0%, gray 20%, blue 40%, blue 60%,
red 80%, red 100%);
background-size: 100% 9000%;
background-repeat: no-repeat;
background-position: center top;
transition: background-position .3s;
}
.play {
background-position: center bottom;
}
<div class="test">
</div>