120

因此,可以在鼠标移出时进行反向动画,例如:

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

4

10 回答 10

70

我认为如果你有一个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 used @-moz-keyframes)
  • Opera 使用@-webkit-keyframes版本 15-22(仅使用 v12 @-o-keyframes
  • Internet Explorer@keyframes从版本 10+ 开始使用

编辑 :

我想出了那个小提琴:

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

使用最少的代码。是否接近您的预期?

于 2013-05-13T07:27:57.867 回答
34

它比这一切都容易:只需转换元素上的相同属性

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

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

于 2017-06-25T01:29:29.520 回答
23

我认为仅使用 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');
    }
);
于 2013-07-13T02:51:12.900 回答
15

创建一个反向动画对于一个简单的问题来说有点矫枉过正。你需要的是:

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>

于 2018-09-08T19:02:01.163 回答
6

我们可以使用 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>

于 2019-06-01T23:29:37.663 回答
3

你会不会更好只有一个动画,但让它反转?

animation-direction: reverse
于 2014-09-12T11:11:15.113 回答
2

将转换与转换结合使用对我来说完美无缺:

.ani-grow {
    -webkit-transition: all 0.5s ease; 
    -moz-transition: all 0.5s ease; 
    -o-transition: all 0.5s ease; 
    -ms-transition: all 0.5s ease; 
    transition: all 0.5s ease; 
}
.ani-grow:hover {
    transform: scale(1.01);
}
于 2021-02-13T20:26:34.750 回答
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+

于 2013-05-13T07:32:27.607 回答
0

我已经将一个带有纯 CSS 修复的 CodePen 和一个带有 2 行 jQuery 的 CodePen 放在一起来修复页面加载问题。继续阅读以了解更简单版本的 2 个解决方案。

https://codepen.io/MateoStabio/pen/jOVvwrM

如果您正在搜索如何仅使用 CSS 执行此操作,Xaltar 的答案很简单、直接,并且是正确的解决方案。唯一的缺点是鼠标移出的动画将在页面加载时播放。发生这种情况是因为要使这项工作正常进行,您需要使用 OUT 动画和:hoverIN 动画来设置元素的样式。

svg path{
    animation: animateLogoOut 1s;
}
svg:hover path{
    animation: animateLogoIn 1s;
}

@keyframes animateLogoIn {
    from {stroke-dashoffset: -510px;}
    to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
    from {stroke-dashoffset: 0px;}
    to {stroke-dashoffset: -510px;}
}

有些人发现这个解决方案在页面加载时没有用。对我来说,这是完美的解决方案。但是我用这两种解决方案制作了一个 Codepen,因为在不久的将来我可能会需要它们。

如果您不希望页面加载时出现 CSS 动画,则需要使用一个很小的 ​​JS 脚本,仅在元素第一次悬停后使用 OUT 动画设置元素的样式。我们将通过向.wasHovered元素添加一个类并使用 OUT 动画设置添加的类的样式来做到这一点。

jQuery:

$("svg").mouseout(function() {
    $(this).addClass("wasHovered");
 });

CSS:

svg path{

}

svg.wasHovered path{
    animation: animateLogoOut 1s;
}

svg:hover path{
    animation: animateLogoIn 1s;
}

@keyframes animateLogoIn {
    from {stroke-dashoffset: -510px;}
    to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
    from {stroke-dashoffset: 0px;}
    to {stroke-dashoffset: -510px;}
}

瞧!您可以在我的 codepen 上找到所有这些以及更多内容,详细显示带有 SVG 徽标悬停动画的 2 个选项。

https://codepen.io/MateoStabio/pen/jOVvwrM

于 2021-03-06T15:40:52.237 回答
0

在这里尝试了几种解决方案,没有任何工作完美无缺;然后再上网搜索一下,在https://greensock.com/上找到GSAP(需获得许可,但相当宽松);一旦你引用了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();
  });

它将完美地工作。

于 2020-03-11T05:02:46.540 回答