【Sassで作るCssミニゲーム】Cssミニゲームで使えるアニメーションテクニックの基礎


※ 当ページには【広告/PR】を含む場合があります。
2021/07/30
2023/12/20
【Sassで作るCssミニゲーム〜番外編】親子要素でonclickなどのイベントをどちらか一方に指定する方法
【CSS/Sassで作るミニゲーム】CSS変数(カスタムプロパティ)とシンプルなJSコードでHTML要素をコントロール
蛸壺の技術ブログ|Cssミニゲームで使えるアニメーションテクニックの基礎

CSSで動きのあるミニゲームを作るとなるとどうしても避けて通れないのがCSSアニメーションです。

純粋なCSSでアニメーション効果をつけるには
transitionanimationを使うことになります。

この記事では、この二つのプロパティの使い方を比較し、長所短所を説明してから、効果的に利用する方法を検討していきます。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】CSS/Sassをこれから学びたい人のためのオススメ書籍&教材特集

transitionを使ったCSSゲームの基礎

transitionプロパティを使えば簡単にCSSアニメーションが作れます。

まずは以下のようにインプットチェックボックスを使ったメンタコが動くだけのCSSアニメーションを操作してみてください。

実装の中身

先程のCSSプログラムの中身を見ていきます。

まずは核になるhtml要素のコードは以下です。

            
            <div id="wrapper">
    <input type="checkbox" id="move1">
    <input type="checkbox" id="move2">
    <input type="checkbox" id="move3">
    <label for="move0">0</label>
    <label for="move1">1</label>
    <label for="move2">2</label>
    <label for="move3">3</label>
    <div class="mentaco"></div>
</div>
        
ここでもやはりCSSゲームの基礎テクである通称input-label法を利用しています。

このhtmlに割り当てているのはCssパートは以下です。

            
            #wrapper {
    width: 100%;
    height: 300px;
    background-color: darkgray;
    box-sizing: border-box;
    position:relative;
    .mentaco{
        position: absolute;
        display: block;
        padding: 0 0 0 0;
        transition: all 1s cubic-bezier(.68,-0.55,.27,1.55);
        top: 20px;
        left: 0;
        width: 80px;
        height: 72px;
        background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/deep-tacopots/blog116/mentaco.png') no-repeat 0 0;
        background-size: 80px 72px;
    }
    #move1:checked ~ .mentaco {
        transform: translateX(120px) translateY(120px);
    }
    #move2:checked ~ .mentaco {
        transform: translateX(90px) translateY(-20px);
    }
    #move3:checked ~ .mentaco {
        transform: translateX(200px) translateY(10px);
    }
    input {
        position: absolute;
        top: 0px;
        &#move1 { left: 0px; }
        &#move2 { left: 20px; }
        &#move3 { left: 40px; }
    }
    label {
        background-color: aqua;
        width: 20px;
        height: 20px;
        display: block;
        border-radius: 50%;
        position: absolute;
        z-index: 1;
        text-align: center;
        &[for="move0"] { top: 46px; left: 28px; }
        &[for="move1"] { top: 165px; left: 148px; }
        &[for="move2"] { top: 22px; left: 118px; }
        &[for="move3"] { top: 55px; left: 228px; }
    }
}
        

プログラムの解説

transitionを使ったアニメーションはデモを動かしてもらった通り、現在のアニメーションターゲット要素の位置と行き先の
2点間を直線的に移動するように作用します。

またチェックボックスをオンオフしても分かるように、
往復移動も含めてアニメーションにすることができます。

transitionを使ったアニメーションはこの特性ゆえに、CSSプログラムを実装する分には理解しやすいというメリットがあります。

つまりチェックボックスのオンオフフラグを上手く利用することで、メンタコのスプライトを好きな2点間で自由に移動させることができます。

例えば
2 --> 01 --> 3のルートで動かしたい場合のチェックボックスの組み合わせを探すのも簡単です(条件はご自分の手で探してみてください)。

モダンなtransitionの記述法

先程のCSSスタイルの一例で見ていただいた通り、
transformからアニメーションを行う場合、必要最低限の値を順序正しく記述する必要があります。

例えば、先述のスタイルに回転移動と拡大縮小の値を追加で設定したものは以下のようになります。

            
            #move1:checked ~ .mentaco {
    transform: translateX(120px) translateY(120px) rotate(45deg) scale(1.4);
}
#move2:checked ~ .mentaco {
    transform: translateX(90px) translateY(-20px) rotate(-72deg) scale(0.9);
}
#move3:checked ~ .mentaco {
    transform: translateX(200px) translateY(10px) rotate(132deg) scale(1.2);
}
        
こういったワンライナー(一括指定)で順序が重要となる値を記述するCSSプロパティはborderなど他に幾つか存在しますが、CSSに書き慣れていないと、一目ではどのようなスタイルが適用されているか分からなくなるときがあり、ワンライナーの設定値が長ければそれだけ難読化する一因ともなります。

そこら辺の事情も鑑みらてたのか、従来のワンライナー指定の代替として、値の個別も指定できるようになっています。

            
            #move1:checked ~ .mentaco {
    translate: 120px 120px;
    rotate: 45deg;
    scale: 1.4;
}
#move2:checked ~ .mentaco {
    translate: 90px -20px;
    rotate: -72deg;
    scale: 0.4;
}
#move3:checked ~ .mentaco {
    translate: 200px 10px;
    rotate: 192deg;
    scale: 1.2;
}
        
これを試してみると、従来のtranformを同じアニメーション効果になっていることが確認できます。

なお、
transformプロパティから独立したプロパティになったのは、translate/rotate/scaleの3つで、他のskewmatrixはまだ独立したプロパティになっていないことに注意しておきましょう。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】CSS/Sassをこれから学びたい人のためのオススメ書籍&教材特集

animationを使ったCSSゲームの基礎

animationプロパティを使った場合、transitionよりも高度なアニメーションが作成できます。

座標値や通過時間などを細かく定義することで、複雑な曲線軌道をうごくアニメーションも定義することができますが、その分より複雑なCSSコードを実装しなければならないのが難点です。

先ほどのtransitionで使ったデモプログラムを少々改造してanimationを使ったプログラムに仕立て直したものが以下です。

デモプログラムの中身

こちらも先ほどのように中身を見ていきましょう。

html部は以下のようになります。

            
            <form id="wrapper">
    <input type="reset" value="リセット">
    <input type="checkbox" id="move1">
    <input type="checkbox" id="move2">
    <input type="checkbox" id="move3">
    <label for="move0">0</label>
    <label for="move1">1</label>
    <label for="move2">2</label>
    <label for="move3">3</label>
    <div class="mentaco"></div>
</form>
        
今回のポイントはform要素を親要素にして中に入れた他の要素をリセットできるようにしているところです。

以下がcssスタイルコードになります。

            
            #wrapper {
    width: 100%;
    height: 300px;
    background-color: darkgray;
    box-sizing: border-box;
    position:relative;
    .mentaco{
        position: absolute;
        display: block;
        padding: 0 0 0 0;
        top: 20px;
        left: 0;
        width: 80px;
        height: 72px;
        background: transparent url('https://raw.githubusercontent.com/tacoskingdom/commonBlogMaterial/main/deep-tacopots/blog116/mentaco.png') no-repeat 0 0;
        background-size: 80px 72px;
    }
    #move1:checked ~ .mentaco {
        animation: xy1 2s cubic-bezier(.45,.05,.55,.95) forwards;
        @keyframes xy1 {
            0% {
                top: 20px;
                left: 0px;
            }
            30% {
                top: 50px + 20px;
                left: 280px;
            }
            70% {
                top: 170px + 20px;
                left: 200px;
            }
            100% {
                top: 120px + 20px;
                left: 120px;
            }
        }
    }
    #move2:checked ~ .mentaco {
        animation: xy2 2s cubic-bezier(.45,.05,.55,.95) forwards;
        @keyframes xy2 {
            0% {
                top: 120px + 20px;
                left: 120px;
            }
            30% {
                top: -40px + 20px;
                left: 150px;
            }
            70% {
                top: 50px + 20px;
                left: 10px;
            }
            100% {
                top: -20px + 20px;
                left: 90px;
            }
        }
    }
    #move3:checked ~ .mentaco {
        animation: xy3 2s cubic-bezier(.45,.05,.55,.95) forwards;
        @keyframes xy3 {
            0% {
                top: -20px + 20px;
                left: 90px;
            }
            30% {
                top: 140px + 20px;
                left: 70px;
            }
            70% {
                top: 110px + 20px;
                left: 190px;
            }
            100% {
                top: 10px + 20px;
                left: 200px;
            }
        }
    }
    input {
        position: absolute;
        top: 0px;
        &#move1 { left: 0px; }
        &#move2 { left: 20px; }
        &#move3 { left: 40px; }
        &[type="reset"] {
            left: 80px;
        }
    }
    label {
        background-color: aqua;
        width: 20px;
        height: 20px;
        display: block;
        border-radius: 50%;
        position: absolute;
        z-index: 1;
        text-align: center;
        &[for="move0"] { top: 46px; left: 28px; }
        &[for="move1"] { top: 165px; left: 148px; }
        &[for="move2"] { top: 22px; left: 118px; }
        &[for="move3"] { top: 55px; left: 228px; }
    }
}
        

ブログラムの解説

先ほどのanimationのでもプログラムを触ってもらうと実感して分かると思いますが、transitionアニメーションとは異なり、このアニメーションは
一方通行になります。つまり、最初に定義した開始フレームから最後の終了フレームまで進むとそこで打ち止めになり、再び最初の状態から再生されるしかなくなります。

このことがtransitionアニメーションとの大きな違いであり、アニメーションの巻き戻しは自動ではおこなえません。デモプログラムでいうと、チェックボックスを順番にクリックして、
0 > 1 > 2 > 3 > [リセット]というように流す以外は正しくアニメーションされないのはこのためです。

よってもし逆再生のアニメーションが必要になる場合には、新しくアニメーションフレームを定義して、html要素に割り当てる必要あります。

このanimationプロパティの
再生不可逆の性質もあって、もしCSSゲームのなかでアニメーションを利用したい場合には、transitionでは「往復」の動きがセットになって定義出来たのに対して、animationでは「行き」と「返り」のアニメーションを2つ用意しないといけません。

そこだけ考えてもanimationの実装の労力は2倍であり、更に
@keyframesを個別に用意しなけれならないため更に実装のコストは跳ね上がります。

とはいえ、animationの持つ高度なアニメーションの表現力は魅力的であり、華やかな演出をWebサイトにもたらすことで、他のサイトにはない印象で集客性に差をつけることも可能かもしれません。


合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】CSS/Sassをこれから学びたい人のためのオススメ書籍&教材特集

結論

以上、アニメーションをCSSゲームに取り入れる時に念頭においておきたいポイントとしては、

            
            + CSSアニメーションには、transitionかanimationを使う
+ transitionを使うと2点間を往復するアニメーションが作れる
+ animationを使うと始状態から終状態まで@keyframesで定義したアニメーションが作れる
+ transitionはアニメーションの逆再生(巻き戻し)ができるが、
    animationは巻き戻しできない
+ transitionは2点間を直線的にしか移動できないが、
    animationはフレームごとに定義した座標を通過するパスで
    細かくアニメーション軌道上を移動できる
+ CSSアニメーションを作る際には、transitionとanimationを混ぜない方がベター
        
基本は作りたいアニメーションがtransitionで出来そうならばtransitionで作成し、どうしてもtransitionで実現しそうにない動きになるならばanimationを使うように実装していくと良いでしょう。

参考サイト

【初めてアニメーションを作る方必見!!】Transitionと@Keyframe animationの違いとは?

記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。

合同会社タコスキングダム|蛸壺の技術ブログ【効果的学習法レポート】CSS/Sassをこれから学びたい人のためのオススメ書籍&教材特集