如何平滑地将 CSS 动画恢复到当前状态?

Posted

技术标签:

【中文标题】如何平滑地将 CSS 动画恢复到当前状态?【英文标题】:How to smoothly revert CSS animation to its current state? 【发布时间】:2015-07-20 14:32:10 【问题描述】:

我有 not animated 元素作为默认值。还有一个触发器可以让我打开和关闭该元素上的动画。动画本身非常简单:将元素从左向右移动。

当我停止动画时,我的元素显然会回到初始位置。但它突然回来了,并不顺利。因此,它只是将其位置从我关闭动画时的位置更改为初始位置。我的问题是:有没有办法让它平滑地停止,所以当我关闭动画时,它会回到初始位置但平滑/动画。

这是我的元素和动画:http://jsfiddle.net/2Lwftq6r/

HTML:

<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
<div></div>

CSS:

div  
    margin-top: 50px;
    width: 50px; height: 10px;
    background: #000;
    transform: translateX(0);


#anim:checked ~ div 
    -webkit-animation: dance 2s infinite ease-in-out;
    -moz-animation: dance 2s infinite ease-in-out;


@-webkit-keyframes dance 
  0%, 100%  -webkit-transform: translateX(0); 
  50%  -webkit-transform: translateX(300px); 

@-moz-keyframes dance 
  0%, 100%  -moz-transform: translateX(0); 
  50%  -moz-transform: translateX(300px); 

【问题讨论】:

不幸的是,当前的 CSS 规范没有为这种行为做出规定。这个问题有一些解决方法(停止/删除动画后没有转换回“基本状态”),但它们都是基于 JS 的。你会考虑基于 JS 的解决方案吗? Smoothly stop CSS keyframe animation的可能重复 这个问题解决了吗? 【参考方案1】:

我刚刚遇到了同样的问题,但我通过不使用动画解决了它,而且效果很好!查看我的解决方案: 所以我有这把抹刀,只有在悬停时我必须移动它,我希望它能够平稳地过渡回来,所以这就是我所做的:

#Spatula:hover
    animation-direction:alternate;
    transform: translate(1.2cm,1cm);
    transition: all 1.5s;
    -webkit-transition: all 1.5s;



#Spatula
    -webkit-transition: all 1.5s;
    transition: all 1.5s;


祝你好运!

【讨论】:

这是我见过的最简单的解决方案,它对我有用:) animation-direction:alternate; 我猜是不需要的【参考方案2】:

你不能只用CSS3的方式存档这个效果,但是如果你真的需要它,你可以使用jQuery + CSS3 Transitions。我的解决方案(http://jsfiddle.net/sergdenisov/3jouzkxr/10/):

HTML:

<input type="checkbox" id="anim-input">
<label for="anim-input">Start / stop animation</label>
<div class="anim-div"></div>

CSS:

.anim-div  
    margin-top: 50px;
    width: 50px;
    height: 10px;
    background: #000;


    .anim-div_active 
        -webkit-animation: moving 2s ease-in-out infinite alternate;
        animation: moving 2s ease-in-out infinite alternate;
    

    .anim-div_return 
        -webkit-transition: -webkit-transform 0.5s ease-in-out;
        transition: transform 0.5s ease-in-out;
    

@-webkit-keyframes moving 
    0%  -webkit-transform: translateX(0); 
    100%  -webkit-transform: translateX(300px); 


@keyframes moving 
    0%  transform: translateX(0); 
    100%  transform: translateX(300px); 

Javascript:

$('#anim-input').on('change', function() 
    var $animDiv = $('.anim-div');
    if (this.checked) 
        $animDiv.removeClass('anim-div_return')
                .addClass('anim-div_active');
        return;
    

    var transformValue = $animDiv.css('webkitTransform') ||
                         $animDiv.css('transform');
    $animDiv.css('webkitTransform': transformValue,
                  'transform': transformValue)
            .removeClass('anim-div_active');

    requestAnimationFrame(function() 
        $animDiv.addClass('anim-div_return')
                .css('webkitTransform': 'translateX(0)',
                      'transform': 'translateX(0)');
    );
);

附言 供应商前缀基于来自http://caniuse.com 的实际浏览器列表。

【讨论】:

【参考方案3】:

查看This *** question。

你不会喜欢这个答案,但事实是 CSS3 动画对于实现这一点并不是很有用。为了使这项工作你 需要在 javascript 中复制大量 CSS 有点破坏了这一点(例如在这个密切相关的 回答 Change speed of animation CSS3?)。 要真正让它顺利停止,你最好的选择是写 像Greensock animation library这样的平台上的动画 它提供了使它真正顺利进行所需的所有工具 停止而不是突然停止。

下面还有另一个答案确实在努力使用 CSS,你可以看看那个。

【讨论】:

在相关说明中,这是添加到 angular animateCss 服务中的内容。【参考方案4】:

还有一个替代的解决方案,它可能不会给你想要的回到它原来的状态的效果,但是由于没有人提到它并且这个问题似乎没有解决方案,所以完全可以在 css 中暂停动画,锁定它的状态直到它再次启动

要暂停动画,您需要先使动画可用,即使复选框未选中

并利用animation-play-state 属性

div  
    margin-top: 50px;
    width: 50px; height: 10px;
    background: #000;
    animation: dance 2s infinite ease-in-out paused;


#anim:checked ~ div 
    animation-play-state: running;


@keyframes dance 
  0%, 100%  transform: translateX(0); 
  50%  transform: translateX(300px); 
<input type="checkbox" id="anim">
<label for="anim">Start / stop animation</label>
    
<div></div>

【讨论】:

这是一个非常聪明的解决方案,而且效果很好。它不会恢复动画,但在不再悬停元素时肯定会阻止跳转。

以上是关于如何平滑地将 CSS 动画恢复到当前状态?的主要内容,如果未能解决你的问题,请参考以下文章

平滑缩放 img 并自动 scrollIntoView

重新启动时如何使这个 CSS 关键帧动画平滑?

CSS:如何在另一个动画运行时保持悬停过渡平滑

CSS3:动画之间的平滑过渡:hover

如何使用 Google Maps SDK 中的自定义 LocationSource 平滑地为当前位置设置动画?

如何动态地将动画添加到队列中