61 votes

Comment mettre en pause et reprendre une animation CSS3 à l'aide de JavaScript ?

J'ai essayé de chercher sur Google et sur ce forum une solution à mon problème, mais sans succès jusqu'à présent. Je voudrais mettre en pause mon animation CSS3 (diaporama d'images) en cliquant sur une image et reprendre la même animation en cliquant sur une image.

Je sais comment mettre le diaporama en pause et j'ai également pu le reprendre une fois, mais il cesse de fonctionner si on essaie de le mettre en pause et de le reprendre plus d'une fois. Voici à quoi ressemble mon code :

<!DOCTYPE html>
<html>

<head>
<title></title>
<style type="text/css">
.pic {
    position: absolute;
    opacity: 0;
}

#pic1 {
    -webkit-animation: pic1 4s infinite linear;
}

#pic2 {
    -webkit-animation: pic2 4s infinite linear;
}

@-webkit-keyframes pic1 {
    0%   {opacity: 0;}
    5%   {opacity: 1;}
    45%  {opacity: 1;}
    50%  {opacity: 0;}
    100% {opacity: 0;}
}

@-webkit-keyframes pic2 {
    0%   {opacity: 0;}
    50%  {opacity: 0;}
    55%  {opacity: 1;}
    95%  {opacity: 1;}
    100% {opacity: 0;}
}
</style>

<script type="text/javascript">
function doStuff(){
    var pic1 = document.getElementById("pic1");
    var pic2 = document.getElementById("pic2");

    pic1.style.webkitAnimationPlayState="paused";
    pic2.style.webkitAnimationPlayState="paused";

    pic1.onclick = function(){
        pic1.style.webkitAnimationPlayState="running";
        pic2.style.webkitAnimationPlayState="running";
    }

    pic2.onclick = function(){
        pic1.style.webkitAnimationPlayState="running";
        pic2.style.webkitAnimationPlayState="running";
    }
}
</script>
</head>  

<body>
    <img id="pic1" class="pic" src="photo1.jpg" />
    <img id="pic2" class="pic" src="photo2.jpg" onclick="doStuff()" />
</body>                                                                

</html>

Je ne veux pas utiliser de bibliothèques JS (par exemple jQuery) ou toute autre solution externe.

Je pense que mes fonctions dans doStuff sont toujours en cours et c'est pourquoi pause y resume ne fonctionne qu'une seule fois.

Existe-t-il un moyen d'effacer ces fonctions après les avoir cliquées une fois ? Ou bien est-ce que j'essaie de le faire d'une manière totalement erronée ? Toute aide est la bienvenue :)

164voto

Luis Hijarrubia Points 611

Je trouve plus facile de le faire avec une classe css. Avec elle, vous pouvez utiliser des préfixes pour chaque navigateur.

.paused{
    -webkit-animation-play-state:paused;
    -moz-animation-play-state:paused;
    -o-animation-play-state:paused; 
    animation-play-state:paused;
}

Il vous suffit ensuite d'ajouter ou de supprimer cette classe à votre élément animé pour mettre en pause ou reprendre l'animation.

6 votes

C'est une meilleure solution et devrait être la réponse acceptée, beaucoup plus propre.

0 votes

Merci pour cette réponse Luis Hijarrubia mais je cherchais un moyen de le faire avec JS. Cela pourrait être mieux pour d'autres cas mais pas pour le mien.

0 votes

@nq1 CSS est la manière correcte de le faire. Utilisez JavaScript pour ajouter la classe. Cette réponse est également compatible avec tous les navigateurs, contrairement à la réponse acceptée.

36voto

Šime Vidas Points 59994

Voici une solution utilisant le javascript :

var imgs = document.querySelectorAll('.pic');

for (var i = 0; i < imgs.length; i++) {
  imgs[i].onclick = toggleAnimation;
  imgs[i].style.webkitAnimationPlayState = 'running';
}

function toggleAnimation() {
  var style;
  for (var i = 0; i < imgs.length; i++) {
    style = imgs[i].style;
    if (style.webkitAnimationPlayState === 'running') {
      style.webkitAnimationPlayState = 'paused';
      document.body.className = 'paused';
    } else {
      style.webkitAnimationPlayState = 'running';
      document.body.className = '';
    }
  }
}

.pic {
  position: absolute;
  opacity: 0;
}

#pic1 {
  -webkit-animation: pic1 4s infinite linear;
}

#pic2 {
  -webkit-animation: pic2 4s infinite linear;
}

@-webkit-keyframes pic1 {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  45% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes pic2 {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0;
  }
  55% {
    opacity: 1;
  }
  95% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

.paused {
  background-color: #ddd;
}

<img id="pic1" class="pic" src="http://placehold.it/200x200/ff0000/ffffff">
<img id="pic2" class="pic" src="http://placehold.it/200x200/ff00ff/ffffff">

Solution jQuery (plus courte et plus lisible) :

var imgs = $('.pic'),
  playState = '-webkit-animation-play-state';

imgs.click(function() {
  imgs.css(playState, function(i, v) {
    return v === 'paused' ? 'running' : 'paused';
  });
  $('body').toggleClass('paused', $(this).css(playState) === 'paused');
});

.pic {
  position: absolute;
  opacity: 0;
}

#pic1 {
  -webkit-animation: pic1 4s infinite linear;
}

#pic2 {
  -webkit-animation: pic2 4s infinite linear;
}

@-webkit-keyframes pic1 {
  0% {
    opacity: 0;
  }
  5% {
    opacity: 1;
  }
  45% {
    opacity: 1;
  }
  50% {
    opacity: 0;
  }
  100% {
    opacity: 0;
  }
}

@-webkit-keyframes pic2 {
  0% {
    opacity: 0;
  }
  50% {
    opacity: 0;
  }
  55% {
    opacity: 1;
  }
  95% {
    opacity: 1;
  }
  100% {
    opacity: 0;
  }
}

.paused {
  background-color: #ddd;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<img id="pic1" class="pic" src="http://placehold.it/200x200/ff0000/ffffff">
<img id="pic2" class="pic" src="http://placehold.it/200x200/ff00ff/ffffff">

0 votes

Est-il possible de détecter le temps restant lors d'une pause ? Thx

9voto

tensai Points 30

Il s'agit de prolonger la réponse donnée par Luis Hijarrubia.

.pause {
   -webkit-animation-play-state: paused !important; 
   -moz-animation-play-state: paused !important; 
   -o-animation-play-state: paused !important;
    animation-play-state: paused !important;
}

Dans ma page, je déclenchais le changement de classe à partir de l'élément parent. Tout ce que je voulais faire était de faire pivoter l'image à l'intérieur. Mais il semble que, comme je n'utilisais pas le survol, l'ajout de la classe en pause ne faisait aucune différence dans l'état de l'animation.

L'utilisation de !important a permis de faire en sorte que ces valeurs soient écrasées par les nouvelles valeurs CSS ajoutées.

2 votes

Pour clarifier, cela est dû à la spécificité des css. Un script qui ajoute la propriété directement à l'élément (comme la réponse de Sime) n'aurait pas ce problème car les styles "en ligne" remplacent les règles des feuilles de style par défaut. developer.mozilla.org/fr/US/docs/Web/CSS/Spécificité

0 votes

Il s'agit d'un problème spécifique causé par votre HTML et votre CSS. Au mieux, il s'agit d'un commentaire, qui ne répond pas à la question posée.

0 votes

Je suis venu ici pour poster cette réponse si elle n'a pas été postée. Dans mon cas, j'avais besoin de mettre en pause plusieurs animations simultanées et j'ai trouvé que cette méthode était la plus simple. Elle vous permet également d'ajouter des effets tels que .pause:hover si cela répond à un besoin.

1voto

snm-yah Points 2067
var e = document.getElementsById("Your_Id");

e.addEventListener("animationstart", listener, false);
e.addEventListener("animationend", listener, false);
e.addEventListener("animationiteration", listener, false);

function listener(e) {  alert("Your POSITION parameter:" + .target.style.position);
  switch(e.type) {
    case "animationstart":
      d = "Started: elapsed time is " + e.elapsedTime;
      break;
    case "animationend":
      d = "Ended: elapsed time is " + e.elapsedTime;
      break;
    case "animationiteration":
      d= "New loop started at time " + e.elapsedTime;  alert("pausing for 1 seconddddddd!!!!!!!"); e.target.style.animationPlayState = "paused";        window.setTimeout(function(){e.target.style.animationPlayState = "running";}, 1000);
      break;
  }
}

-1voto

user40521 Points 21

Je ne l'ai pas testé mais peut-être quelque chose comme ça ?

<!DOCTYPE html>
<html>
<head>
<title></title>
<style type="text/css">
.pic {   position: absolute;opacity: 0;  }
.pic1 {  -webkit-animation: pic1 4s infinite linear;   }
.pic2 {  -webkit-animation: pic2 4s infinite linear;   }
@-webkit-keyframes pic1 {  0%   {opacity: 0;}
                           5%   {opacity: 1;}
                           45%  {opacity: 1;}
                           50%  {opacity: 0;}
                           100% {opacity: 0;}    }
@-webkit-keyframes pic2 {  0%   {opacity: 0;}
                           50%  {opacity: 0;}
                           55%  {opacity: 1;}
                           95%  {opacity: 1;}
                           100% {opacity: 0;}    }
</style>
<script type="text/javascript">
function doStuff(){
    var pic1 = document.getElementById("pic1");
    var pic2 = document.getElementById("pic2");

    pic1.className="pic paused";
    pic2.className="pic paused";

    pic1.onclick = function(){
       pic1.className="pic pic1";
       pic2.className="pic pic2";
    }
    pic2.onclick = function(){
       pic1.className="pic pic1";
       pic2.className="pic pic2";
    }
}
</script>
</head>  
<body>
    <img id="pic1" class="pic pic1" src="photo1.jpg" />
    <img id="pic2" class="pic pic2" src="photo2.jpg" onclick="doStuff()" />
</body>                                                                 
</html>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X