悬停后如何在鼠标移出时反转动画


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

Answers:


61

我认为,如果您有to,则必须使用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确实支持关键帧动画。
dlev

4
那确实恢复了转换,但是问题是,如果鼠标在悬停转换结束之前移出,则会出现“跳转”。经过一番搜索之后,显然必须“保持”元素的状态,以便我们可以从末端旋转位置恢复到“动画填充模式:前进;”;可以使用,但似乎不起作用。
哈立德

21
@Xaltar首次加载应用程序时,第一个动画播放时不会悬停在正方形上。无论如何,有什么方法可以阻止初始加载动画的发生?
jlewkovich

2
是否有人找到刷新后自行播放的第一个动画的解决方案?有点重要。
user2619824

1
如果您不能抑制第一次播放动画,此答案最终将毫无用处
NearHuscarl

19

比这一切都容易得多:只需在元素上转换相同属性

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

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


4
是的,但这仅在更改了一个属性的情况下有效。
马库斯(Marcus)

4
@Marcustransition: border-color 0.3s, background-color 0.3s, color 0.3s;
酷航队

4
哇,自上次我进行一些Web编程以来,CSS已经走了很长一段路:D
Franz D.

5
他在问动画!
iKamy

18

我认为仅使用CSS动画是无法实现的。我假设CSS过渡无法满足您的用例,因为(例如)您想将两个动画链接在一起,使用多个停止,迭代或以其他方式利用授予您的其他强大动画。

我找不到在不使用JavaScript附加“ over”和“ out”类的情况下专门在鼠标移出时触发CSS动画的任何方法。尽管您可以使用基本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

在这里尝试了几种解决方案,没有任何问题。然后在网上搜索更多内容,以在https://greensock.com/上找到GSAP(需获得许可,但这是相当宽松的);一旦您引用库...

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

并且它将完美地工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.