web-dev-qa-db-ja.com

CSSアニメーションの速度を変更するにはどうすればよいですか?

私はアニメーションを持っています:

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

私は無限に回転する画像を持っています。 JSで回転速度を変えたいです。私は試した:

$('img').css('animation-duration', '2s');

継続時間によって速度が変わりますが、アニメーションはフレームキー0%(最初)に再起動しますが、何も起こらなかったようにアニメーションを続行したいだけです。 0%に戻りたくない。

どうやってやるの?

14
Matrix

そうすることは非常に難しいプロセスです。現在、アニメーションの途中でアニメーションを変更する唯一の方法は、setIntervalを使用して現在のキーフレームのパーセンテージを概算し、そのキーフレームのプロパティを保存し、アニメーションを更新して(この場合は速度のみ)、新しいものを適用することです。保存されたポイントから始まるアニメーションのバージョン。私がCSSトリックのために書いた記事で同様の例を作成しました JavascriptによるCSSアニメーションとトランジションの制御

記事で説明したように、animationIterationの速度を変更する方が簡単です。この場合、 this demo 、しかしそれはまだきれいにはほど遠い

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

現時点では、別のタイミング関数でアニメーションを単純に再開することはできません(マイケルが言ったように、一時停止して再度実行したとしても)。その結果、setInterval(より高い遅延を与える)を使用するか、変更された値で要素のクローンを作成する必要があります。私が使用したアプローチの詳細については、デモを見て、追加したすべてのJavaScriptにコメントを追加しました

[〜#〜]編集[〜#〜]コメント内のリンクされたフィドルに基づいて

ルーレットをシミュレートしようとしているので、JavaScriptを使用する必要はまったくありません。 rotationアニメーションを変更して、時間の経過とともに速度を変更するだけです(: これが大まかなバージョンです dそうしますが、現在の動作よりもスムーズに見えるように、キーフレームを追加する必要があります

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

編集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
    );
}

とCSS

img { -webkit-transition: -webkit-transform 2s ease-out; }

編集3

これは完全に関連性があるわけでも関連性がないわけでもありませんが、 [〜#〜] gsap [〜#〜] のように このプロジェクトで行った を使用して非常によく似たことができます。よりインタラクティブ/ダイナミック

10
Zach Saucier

これを行うには、ラッパーを設定し、それを逆回転させます。

CSS

.wrapper, .inner {
    position: absolute;
    width: 100px;
    height: 100px;
  -webkit-animation-name: rotate;
  -webkit-animation-iteration-count: infinite;
  -webkit-animation-timing-function: linear;
  animation-name: rotate;
  animation-iteration-count: infinite;
  animation-timing-function: linear;
}
.wrapper {
    left: 40px;
    top: 40px;
  -webkit-animation-duration: 2.5s;
    -webkit-animation-play-state: paused;
    -webkit-animation-direction: reverse;
  animation-duration: 2.5s;
    animation-play-state: paused;
    animation-direction: reverse;
}
.wrapper:hover {
    -webkit-animation-play-state: running;
    animation-play-state: running;
}
.inner {
    display: block;
    background-color: red;
  -webkit-animation-duration: 1.5s;
  animation-duration: 1.5s;
}
@keyframes rotate {
  from { transform: rotate(0deg);  }
  to {    transform: rotate(360deg);  }
}    
@-webkit-keyframes rotate {
  from { -webkit-transform: rotate(0deg);  }
  to {    -webkit-transform: rotate(360deg);  }
}    

デモ

(正方形にカーソルを合わせると遅くなります)

1
vals