css3 动画:悬停;强制整个动画

Posted

技术标签:

【中文标题】css3 动画:悬停;强制整个动画【英文标题】:css3 animation on :hover; force entire animation 【发布时间】:2011-12-03 09:44:15 【问题描述】:

我创建了一个简单的反弹动画,我将其应用于元素的:hover 状态:

@keyframes bounce 
    0% 
      top: 0;
      animation-timing-function: ease-out;
    
    17% 
      top: 15px;
      animation-timing-function: ease-in;
    
    34% 
      top: 0;
      animation-timing-function: ease-out;
    
    51% 
      top: 8px;
      animation-timing-function: ease-in;
    
    68% 
      top: 0px;
      animation-timing-function: ease-out;
    
    85% 
      top: 3px;
      animation-timing-function: ease-in;
    
    100% 
      top: 0;
    


.box:hover  
    animation: bounce 1s;

动画效果很好,只是当您从元素上移开光标时,它会突然停止。即使鼠标已经退出,是否有强制它继续设定的迭代次数?基本上我在这里寻找的是由:hover 状态触发的动画。我不是在寻找 javascript 解决方案。我还没有在规范中看到这样做,但也许我在这里错过了一个明显的解决方案?

这是一个可以玩的小提琴:http://jsfiddle.net/dwick/vFtfF/

【问题讨论】:

【参考方案1】:

恐怕解决这个问题的唯一方法是使用一点javascript,您必须将动画添加为一个类,然后在动画完成时将其删除。

$(".box").bind("webkitAnimationEnd mozAnimationEnd animationend", function()
  $(this).removeClass("animated")  
)

$(".box").hover(function()
  $(this).addClass("animated");        
)

http://jsfiddle.net/u7vXT/

【讨论】:

希望避免使用 javascript,但我认为这是唯一的方法。 与浏览器无关的事件名称应全部小写:animationend【参考方案2】:

如果有人想使用它,我使用纯 Javascript 从同一篇帖子 https://***.com/a/7697786/8335898 中创建了一个 JsFiddle 的答案。

const elements = document.getElementsByClassName('box');

for (let i = 0; i <= elements.length; i++) 
  elements[i].addEventListener('animationend', function(e) 
    elements[i].classList.remove('animated');
  );

 elements[i].addEventListener('mouseover', function(e) 
   elements[i].classList.add('animated')
 )

【讨论】:

【参考方案3】:

只是为了改进 Duopixel 的答案,当我运行无限动画时,我必须这样做:

$(".box").css("animation-iteration-count", "1"); 
$(".box").bind("webkitAnimationEnd mozAnimationEnd animationEnd", function()
  $(this).removeClass("animated")  
)
$(".box").hover(function()
  $(".box").css("animation-iteration-count", "infinite"); 
  $(this).addClass("animated");        
)

这只是没有突然结束动画。

【讨论】:

如果我想在移除悬停时优雅地停止动画怎么办?然后当我再次悬停时再次启动无限动画? 可以实现box的mouseleave事件,可以在里面添加这段代码。 开发了一个解决方案 :D 如果它可以帮助任何人,这就是小提琴! jsfiddle.net/sSYYE/33 谢谢@Vinay!您的解决方案真的很有帮助! 是否可以确保动画结束但在反面?【参考方案4】:

与@methodofaction 的答案相同,但适用于任何使用 React 的人:

import React,  useState  from 'react';
import  FontAwesomeIcon  from '@fortawesome/react-fontawesome';

export default function Icon( icon ) 
    const [animated, setAnimated] = useState(false);

    return (
        <div
            onMouseEnter=() => setAnimated(() => true)
            onAnimationEnd=() => setAnimated(() => false)
        >
            <FontAwesomeIcon icon=icon className=animated ? 'animated' : '' />
        </div>
    );

【讨论】:

【参考方案5】:

一个简单的技巧就可以完成这项工作:

-webkit-animation:swing 3600ms ease-in-out 6000s;
-webkit-transform-origin:top;

在元素上设置一个高值的“延迟”(不是:悬停)。

发件人:*** - Robert McKee

【讨论】:

【参考方案6】:

CSS 在某些情况下可能会有所帮助,但不是全部,下面是在悬停时和悬停后为字母间距设置动画的代码。

h1

    -webkit-transition:all 0.3s ease;


h1:hover

    -webkit-transition:all 0.3s ease;
    letter-spacing:3px;
<body>
    <h1>Hello</h1>
</body>

【讨论】:

这是一个过渡,不是动画。【参考方案7】:

这不会在所有情况下都有效,并且在没有一些妥协的情况下不适用于 OP,但我通过向 :not(:hover) 选择器添加动画解决了这个问题:

@keyframes stopBounce 
    0% 
         top: 15px;
    
    100% 
        top: 0px;
    


@keyframes bounce 
    ops: bounce code



.box
    top: 0px;
    transition: top 250ms 1000ms ease-in-out,

.box:hover
    animation-name: bounce;
    animation-fill-mode: both;
    animation-duration: 250ms;

.box:not(:hover)
    animation-name: stopBounce;
    animation-duration: 250ms;
    animation-delay: 1000ms;
    animation-fill-mode: both;

所以,这不会让动画一直持续下去。据我所知,纯 CSS 解决方案是不可能的。它所做的是让它平稳地过渡回它的起始位置。诀窍是有两个选择器,任何时候只有一个可以处于活动状态。

这让我们可以做的是在用户悬停时播放动画,并在用户停止悬停时播放单独的动画。由于这两个动画都可以控制,因此我们可以确保它们之间的过渡是平滑的。

就像我说的,这并不能完全解决问题,但它不使用 JavaScript 并且会保持流畅。

【讨论】:

以上是关于css3 动画:悬停;强制整个动画的主要内容,如果未能解决你的问题,请参考以下文章

css CSS3,动画:使用translate3d强制WebKit中的硬件加速

悬停时继续 CSS3 关键帧动画/悬停时停止重复

css3关键帧悬停动画firefox

取消悬停时的 CSS3 动画

CSS3:动画精灵+悬停过渡

是否有 Firefox 相当于 Chrome 的“translateZ(0);”强制 GPU 加速 CSS 动画?