Help us understand the problem. What is going on with this article?

【Sass】【Javascript】CSSアニメーションとローディング画面【おまけのRails】

ポートフォリオにローディングアニメーションを実装をしたので、備忘録をつらつらと。

Sassでアニメーション

CSSをもっと便利に使えるSassを使って、簡単なアニメーションをコーディングしました。

以下がデモ動画。

こんな感じで、ローディング中にノートに記述してる的なアニメーションを作ります。

まずは土台から

とりあえず形だけ作ってみましょう。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="back">
        <div>
            <div id="load-box">
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
                <div></div>
            </div>
            <p>Loading<span>...</span></p>
        </div>
    </div>
</body>
</html>
style.scss
#back{
    /* 画面いっぱい */
    width: 100vw;
    height: 100vh;
    background-color: #ffffff;
    display: flex;
    & div{
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
        margin: auto;
        & p{
            color: #a9dee6;
            }
        }
    }

#load-box{
    width: 100px;
    height: 135px;
    border: 1px solid #a9dee6;
    & div{
        width: 60px;
        border: 1px solid #a9dee6;
        margin: 5px auto;
    }
}

divでいくつか箱を作っています。
id="back"はローディング画面全体の箱を指します。

Sassは入れ子構造でCSSを記述できるのでスッキリしてて良いですね。

とりあえずこれで形ができました。

アニメーションをつける

ではアニメーションを付与しましょう。

@mixinを使用すればcssをメソッドのように扱えてメンテナンスが楽になります。
なので、外部ファイル_mixinを作り、今回付与するアニメーションの定義をします。

_mixin.scss
@mixin animation(
    $name,
    $duration: 3s,
    $interation-count: infinite,
    $fill-mode: forwards
){
    animation: {
        name: $name;
        duration: $duration;
        iteration-count: $interation-count;
        fill-mode: $fill-mode;
    }
}

引数に使いたいアニメーションを色々初期設定してます。
そして各アニメーションにその引数を渡してあげます。
これ本当便利ですね。

それぞれの機能についてはこちらの記事でわかりやすくまとめてくれています。
これは保存版です。
【CSS3】@keyframes と animation 関連のまとめ

ではこのmixinを用いて、style.scssを以下のように変えてあげましょう。

style.scss
@import "mixin";

#back{
    width: 100vw;
    height: 100vh;
    background-color: #ffffff;
    display: flex;
    & div{
        display: flex;
        justify-content: center;
        flex-direction: column;
        align-items: center;
        margin: auto;
        & p{
            color: #a9dee6;
            /* 追加 */
            & span{
                transform-origin: left;
                @include animation(
                    $name: dot-anime
                );
            }
        }
    }
}

#load-box{
    width: 100px;
    height: 135px;
    border: 1px solid #a9dee6;
    & div{
        width: 60px;
        border: 1px solid #a9dee6;
        margin: 5px auto;
        /* 追加 */
        transform-origin: left;
        animation-timing-function: cubic-bezier(1, 0.03, 0.98, 0.04);
        @include animation(
            $name: load-anime
        );
        /* for文でアニメーションのタイミングをずらす */
        @for $i from 1 through 7 {
            &:nth-child(#{$i}){
                animation-delay: -1.3s + $i * 0.1s;
            }
        }
    }
}

/* 追加 */
@keyframes load-anime{
    0%{
        opacity: 0;
        transform: scaleX(0);
    }
    50%{
        opacity: 1;
        transform: scaleX(1);
    }
    100%{
        opacity: 0;
        transform: scaleX(0);
    }
}

/* 追加 */
@keyframes dot-anime{
    0%{
        opacity: 0;
    }
    50%{
        opacity: 1;
    }
    100%{
        opacity: 0;
    }
}

ざっと説明しますと、@includeで先ほどのmixinで定義したアニメーションを読み込んでいます。
外部ファイルで管理してるので、同じような処理もコードが短く済んで良いですね。

また、Sassではfor文が使えるので、子要素に対してタイミングをズラして動くアニメーションを付与してあげました。

@keyframesでは、animation-nameに対してアニメーションを付与してます。
0%と100%はそれぞれアニメーションのはじめと終わりを指しているので、好きなタイミングで好きなアニメーションを付与してあげましょう。

Javascriptでローディング

アニメーションができたので、Javascriptでローディングの設定をしましょう。
と言ってもこちらはそんなに難しくありません。
以下のように記述するだけです。

application.js
function loaded(){
    const loading = document.querySelector('#back');
    loading.classList.add('loaded');
}
window.onload = loaded;

関数loadedには次のような処理をさせています。

  • ローディング画面全体のhtmlを取得する処理
  • そこにローディング画面を隠すloadedクラス(scssに追加します)を付与する処理

この処理を画面読み込みが完了したら発動するように、window.onloadで呼び出します。

あとはscssファイルに必要なスタイルを記述するだけです。

style.scss
.loaded{
    opacity: 0;
    visibility: hidden;
}

これでロードが完了したらローディングアニメーションが隠れます。

Railsでのちょっとした注意点

今回これらをRailsアプリに実装したのですが、そのままjsファイルに記述すると一生ローディング画面になるという中々だるい展開に。

原因はjsファイルにあらかじめ記述してある、

application.js
//= require turbolinks

みたいです。

同じような感じで困ったら、とりあえずこいつを消してやりましょう。

まとめ

SassとJavascriptを使ってローディング画面を実装しました。
フロントの勉強にはとても良かったです。

ローディング画面があるだけで良い感じのアプリに見えるので、もし実装を考えていたら参考にしてください。

ではでは。

soehina
ruby on rails を中心にアプリ開発を学んでいます。 フロントに興味があるのでJavascriptとReactも勉強中。 現在は大阪にてSESをしており、たまにWebライティングもしております。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした