web-dev-qa-db-fra.com

Comment inverser une animation après le survol de la souris

Ainsi, il est possible d'avoir une animation inversée à la souris telle que:

.class{
   transform: rotate(0deg);

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

mais, en utilisant l'animation @keyframes, je ne pouvais pas le faire fonctionner, par exemple:

.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/

73
Khaled

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, je dois déjà l'avoir vérifié, mais j'ai trouvé étrange que vous n'utilisiez que la propriété transform, car CSS3 n'est pas complètement implémenté partout. Peut-être que cela fonctionnerait mieux avec les considérations suivantes:

  • Chrome utilise @-webkit-keyframes, Aucune version particulière n'est requise
  • Safari utilise @-webkit-keyframes Depuis la version 5+
  • Firefox utilise @keyframes Depuis la version 16 (v5-15 utilisé @-moz-keyframes)
  • Opera utilise @-webkit-keyframes Version 15-22 (seule la v12 utilisait @-o-keyframes)
  • Internet Explorer utilise @keyframes Depuis la version 10+

MODIFIER :

Je suis venu avec ce violon:

http://jsfiddle.net/jjHNG/35/

Utiliser un code minimal. Est-ce que vous approchez de ce que vous attendiez?

51
Xaltar

Je ne pense pas que cela soit réalisable en utilisant uniquement des animations CSS. Je suppose que les transitions CSS ne pas répondent à votre cas d'utilisation, parce que (par exemple) vous souhaitez enchaîner deux animations, utiliser plusieurs arrêts, itérations ou exploiter d'une autre manière l'exploitation des autorisations d'alimentation supplémentaires accordées. toi.

Je n'ai trouvé aucun moyen de déclencher une animation CSS spécifiquement sur 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 survol, cette même animation s’exécutera ensuite au chargement de la page. En utilisant les classes "over" et "out", vous pouvez scinder la définition en déclaration de base (chargement) et en deux déclarations de déclencheur d'animation.

Le CSS pour 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');
    }
);
13
Giles Copp

C'est beaucoup plus facile que tout ça: il suffit de transférer 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

13
Jordan Lafland

créer une animation inversée est un peu excessif à un problème simple, ce dont vous avez besoin

animation-direction: reverse

cependant, cela ne fonctionnera pas tout seul, car les spécifications de l'animation sont si volumineuses qu'elles ont oublié d'ajouter un moyen de redémarrer l'animation. Voici comment procéder à 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>
6
ctf0

Seriez-vous mieux d'avoir une seule animation, mais l'inverser?

animation-direction: reverse
5
Andrew Lazarus

nous pouvons utiliser requestAnimationFrame pour réinitialiser l'animation et l'inverser lorsque le navigateur affiche l'image suivante.

Utilisez également les gestionnaires d’événements onmouseenter et onmouseout pour inverser le sens de l’animation.

comme par

Tous les rAF en file d'attente dans vos gestionnaires d'événements seront exécutés dans le même cadre. Tous les RAF en file d'attente dans un RAF seront exécutés dans la trame suivante.

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>
1
Shishir Arora

Essaye ça:

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

supporté dans Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+

0
Ansipants