Як змінити анімацію на миші після наведення


91

Отже, можна мати зворотну анімацію на миші, наприклад:

.class{
   transform: rotate(0deg);

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

але, використовуючи анімацію @keyframes, я не міг змусити її працювати, наприклад:

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

Яке оптимальне рішення, знаючи, що мені потрібні ітерації та сама анімація?

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


Чи не краще було б використовувати переходи, як тут - jsfiddle.net/HQFby ?
piatek

Відповідь уже розміщено на stackoverflow. введіть тут опис посилання
watereffect

Відповіді:


61

Я думаю, що якщо у вас є a to, ви повинні використовувати a from. Я б подумав про щось на зразок:

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

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

Звичайно, це вже потрібно було перевірити, але мені здалося дивним, що ви використовуєте лише transformвластивість, оскільки CSS3 не повною мірою реалізований. Можливо, це було б краще з наступними міркуваннями:

  • Chrome використовує @-webkit-keyframes, не потрібна конкретна версія
  • Safari використовує @-webkit-keyframesз версії 5+
  • Firefox використовує @keyframesз версії 16 (використовується v5-15 @-moz-keyframes)
  • Opera використовує @-webkit-keyframesверсію 15-22 (використовується лише v12 @-o-keyframes)
  • Internet Explorer використовує @keyframesз версії 10+

РЕДАГУВАТИ:

Я придумав цю скрипку:

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

Використання мінімального коду. Чи наближається воно до того, що ви очікували?


1
IE 10 підтримує анімацію ключових кадрів.
длев

4
Це повертає перехід, але проблема полягає в тому, що якщо миша вийшла до кінця переходу при наведенні, ми отримаємо цей "стрибок". Після деякого пошуку, очевидно, стан елемента повинен бути "збереженим", щоб ми могли повернутися з кінцевого положення обертання, для того "режим анімації-заповнення: вперед;" можна використовувати, але, здається, це не працює.
Халед

22
@Xaltar При першому завантаженні програми перша анімація відтворюється, не наводячи курсор на квадрат. Чи можна якось зупинити цю початкову анімацію навантаження?
jlewkovich

3
Хтось знайшов рішення для першої анімації, яка відтворюється самостійно після оновлення? Вид важливий.
user2619824

2
Ця відповідь, зрештою, марна, якщо ви не можете придушити анімацію, яка відтворюється вперше
NearHuscarl

20

Це набагато простіше, ніж усе це: просто перекладіть одну і ту ж властивість на ваш елемент

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

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


4
Так, але це спрацює, лише якщо буде змінено лише одне властивість.
Маркус

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

4
Woah, CSS пройшов довгий шлях з часу останнього разу, коли я займався веб-програмуванням: D
Franz D.

5
він запитує про анімацію !!
iKamy

18

Я не думаю, що цього можна досягти, використовуючи лише анімацію CSS. Я припускаю, що переходи CSS не відповідають вашому випадку використання, оскільки (наприклад) ви хочете об'єднати дві анімації разом, використовувати кілька зупинок, ітерацій або якимось іншим чином використовувати додаткові потужності, які вам дають анімації.

Я не знайшов жодного способу активувати CSS-анімацію спеціально при наведенні миші без використання JavaScript для приєднання класів "over" та "out". Хоча ви можете використовувати базову декларацію CSS, що запускає анімацію, коли закінчується: hover, ця сама анімація буде запускатися при завантаженні сторінки. За допомогою класів "over" та "out" ви можете розділити визначення на базову (завантажувальну) декларацію та дві декларації тригера анімації.

CSS для цього рішення буде таким:

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

І використання JavaScript (синтаксис jQuery) для прив’язки класів до подій:

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

8

створення зворотної анімації - це якось надмірне вирішення простої проблеми, що вам потрібно

animation-direction: reverse

однак це не працює самостійно, оскільки специфікація анімації настільки дамп, що вони забули додати спосіб перезапустити анімацію, тому ось як ви це робите за допомогою 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>



3

ми можемо використовувати requestAnimationFrame, щоб скинути анімацію та повернути її назад, коли браузер малює в наступному кадрі.

Також використовуйте обробники подій onmouseenter та onmouseout, щоб змінити напрямок анімації

Згідно

Будь-які rAF, що стоять у черзі у ваших обробниках подій, будуть виконуватися в тому ж кадрі. Будь-які rAF, що стоять у черзі у rAF, будуть виконані в наступному кадрі.

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

Спробуйте це:

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

підтримується у Firefox 5+, IE 10+, Chrome, Safari 4+, Opera 12+


0

Спробував тут кілька рішень, нічого не працювало бездоганно; потім ще трохи пошукайте в Інтернеті, щоб знайти GSAP на https://greensock.com/ (за умови ліцензії, але це досить дозвільно); як тільки ви посилаєтесь на lib ...

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

... Ви можете піти:

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

І це буде працювати бездоганно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.