In 'n' Out

知識を取り込み、そして発信する

アニメーションの制御

アニメーションを自在に動かす

transitionでは、状態の変化を滑らかに表現できましたが、時間の流れに沿って動きを細かく制御することはできません。
途中で動きを変えたり、動く順番を調整したりするには、変化の過程を自分で定義する必要があります。
ここでは、その方法について解説していきます。

動きの内容を定義する

要素の見た目を変えるだけでは、時間の流れに沿った動きを細かく制御することはできません。
動きを実現するためには、どのように変化していくのかをあらかじめ定義する必要があります。
開始時と終了時、または途中の状態を指定することで、変化の流れを作ることができます。

構文

@keyframes 名前 {
    from { プロパティ: 値; }
    to { プロパティ: 値; }
}

@keyframesでアニメーションの名前を定義します。
この名前は、後から指定するプロパティで使用します。
fromは開始時、toは終了時の状態を指定します。
ブロック内には、変化させたいCSSプロパティとその値を記述します。
ただし@keyframesは動きの内容を定義するだけで、これだけではアニメーションは実行されません。
この定義を実際に動かすには、専用のプロパティを指定する必要があります。

構文

セレクタ {
    animation-name: 名前;
    animation-duration: 時間;
}

animation-nameはどの動きを使うかを指定します。あらかじめ定義した名前を指定します。
animation-durationは1回の動きにかかる時間を指定します。秒(s)やミリ秒(ms)で設定します。
それでは、どのように動くのかをコード例で見ていきましょう。

コード例

<div>
    <p id="anim">要素</p>
</div>
div{
    height: 100px;
}

#anim{
    width: 75px;
    height: 50px;
    background-color: #ff0000;
    color: #ffffff;
    text-align: center;
    line-height: 50px;
}

#anim:hover{
    animation-name: anime;
    animation-duration: 2s;
}

@keyframes anime{
    from{
        transform: translate(0);
    }
    to{
        transform: translateX(100px);
    }
}

出力例

要素

このコードでは、要素が2秒かけて右に100px移動するアニメーションを設定しています。
まず、@keyframesでanimeという名前の動きを定義し、開始時はその場、終了時は右に100px移動するように指定しています。
次に、animation-nameでその動きを指定し、animation-durationでアニメーションにかかる時間を2秒に設定しています。
animation-nameとanimation-durationは、アニメーションを適用したい要素に指定することで、その動きが実行されます。
これにより、要素はゆっくりと右へ移動します。
開始と終了だけでもアニメーションは実現できます。
それでは、アニメーションをさらに制御していきましょう。

アニメーションの流れを細かく制御する

開始と終了だけを指定することで、シンプルなアニメーションを作ることができます。
しかし、途中の動きを細かく変化させることはできません。
途中で動きを変えたり、複雑な動きを実現するには、時間ごとの状態を指定する必要があります。
ここでは、その方法について解説していきます。

構文

@keyframes 名前 {
    0% { プロパティ: 値; }
    任意の% { プロパティ: 値; }
    100% { プロパティ: 値; }
}

0%はアニメーションの開始時、100%は終了時の状態を表します。
その間に任意の%を指定することで、時間の経過に応じた途中の状態を設定することができます。
%は複数指定することができ、細かく設定するほど、より自由な動きを表現することができます。

コード例

<div>
    <p id="anim">要素</p>
</div>
div{
    height: 100px;
}

#animP{
    width: 75px;
    height: 50px;
    background-color: #ff0000;
    color: #ffffff;
    text-align: center;
    line-height: 50px;
}

#animP:hover{
    animation-name: animeP;
    animation-duration: 4s;
}

@keyframes animeP{
    0%{
        transform: translate(0);
    }
    25%{
        transform: translateX(50px);
    }
    50%{
        transform: translateX(0);
    }
    100%{
        transform: translateX(100px);
    }
}

出力例

要素

このコードでは、要素にマウスを重ねたときに、4秒かけて動きが変化するアニメーションを設定しています。
まず、animation-nameでanimePという動きを指定し、animation-durationでアニメーションの時間を4秒に設定しています。
これにより、定義した動きが実行されます。
次に、@keyframesで時間ごとの状態を指定しています。
0%では初期位置、25%では右に50px移動し、50%では元の位置に戻ります。
さらに100%では右に100px移動するように設定されています。
ここでの%は、アニメーション全体の時間に対する割合を表しています。
今回は4秒のアニメーションなので、25%は1秒後、50%は2秒後の状態になります。 このように、時間ごとの状態を指定することで、動きの流れを細かくコントロールすることができます。

アニメーションプロパティ

これまでに登場したanimation-nameやanimation-durationも含め、アニメーションにはさまざまな専用プロパティが用意されています。

構文

セレクタ{
    animation-timing-function: 値;
    animation-delay: 遅延;
    animation-iteration-count: 回数;
    animation-direction: 再生方向;
    animation-fill-mode: 値;
    animation-play-state: 値;
    animation: 名前 時間 動き 遅延 回数 再生方向...;
}

animation-timing-functionは動きのスピードの変化を指定します。
値の詳細は下記の一覧表を確認してください。

animation-timing-function値一覧
説明
linear一定の速度で変化
easeゆっくり始まり→速く→ゆっくり終わる
ease-inゆっくり始まる
ease-outゆっくり終わる
ease-in-outゆっくり始まり、ゆっくり終わる
step-start開始時点ですぐに変化(カクッと切り替わる)
step-end終了時点で変化(最後に切り替わる)
steps(数値, start | end)指定した数値を段階として変化
cubic-bezier(x1, y1, x2, y2)xは時間、yは変化量を示し、加速や減速のタイミングを細かく制御できる

animation-delayは動きが開始されるまでの待ち時間を秒かミリ秒で指定します。
animation-iteration-countは動きを何回繰り返すかを数値またはinfinite(無限ループ)で指定します。
animation-directionは動きの再生方向を指定します。
値の詳細は下記の一覧表を確認してください。

animation-direction値一覧
説明
normalアニメーションの通常再生
reverseアニメーションの逆再生
alternateアニメーションの往復再生
alternate-reverse逆から往復再生

animation-fill-modeは動きの前後でどの状態を適用するかを指定します。
値の詳細は下記の一覧表を確認してください。

animation-fill-mode値一覧
説明
noneアニメーションの影響を前後に適用しない(終了後は元に戻る)
forwardsアニメーション終了後、最後の状態を維持
backwardsアニメーション開始前に最初の状態を適用
both開始前と終了後の両方に適用

animation-play-stateはrunningで再生、pausedで一時停止と、アニメーションの再生状態を指定します。
animationは複数の設定をまとめて指定するための省略記法で、順番に値を並べて記述します。

コード例

<div>
    <p id="anims">要素</p>
</div>
div{
    height: 100px;
}

#anims{
    width: 75px;
    height: 50px;
    background-color: #ff0000;
    color: #ffffff;
    text-align: center;
    line-height: 50px;
}

#anims:hover{
    animation-name: anims;
    animation-duration: 2s;
    animation-timing-function: linear;
    animation-delay: 0.5s;
    animation-iteration-count: 3;
    animation-direction: reverse;
    animation-fill-mode: forwards;
    animation-play-state: running;
}
        
@keyframes anims{
    0%{
        transform: translate(0);
    }
    100%{
        transform: translate(50px);
    }
}

出力例

要素

このコードでは、要素にマウスを重ねたときに、一定の動きを繰り返すアニメーションを設定しています。
まず、:hover時にanimation-nameで「anims」という動きを指定し、animation-durationで1回のアニメーション時間を2秒に設定しています。
さらにanimation-delayで0.5秒後に動きが開始されるようにしています。
animation-timing-functionにはlinearを指定しているため、一定の速度で移動します。
また、animation-iteration-countを3にすることで、この動きを3回繰り返します。
animation-directionにreverseを指定しているため、アニメーションは終了状態から開始状態に向かって再生されます。
animation-fill-modeにforwardsを指定しているため、アニメーション終了後は最後の状態が維持されます。
@keyframesでは、0%で初期位置、100%で右に50px移動するように設定しています。
これにより、通常は右方向に移動する動きですが、reverseが指定されているため、左方向へ移動するアニメーションが実行されます。
なお、この内容をショートハンドにすると下記のようになります。

コード例

#anims:hover{
    animation: anims 2s linear 0.5s 3 reverse forwards running;
}

なお、コード例ではanimationプロパティをすべて指定していますが、実際には必要なプロパティだけを指定すれば問題ありません。
また、animationプロパティは@keyframesのブロック内には指定できず、指定しても無視されるため注意が必要です。

これまでアニメーションについて見てきました。
これらの動きはJavaScriptと組み合わせることで、より柔軟に制御することもできます。