Cara membalikkan animasi saat mouse keluar setelah hover

91

Jadi, dimungkinkan untuk memiliki animasi terbalik pada mouse out seperti:

.class{
   transform: rotate(0deg);

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

tetapi, saat menggunakan animasi @keyframes, saya tidak dapat membuatnya berfungsi, misalnya:

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

Apa solusi optimal, mengetahui bahwa saya memerlukan iterasi dan animasi itu sendiri?

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

Khaled
sumber
Bukankah lebih baik menggunakan transisi, seperti di sini - jsfiddle.net/HQFby ?
piatek
Jawabannya sudah diposting di stackoverflow. masukkan deskripsi tautan di sini
efek air

Jawaban:

61

Saya pikir jika Anda memiliki to, Anda harus menggunakan file from. Saya akan memikirkan sesuatu seperti:

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

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

Tentu saja harus sudah memeriksanya, tetapi saya merasa aneh bahwa Anda hanya menggunakan transformproperti karena CSS3 tidak sepenuhnya diterapkan di mana-mana. Mungkin akan bekerja lebih baik dengan pertimbangan berikut:

  • Chrome menggunakan @-webkit-keyframes, tidak perlu versi khusus
  • Safari digunakan @-webkit-keyframessejak versi 5+
  • Firefox digunakan @keyframessejak versi 16 (v5-15 digunakan @-moz-keyframes)
  • Opera menggunakan @-webkit-keyframesversi 15-22 (hanya menggunakan v12 @-o-keyframes)
  • Internet Explorer digunakan @keyframessejak versi 10+

EDIT:

Saya datang dengan biola itu:

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

Menggunakan kode minimal. Apakah itu mendekati apa yang Anda harapkan?

Xaltar
sumber
1
IE 10 mendukung animasi keyframe.
dlev
4
Itu memang mengembalikan transisi, tetapi masalahnya adalah jika mouse keluar sebelum akhir transisi hover kita mendapatkan "lompatan" ini. Setelah beberapa pencarian ternyata status elemen harus "dipertahankan" sehingga kita dapat kembali dari posisi rotasi akhir, untuk itu "animasi-isi-mode: maju;" dapat digunakan, tetapi sepertinya tidak berhasil.
Khaled
22
@Xaltar Saat pertama kali memuat aplikasi, animasi pertama diputar tanpa mengarahkan kursor ke kotak. Apakah ada cara untuk menghentikan animasi pemuatan awal agar tidak terjadi?
jlewkovich
3
Adakah yang menemukan solusi untuk animasi pertama yang diputar sendiri setelah menyegarkan? Agak penting.
pengguna2619824
2
Jawaban ini pada akhirnya tidak berguna jika Anda tidak dapat menekan animasi yang diputar pertama kali
NearHuscarl
20

Jauh lebih mudah daripada semua ini: Cukup transisikan properti yang sama pada elemen Anda

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

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

Jordan Lafland
sumber
4
Ya, tapi ini hanya akan berfungsi jika hanya satu properti yang diubah.
Marcus
4
@Marcustransition: border-color 0.3s, background-color 0.3s, color 0.3s;
scoots
4
Woah, CSS telah berkembang jauh sejak terakhir kali saya melakukan beberapa pemrograman web: D
Franz D.
5
dia bertanya tentang animasi !!
iKamy
18

Saya tidak berpikir ini dapat dicapai hanya dengan menggunakan animasi CSS. Saya berasumsi bahwa transisi CSS tidak memenuhi kasus penggunaan Anda, karena (misalnya) Anda ingin merangkai dua animasi bersama-sama, menggunakan beberapa penghentian, iterasi, atau dengan cara lain memanfaatkan animasi daya tambahan yang diberikan kepada Anda.

Saya tidak menemukan cara untuk memicu animasi CSS khususnya saat mouse-out tanpa menggunakan JavaScript untuk melampirkan kelas "over" dan "out". Meskipun Anda dapat menggunakan deklarasi CSS dasar yang memicu animasi saat: hover berakhir, animasi yang sama kemudian akan berjalan saat pemuatan halaman. Dengan menggunakan kelas "over" dan "out", Anda dapat membagi definisi menjadi deklarasi dasar (load) dan dua deklarasi pemicu animasi.

CSS untuk solusi ini adalah:

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

Dan menggunakan JavaScript (sintaks jQuery) untuk mengikat kelas ke acara:

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

membuat animasi terbalik agak berlebihan untuk masalah sederhana, apa yang Anda butuhkan

animation-direction: reverse

Namun ini tidak akan berfungsi dengan sendirinya karena spesifikasi animasi sangat buruk sehingga mereka lupa menambahkan cara untuk memulai ulang animasi jadi inilah cara Anda melakukannya dengan bantuan 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>

ctf0
sumber
4

Apakah Anda lebih baik hanya memiliki satu animasi, tetapi sebaliknya?

animation-direction: reverse
Andrew Lazarus
sumber
4
Saat ini hanya didukung di beberapa browser
Adam Hutchinson
Punya contoh?
MD Ashik
3

kita bisa menggunakan requestAnimationFrame untuk mengatur ulang animasi dan membalikkannya saat browser mengecat di frame berikutnya.

Juga gunakan penangan kejadian onmouseenter dan onmouseout untuk membalikkan arah animasi

Sesuai

Setiap rAF yang antri di event handler Anda akan dieksekusi dalam frame yang sama. Setiap rAF yang antri dalam rAF akan dieksekusi di frame berikutnya.

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>

Shishir Arora
sumber
0

Coba ini:

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

didukung di Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+

Ansipants
sumber
0

Telah mencoba beberapa solusi di sini, tidak ada yang bekerja dengan sempurna; kemudian Menelusuri web sedikit lagi, untuk menemukan GSAP di https://greensock.com/ (tunduk pada lisensi, tetapi cukup permisif); setelah Anda mereferensikan lib ...

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

... Anda bisa pergi:

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

Dan itu akan bekerja dengan sempurna.

Razvan_TK9692
sumber