カーテンみたいに両側に開いていくローディング画面をJavaScriptで実装してみる(備忘録)

今回はJavaScriptを用いて、カーテンみたいに両側に開いていくローディング画面を実装してみる。

それでは解説に入っていく。

htmlの記述について

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>ローディング</title>
  <link rel="stylesheet" href="../reset.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div id="js_loading" class="bl_loading">
    <div class="bl_loadingLeft">
      <div class="bl_loadingCircle"></div>
    </div>
    <div class="bl_loadingRight">
      <div class="bl_loadingText">loading...</div>
    </div>
  </div>
  <main>
    <section>
      <div class="ly_inner" id="menu1">
        <h2>menu1</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu2">
        <h2>menu2</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu3">
        <h2>menu3</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu4">
        <h2>menu4</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
    <section>
      <div class="ly_inner" id="menu5">
        <h2>menu5</h2>
        <div class="md_textblock">
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
          <p>テキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入りますテキストが入ります</p>
        </div>
      </div>
    </section>
  </main>
  <script src="style.js"></script>
</body>
</html>

今回は左半分と右半分で、表示させる要素を分けるために、下記のように組んでいる。

<div id="js_loading" class="bl_loading">
  <div class="bl_loadingLeft">
    <div class="bl_loadingCircle"></div>
  </div>
  <div class="bl_loadingRight">
    <div class="bl_loadingText">loading...</div>
  </div>
</div>

bl_loadingLeftで左半分の要素、bl_loadingRightで右半分の要素といった形にしている。

左半分にはぐるぐる回る要素を、右半分にはLoading…のテキスト要素を入れて分かりやすいようにしているつもりだ。

実際には中にテキストを入れて組むことは少ないかと思うので、入れなくてもOKだ。

cssの記述について

@charset "utf-8";

/* ==========================
  初期設定
========================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}
img {
  width: 100%;
}

/* ==========================
  ローディング画面
========================== */
.bl_loading {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  color: #fff;
  font-size: 12px;
}
.bl_loadingLeft {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background-color: #444;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: 0.5s;
}
.bl_loadingRight {
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
  background-color: #444;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: 0.5s;
}
@keyframes loadingCircle {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
@keyframes loadingText {
  50% {
    opacity: 0.3;
    transform: scale(1.1);
  }
}
.bl_loadingCircle {
  animation: 3s linear loadingCircle infinite;
  height: 30px;
  width: 30px;
  border: 1px solid #fff;
  border-top: 1px solid #aaa;
  border-radius: 50%;
  content: "";
}
.bl_loadingText {
  animation: 0.6s loadingText infinite;
}
#js_loading.loaded > .bl_loadingLeft {
  transform: translateX(-100%);
}
#js_loading.loaded > .bl_loadingRight {
  transform: translateX(100%);
}

/* ==========================
  コンテンツの中身
========================== */
.ly_inner {
  width: 100%;
  max-width: 1080px;
  margin: 100px auto;
  padding: 20px;
  background-color: #ccc;
}
.ly_inner h2 {
  font-size: 150%;
  font-weight: bold;
  margin-bottom: 30px;
}
.md_textblock > * + * {
  margin-top: 10px;
}

bl_loadingの大枠の部分で、要素が固定されるようにpositionをfixedにして組んでいる。これは下記のページでも触れているので解説は省略したい。

参考ページはこちら

左半分と右半分の対応

.bl_loadingLeft {
  position: absolute;
  top: 0;
  left: 0;
  width: 50%;
  height: 100%;
  background-color: #444;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: 0.5s;
}
.bl_loadingRight {
  position: absolute;
  top: 0;
  right: 0;
  width: 50%;
  height: 100%;
  background-color: #444;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: 0.5s;
}

実際にやっているのは同じようなことで、bl_loadingに対してfixedを設定しているので、bl_loadingLeftやbl_loadingRightに対してはpositionをabsoluteにすることで、bl_loadingの左上の基準に合うようになる。

あとはこれに対して、topを0にして、左半分の時はleftを0に、右半分の時はrightを0にして、幅(width)を50%、高さ(height)を100%にし、背景色を任意の色に設定すればOKだ。

また、テキストなどを左半分の上下中央に配置したい場合は、display以降の記述をするとうまくいくかと思う。

transitionを最後に記述しているのは、javascript側でloadedのクラスが付与されるようにしているので、それがついた時にアニメーションされるように対応している。

これで以上になるが、実際には上記のように同じような記述がある場合は、CSSをまとめて省略して記述することが多いので、興味があれば調べてみてほしい。

また、その他の記述部分については、過去ページで触れているので解説は省略したいと思う。

JavaScriptの記述について

'use strict';

// ローディング画面
function loadedPage() {
  const loadingID = document.getElementById("js_loading");
  loadingID.classList.add("loaded");
}
window.addEventListener('load', function () {
  setTimeout(loadedPage, 2000);
});
setTimeout(loadedPage, 5000);

こちらも過去ページの記述と変わっていないため、解説は省略したい。

これで実装完了だ。