So kehren Sie eine Animation mit der Maus nach dem Hover um


89

Es ist also möglich, eine umgekehrte Animation mit der Maus auszuführen, z. B.:

.class{
   transform: rotate(0deg);

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

Bei Verwendung der @ keyframes-Animation konnte ich sie jedoch nicht zum Laufen bringen, z.

.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);}
}

Was ist die optimale Lösung, wenn ich weiß, dass ich Iterationen und Animationen selbst benötigen würde?

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


Wäre es nicht besser, Übergänge wie hier zu verwenden - jsfiddle.net/HQFby ?
Piatek

Die Antwort ist bereits im Stackoverflow veröffentlicht.
Geben Sie

Antworten:


59

Ich denke, wenn Sie eine haben to, müssen Sie eine verwenden from. Ich würde an etwas denken wie:

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

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

Natürlich muss es bereits überprüft worden sein, aber ich fand es seltsam, dass Sie die transformEigenschaft nur verwenden, da CSS3 nicht überall vollständig implementiert ist. Vielleicht würde es mit den folgenden Überlegungen besser funktionieren:

  • Chrome verwendet @-webkit-keyframes, keine besondere Version erforderlich
  • Safari verwendet @-webkit-keyframesseit Version 5+
  • Firefox verwendet @keyframesseit Version 16 (v5-15 verwendet @-moz-keyframes)
  • Opera verwendet @-webkit-keyframesVersion 15-22 (nur Version 12 verwendet @-o-keyframes)
  • Internet Explorer verwendet @keyframesseit Version 10+

EDIT:

Ich habe mir diese Geige ausgedacht:

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

Verwenden von minimalem Code. Nähert es sich dem, was Sie erwartet haben?


1
IE 10 unterstützt Keyframe-Animationen.
dlev

4
Das kehrt zwar den Übergang zurück, aber das Problem ist, dass wir diesen "Sprung" bekommen, wenn die Maus vor dem Ende des Schwebeübergangs heraus ist. Nach einiger Suche muss der Status des Elements anscheinend "beibehalten" werden, damit wir von der Endrotationsposition für diesen "Animationsfüllmodus: vorwärts" zurückkehren können. kann verwendet werden, aber es scheint nicht zu funktionieren.
Khaled

21
@Xaltar Wenn Sie die App zum ersten Mal laden, wird die erste Animation abgespielt, ohne über dem Quadrat zu schweben. Gibt es überhaupt eine Möglichkeit, das Auftreten dieser anfänglichen Ladeanimation zu verhindern?
Jlewkovich

2
Hat jemand eine Lösung für die erste Animation gefunden, die nach dem Aktualisieren alleine abgespielt wird? Irgendwie wichtig.
user2619824

1
Diese Antwort ist letztendlich nutzlos, wenn Sie die Animation, die beim ersten Mal
abgespielt wird,

19

Es ist viel einfacher als all dies: Übertragen Sie einfach dieselbe Eigenschaft auf Ihr Element

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

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


4
Ja, aber das funktioniert nur, wenn nur eine Eigenschaft geändert wird.
Marcus

4
@ Marcustransition: border-color 0.3s, background-color 0.3s, color 0.3s;
Scoots

4
Woah, CSS hat einen langen Weg zurückgelegt, seit ich das letzte Mal Webprogrammierung gemacht habe: D
Franz D.

5
er fragt nach Animation !!
iKamy

18

Ich denke nicht, dass dies nur mit CSS-Animationen möglich ist. Ich gehe davon aus, dass CSS-Übergänge Ihren Anwendungsfall nicht erfüllen, weil Sie (zum Beispiel) zwei Animationen miteinander verketten, mehrere Stopps und Iterationen verwenden oder auf andere Weise die zusätzlichen Leistungsanimationen ausnutzen möchten, die Sie erhalten.

Ich habe keine Möglichkeit gefunden, eine CSS-Animation speziell beim Mouse-Out auszulösen, ohne JavaScript zum Anhängen von "Over" - und "Out" -Klassen zu verwenden. Obwohl Sie die Basis-CSS-Deklaration verwenden können, um eine Animation auszulösen, wenn der Hover endet, wird dieselbe Animation beim Laden der Seite ausgeführt. Mit den Klassen "over" und "out" können Sie die Definition in die Basisdeklaration (load) und die beiden Animationsauslöserdeklarationen aufteilen.

Das CSS für diese Lösung wäre:

.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);
    }
}

Und mit JavaScript (jQuery-Syntax), um die Klassen an die Ereignisse zu binden:

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

7

Das Erstellen einer umgekehrten Animation ist ein Overkill für ein einfaches Problem. Was Sie brauchen, ist

animation-direction: reverse

Dies funktioniert jedoch nicht von alleine, da die Animationsspezifikation so umfangreich ist, dass sie vergessen haben, eine Möglichkeit zum Neustart der Animation hinzuzufügen. Hier erfahren Sie, wie Sie dies mit Hilfe von js tun

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>



2

Wir können requestAnimationFrame verwenden, um die Animation zurückzusetzen und umzukehren, wenn der Browser im nächsten Frame malt.

Verwenden Sie auch die Ereignishandler onmouseenter und onmouseout, um die Animationsrichtung umzukehren

Wie per

Alle in Ihren Ereignishandlern in die Warteschlange gestellten rAFs werden im selben Frame ausgeführt. Alle in einem rAF in die Warteschlange gestellten rAFs werden im nächsten Frame ausgeführt.

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>


0

Versuche dies:

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

unterstützt in Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+


0

Habe hier mehrere Lösungen ausprobiert, nichts hat einwandfrei funktioniert; suchte dann ein bisschen mehr im Internet, um GSAP unter https://greensock.com/ zu finden (lizenzpflichtig, aber ziemlich freizügig ); Sobald Sie auf die Bibliothek verweisen ...

 <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.2.4/gsap.min.js"></script>

... du kannst gehen:

  var el = document.getElementById('divID');    

  // create a timeline for this element in paused state
  var tl = new TimelineMax({paused: true});

  // create your tween of the timeline in a variable
  tl
  .set(el,{willChange:"transform"})
  .to(el, 1, {transform:"rotate(60deg)", ease:Power1.easeInOut});

  // store the tween timeline in the javascript DOM node
  el.animation = tl;

  //create the event handler
  $(el).on("mouseenter",function(){
    //this.style.willChange = 'transform';
    this.animation.play();
  }).on("mouseleave",function(){
     //this.style.willChange = 'auto';
    this.animation.reverse();
  });

Und es wird einwandfrei funktionieren.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.