123 votes

Redémarrer l'animation en CSS3 : y a-t-il un meilleur moyen que de supprimer l'élément ?

J'ai une animation CSS3 qui doit être redémarrée sur un clic. C'est une barre montrant combien de temps il reste. J'utilise la transformation scaleY(0) pour créer l'effet.

Maintenant, je dois redémarrer l'animation en restaurant la barre à scaleY(1) et la laisser passer à nouveau à scaleY(0). Ma première tentative de définir scaleY(1) a échoué car cela prend également 15 secondes pour la ramener à sa pleine longueur. Même si je change la durée à 0,1 seconde, je devrais retarder ou chaîner l'assignation de scaleY(0) pour que la barre se reconstitue complètement. Cela semble trop compliqué pour une tâche aussi simple.

J'ai également trouvé un astuce intéressante pour redémarrer l'animation en supprimant l'élément du document, puis en réinsérant un clone de celui-ci : http://css-tricks.com/restart-css-animation/

Cela fonctionne, mais y a-t-il un meilleur moyen de redémarrer une animation CSS? J'utilise Prototype et Move.js, mais je ne suis pas limité à eux.

152voto

user Points 1438

Pas besoin de temporisation, utilisez reflow pour appliquer le changement :

function reset_animation() {
  var el = document.getElementById('animated');
  el.style.animation = 'none';
  el.offsetHeight; /* déclencher le reflow */
  el.style.animation = null; 
}

#animated {
  position: absolute;
  top: 70px;
  width: 50px; height: 50px;
  background-color: black;
  animation: bounce 3s ease-in-out infinite;
}
@keyframes bounce {
  0% { left: 0; }
  50% { left: calc( 100% - 50px ); }
  100% { left: 0; }
}

Réinitialiser

99voto

Lea Verou Points 7869

Il suffit de définir la propriété animation via JavaScript sur "none" puis de définir une temporisation qui modifie la propriété en "", afin qu'elle hérite à nouveau du CSS.

Démonstration pour Webkit ici : http://jsfiddle.net/leaverou/xK6sa/ Cependant, gardez à l'esprit que dans une utilisation réelle, vous devriez également inclure -moz- (au moins).

27voto

V. Rubinetti Points 366

@ZachB's answer about the Web Animation API seems like "right"™ way to do this, but unfortunately seems to require that you define your animations through JavaScript. However it caught my eye and I found something related that's useful:

Element.getAnimations() and Document.getAnimations()

The support for them is pretty good as of 2021.

In my case, I wanted to restart all the animations on the page at the same time, so all I had to do was this:

const replayAnimations = () => {
  document.getAnimations().forEach((anim) => {
    anim.cancel();
    anim.play();
  });
};

But in most cases people will probably want to select which animation they restart...

getAnimations returns a bunch of CSSAnimation and CSSTransition objects that look like this:

animationName: "fade"
currentTime: 1500
effect: KeyframeEffect
  composite: "replace"
  pseudoElement: null
  target: path.line.yellow
finished: Promise {: CSSAnimation}
playState: "finished"
ready: Promise {: CSSAnimation}
replaceState: "active"
timeline: DocumentTimeline {currentTime: 135640.502}

# ...etc

So you could use the animationName and target properties to select just the animations you want (albeit a little circuitously).


EDIT

Here's a handy function that might be more compatible using just Document.getAnimations, with TypeScript thrown in for demonstration:

// restart animations on a given dom element
export const restartAnimations = (element: Element): void => {
  for (const animation of document.getAnimations()) {
    if (
      animation.effect instanceof KeyframeEffect &&
      element.contains(animation.effect.target)
    ) {
      animation.cancel();
      animation.play();
    }
  }
};

14voto

bigjosh Points 923
  1. Implémentez l'animation en tant que descripteur CSS
  2. Ajoutez le descripteur à un élément pour démarrer l'animation
  3. Utilisez une fonction gestionnaire d'événements animationend pour supprimer le descripteur lorsque l'animation est terminée afin qu'il soit prêt à être ajouté à nouveau la prochaine fois que vous souhaitez redémarrer l'animation.

HTML

    Animation se déroule ici

  function startanimation(element) {
    element.classList.add("animateDescriptor");
    element.addEventListener( "animationend",  function() {
      element.classList.remove("animateDescriptor");    
    } );
  }

    Cliquez pour animer le texte ci-dessus

CSS

@keyframes fadeinout {  
    from { color: #000000; }    
    25% {color: #0000FF; }  
    50% {color: #00FF00; }      
    75% {color: #FF0000; }  
    to { color : #000000; } 
}   

.animateDescriptor {    
    animation: fadeinout 1.0s;  
}   

Essayez-le ici: jsfiddle

8voto

Usama Majid Points 444

Vous pouvez également utiliser la propriété d'affichage, il suffit de définir l'affichage sur none.

display:none;

et la changer pour le mettre en bloc (ou toute autre propriété que vous souhaitez).

display:block;

en utilisant JavaScript.

et cela fonctionnera étonnamment bien.

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