132 votes

Comment inverser une animation lors de la sortie de la souris après le survol d'un objet ?

Il est donc possible d'avoir une animation inverse lors de la sortie de la souris, par exemple :

.class{
   transform: rotate(0deg);

}
.class:hover{
   transform: rotate(360deg);
}

mais, lorsque j'utilise l'animation @keyframes, je n'ai pas réussi à la faire fonctionner, par ex :

.class{
   animation-name: out;
   animation-duration:2s;

}
.class:hover{
   animation-name: in;
   animation-duration:5s;
   animation-iteration-count:infinite;

}
@keyframe in{
    to {transform: rotate(360deg);}
}

@keyframe out{
    to {transform: rotate(0deg);}
}

Quelle est la solution optimale, sachant que j'aurais besoin d'itérations et de l'animation elle-même ?

http://jsfiddle.net/khalednabil/eWzBm/

77voto

Xaltar Points 612

Je pense que si vous avez un to vous devez utiliser un from . Je penserais à quelque chose comme :

@keyframe in {
    from: transform: rotate(0deg);
    to: transform: rotate(360deg);
}

@keyframe out {
    from: transform: rotate(360deg);
    to: transform: rotate(0deg);
}

Bien sûr, vous avez déjà dû le vérifier, mais j'ai trouvé étrange que vous n'utilisiez que l'option transform puisque CSS3 n'est pas entièrement mis en œuvre partout. Peut-être cela fonctionnerait-il mieux avec les considérations suivantes :

  • Chrome utilise @-webkit-keyframes aucune version particulière n'est nécessaire
  • Safari utilise @-webkit-keyframes depuis la version 5+.
  • Firefox utilise @keyframes depuis la version 16 (v5-15 utilisée @-moz-keyframes )
  • Opera utilise @-webkit-keyframes version 15-22 (seulement v12 utilisée @-o-keyframes )
  • Internet Explorer utilise @keyframes à partir de la version 10

EDIT :

C'est moi qui ai inventé ce violon :

http://jsfiddle.net/JjHNG/35/

Utilisation d'un code minimal. Est-ce que cela correspond à ce que vous attendiez ?

47voto

Jordan Lafland Points 509

C'est beaucoup plus facile que tout ça : Il suffit de faire passer la même propriété sur votre élément

.earth { width:  0.92%;    transition: width 1s;  }
.earth:hover { width: 50%; transition: width 1s;  }

https://codepen.io/lafland/pen/MoEaoG

28voto

Giles Copp Points 331

Je ne pense pas que cela soit réalisable en utilisant uniquement des animations CSS. Je suppose que les transitions CSS ne pas remplissez votre cas d'utilisation, parce que (par exemple) vous voulez enchaîner deux animations, utiliser des arrêts multiples, des itérations, ou exploiter d'une autre manière la puissance supplémentaire que les animations vous accordent.

Je n'ai pas trouvé de moyen de déclencher une animation CSS spécifiquement à la sortie de la souris sans utiliser JavaScript pour attacher les classes "over" et "out". Bien que vous puissiez utiliser la déclaration CSS de base pour déclencher une animation à la fin du :hover, cette même animation s'exécutera ensuite au chargement de la page. En utilisant les classes "over" et "out", vous pouvez diviser la définition en une déclaration de base (load) et deux déclarations de déclenchement d'animation.

Le CSS de cette solution serait :

.class {
    /* base element declaration */
}
.class.out {
   animation-name: out;
   animation-duration:2s;

}
.class.over {
   animation-name: in;
   animation-duration:5s;
   animation-iteration-count:infinite;
}
@keyframes in {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
}
@keyframes out {
    from {
        transform: rotate(360deg);
    }
    to {
        transform: rotate(0deg);
    }
}

Et en utilisant JavaScript (syntaxe jQuery) pour lier les classes aux événements :

$(".class").hover(
    function () {
        $(this).removeClass('out').addClass('over');
    },
    function () {
        $(this).removeClass('over').addClass('out');
    }
);

18voto

ctf0 Points 3640

Créer une animation inversée est un peu exagéré pour un problème simple. Ce dont vous avez besoin :

animation-direction: reverse

Cependant, cela ne fonctionnera pas tout seul car l'animation spec a oublié d'ajouter un moyen de redémarrer l'animation, voici donc comment faire avec l'aide de JS

let item = document.querySelector('.item')

// play normal
item.addEventListener('mouseover', () => {
  item.classList.add('active')
})

// play in reverse
item.addEventListener('mouseout', () => {
  item.style.opacity = 0 // avoid showing the init style while switching the 'active' class

  item.classList.add('in-active')
  item.classList.remove('active')

  // force dom update
  setTimeout(() => {
    item.classList.add('active')
    item.style.opacity = ''
  }, 5)

  item.addEventListener('animationend', onanimationend)
})

function onanimationend() {
  item.classList.remove('active', 'in-active')
  item.removeEventListener('animationend', onanimationend)
}

@keyframes spin {
  0% {
    transform: rotateY(0deg);
  }
  100% {
    transform: rotateY(180deg);
  }
}

div {
  background: black;
  padding: 1rem;
  display: inline-block;
}

.item {
  /* because span cant be animated */
  display: block;
  color: yellow;
  font-size: 2rem;
}

.item.active {
  animation: spin 1s forwards;
  animation-timing-function: ease-in-out;
}

.item.in-active {
  animation-direction: reverse;
}

<div>
  <span class="item">ABC</span>
</div>

6voto

Shishir Arora Points 21

Nous pouvons utiliser requestAnimationFrame pour réinitialiser l'animation et l'inverser lorsque le navigateur peint dans le cadre suivant.

Utilisez également les gestionnaires d'événements onmouseenter et onmouseout pour inverser la direction de l'animation.

Conformément à

Tous les rAFs mis en file d'attente dans vos gestionnaires d'événements seront exécutés dans le même processus d'exécution. cadre. Tous les rAFs mis en file d'attente dans un rAF seront exécutés dans le cadre suivant.

function fn(el, isEnter) {
  el.className = "";
   requestAnimationFrame(() => {
    requestAnimationFrame(() => {
        el.className = isEnter? "in": "out";
    });
  });  
}

.in{
  animation: k 1s forwards;
}

.out{
  animation: k 1s forwards;
  animation-direction: reverse;
}

@keyframes k
{
from {transform: rotate(0deg);}
to   {transform: rotate(360deg);}
}

<div style="width:100px; height:100px; background-color:red" 
  onmouseenter="fn(this, true)"
   onmouseleave="fn(this, false)"  
     ></div>

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