改变动画CSS3的速度?

Mat*_*rix 13 css jquery css-animations

我有动画:

img.rotate {
  animation-name: rotate;
  animation-duration: 1.5s;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
Run Code Online (Sandbox Code Playgroud)

我有无限的旋转图像.现在我想用JS改变旋转速度.我试过了:

$('img').css('animation-duration', '2s');
Run Code Online (Sandbox Code Playgroud)

持续时间会改变速度,但动画会重新启动到帧密钥0%(第一个),但我只想让动画继续,就像什么也没发生一样; 我不想回到0%.

我怎样才能做到这一点?

Zac*_*ier 10

这是一个非常困难的过程.目前改变动画中期动画的唯一方法是使用a setInterval近似当前关键帧百分比,保存该关键帧的属性,更新动画(在你的情况下只是速度)然后应用新版本的动画从保存的点.我在为CSS Tricks编写的文章中创建了一个类似的例子,名为Controlling CSS Animations&Transitions with Javascript

正如文章所描述的那样,animationIteration在您的情况下更改速度会更容易看起来像这个演示,但它仍然远非漂亮

 var pfx = ["webkit", "moz", "MS", "o", ""],
    rotates = $('.rotate'),
    prevent = false;

function PrefixedEvent(element, type, callback) {
    for (var p = 0; p < pfx.length; p++) {
        if (!pfx[p]) type = type.toLowerCase();
        element.addEventListener(pfx[p]+type, callback, false);
    }
}

function listen() {
    for(var i = 0, j = rotates.length; i < j; i ++) {
        PrefixedEvent(rotates[i], "AnimationIteration", function() {
            if(!$('#faster').is(':checked') && !prevent) {
                var el = $(this),  
                   newOne = el.clone(true)
                            .css({'animation':'rotate 2s linear infinite'});
                el.before(newOne);        
                $("." + el.attr("class") + ":last").remove();
                rotates = $('.rotate');
                listen();
                prevent = true;
            }
            else if($('#faster').is(':checked') && prevent) {
                prevent = false;
                var el = $(this),
                   newOne = el.clone(true)
                            .css({'animation':'rotate 1.5s linear infinite'});
                el.before(newOne);
                $("." + el.attr("class") + ":last").remove();
                rotates = $('.rotate');
                listen();
            }
        });
    }
}
listen();
Run Code Online (Sandbox Code Playgroud)

目前我们不能简单地使用不同的计时功能重新启动动画(即使你暂停它并像Michael所说的那样再次运行它).因此,您必须使用a setInterval(提供更高的延迟)或使用更改的值克隆元素.有关我使用的方法的更多信息,请参阅演示,我在我添加的所有javascript中添加了注释

编辑基于您在评论中的链接小提琴

由于您正在尝试模拟轮盘赌,因此您根本不需要使用javascript!只需更改rotation动画即可随时间更改速度(:这是您如何操作的粗略版本,但您应该添加更多关键帧,使其看起来比目前的行为更加流畅

@-webkit-keyframes rotate {
    0%   { -webkit-transform: rotate(   0deg); }
    30%  { -webkit-transform: rotate(2600deg); }
    60%  { -webkit-transform: rotate(4000deg); }
    80%  { -webkit-transform: rotate(4500deg); }
    100% { -webkit-transform: rotate(4780deg); }
}
Run Code Online (Sandbox Code Playgroud)

编辑2

因为你显然需要一个随机的结束位置并可能多次运行它你可以做一些更简单的事情,只使用CSS转换,并且非常有用

var img = document.querySelector('img');
img.addEventListener('click', onClick, false);    
var deg = 0;

function onClick() {
    this.removeAttribute('style');        
    deg += 5 * Math.abs(Math.round(Math.random() * 500));        
    var css = '-webkit-transform: rotate(' + deg + 'deg);';        
    this.setAttribute(
        'style', css
    );
}
Run Code Online (Sandbox Code Playgroud)

和CSS

img { -webkit-transition: -webkit-transform 2s ease-out; }
Run Code Online (Sandbox Code Playgroud)

编辑3

这不完全相关或不相关,但您可以使用GSAP执行非常类似的操作,就像我在此项目中所做的那样,使其更具交互性/动态性