3

I'm having a really hard time figuring out how to start and stop an animation and reverse it.

I've assigned an animation to the element.style.animation property and from what I've read, I decided to use:

element.style.animationPlayState = "running";

to start it and:

element.style.animationPlayState = "paused";

to stop it.

But it reports "running" all the time.

Has anyone figured out how to start and stop an animation?

I have a related question here. The related part is this block of code that I use to make animations start and stop:

var style = element.style;
var animation = null;
style.animationPlayState = "paused";

if (style.animation) {
    animation = style.animation;
    style.animation = null;
    style.animationPlayState = "paused";
    element.addEventListener("animationend", function(event) {
        log("animation ended");
        element.removeEventListener("animationend", arguments.callee);
    });

    setTimeout(function() {
        style.animation = animation;
        style.animationPlayState = "paused";
        style.animationDirection = "reverse";
        style.animationPlayState = "running";
    }, 30);
}

The goal is simple:

  • Display a div when user presses button
  • div display is none, so set it to display: block
  • Fade in div
  • LATER - user presses a close button on div
  • Fade out div
  • After fade out set display: none

A method to do something like this:

fadeInElement(element)
fadeOutElement(element) 
TylerH
  • 20,799
  • 66
  • 75
  • 101
1.21 gigawatts
  • 16,517
  • 32
  • 123
  • 231
  • That link doesn't go to what you think it does. – Libra Oct 29 '19 at 21:50
  • you are always having `style.animationPlayState = "running";` at the last so it will always be running – Temani Afif Oct 29 '19 at 21:50
  • Can we see a bit more code? – Blackhole Oct 29 '19 at 21:51
  • Can you drop the code sample? – darligee Oct 29 '19 at 21:52
  • Add Webkit to it aswell. -webkit-animation-play-state: paused; animation-play-state: paused; I would love to see the code. – darligee Oct 29 '19 at 21:58
  • I've updated with some code – 1.21 gigawatts Oct 29 '19 at 21:59
  • Wonder why you opened another question... Anyway - what is the goal? do you want that when the animation paused it will fade out until it disappears? – A. Meshu Oct 29 '19 at 22:03
  • @A.Meshu I want to assign a fade in animation when the div appears and then I want NAY need to apply a fade out animation when the div disappears. I am choosing to reverse the fadein animation since it seemed the same amount of work. – 1.21 gigawatts Oct 29 '19 at 22:05
  • `reverse` will not do what you think it will do, full explanation here: https://stackoverflow.com/a/57333022/8620333 – Temani Afif Oct 29 '19 at 22:10
  • You can't animate display: block and none. You can however animate opacity. – Nathaniel Flick Oct 30 '19 at 01:14
  • It sounds like reverse reverses the animation but doesn't reset it's position? I was able to reset everything by setting the animation property to null but it didn't apply right away in my tests. I had to set a timeout. I updated the question with more info. With two methods fadeIn and fadeOut that make it easier to solve. – 1.21 gigawatts Oct 30 '19 at 14:00

3 Answers3

1

You can toggle classes with setTimeout, something like this maybe?

var theDiv = document.querySelectorAll('div')[0];
function showDiv() {
  theDiv.setAttribute('class', 'fadeIn');
  setTimeout(function(){ theDiv.style.opacity = '1'; }, 2000);
}
function hideDiv() {
  theDiv.removeAttribute('class');  
  theDiv.setAttribute('class', 'fadeOut');
  setTimeout(function(){ theDiv.style.opacity = '0' }, 2000);
}
div {height: 100px; height: 100px; background: black; opacity: 0;}
.fadeIn {animation: 2s fadein}
.fadeOut {animation: 2s fadeout}
@keyframes fadein {  to {opacity: 1;} }
@keyframes fadeout {  to {opacity: 0;} }
<div></div>
<button onclick="showDiv()">Show DIV</button>
<button onclick="hideDiv()">Hide DIV</button>

EDIT

I changed the above code to something like this, though i guess you are looking for more modern solution:

var theDiv = document.querySelectorAll('div')[0];
var anBtn = document.querySelector('#animateBtn');
var clicks = 1;
anBtn.addEventListener('click', function() {
  anBtn.disabled = true;
  if ((clicks/2) != (clicks/2).toFixed()) {
    showDiv();
  }
  else {
    hideDiv();
  }
  clicks += 1;
});
function showDiv() {
  theDiv.setAttribute('class', 'fadeIn');
  setTimeout(function(){ theDiv.style.opacity = '1'; anBtn.disabled = false; anBtn.textContent = 'Hide Div'; }, 2000);
}
function hideDiv() {
  theDiv.removeAttribute('class');
  theDiv.setAttribute('class', 'fadeOut');
  setTimeout(function(){ theDiv.style.opacity = '0'; anBtn.disabled = false; anBtn.textContent = 'Show Div'; }, 2000);
}
div {height: 100px; height: 100px; background: black; opacity: 0;}
.fadeIn {animation: 2s fadein}
.fadeOut {animation: 2s fadeout}
@keyframes fadein {  to {opacity: 1;} }
@keyframes fadeout {  to {opacity: 0;} }
<div></div>
<button id="animateBtn">Show DIV</button>
A. Meshu
  • 4,053
  • 2
  • 20
  • 34
1

With the Javascript Web Animations API you are able to use things like:

variable.play();
variable.pause();

it is a very powerful tool, here is the documentation

Also able to set the playback speed, including negative numbers which would play the animation in reverse. seems to address all of the issues that you brought up here.

Here is the polyfill which has proven to be very powerful, even works in IE

<script src="https://rawgit.com/web-animations/web-animations-js/master/web-animations.min.js"></script>
0

Attempting to solve my own question with help provided. This sort of seems to work. But seems to break the edit window console.log. Also seems to break after a few runs. Maybe unrelated.

var fadeInAnimation = "2s fadein";
var fadeOutAnimation = "2s fadein reverse";

function fadeIn() {
  var element = document.getElementById('box');
  //console.log("element", element);
  element.style.animation = fadeInAnimation;
  element.style.display = "block";
  //element.style.animationPlayState = "running";
}
function fadeOut() {
  var element = document.getElementById('box');
  element.style.display = "block";
  element.style.animationPlayState = "paused";
  element.style.animation = fadeOutAnimation;
  element.style.animationPlayState = "running";
  element.addEventListener("animationend", function(event) {
    element.style.display = "none";
console.log("animation ended");
    element.removeEventListener("animationend", arguments.callee);
  });
}
#box {
  width: 100px; 
  height: 100px; 
  background: red; 
  opacity: 1;
  display: none;
}

@keyframes fadein {  from {opacity: 0 } to {opacity: 1;} }
@keyframes fadeout {  from {opacity: 1 } to {opacity: 0;} }
<button onclick="fadeIn()">Fade In</button>
<button onclick="fadeOut()">Fade Out</button>

<div id="box">
</div>
1.21 gigawatts
  • 16,517
  • 32
  • 123
  • 231