今日の年月日をスロット風アニメーションで表示 jQuery $.each()とfor()

Adobe XDの無料UIキットページからダウンロードしたAuto-Animate(解凍後のファイル名はxd-resources-auto-animate-ui.xd)に、スロット風に数字が回転されて表示されるアニメーションがありました。
そこから発想を得て、今日の年月日をスロット風に表示してみました。

おおまかな流れは、まずJavaScriptで今日の日付を取得し一文字ずつに分解します。
そして、jQueryの$.eachメソッドの中にfor文を入れて各数字をHTMLの該当箇所に挿入していきます。
CSSの方では、挿入された数字を縦に並べ、上方向へ移動するアニメーションをつけます。

因みにスロットの数字が並べられた回転するアレは「リール」というそうです。
コメントアウトに「リール」という言葉が出てきますので念のため。

各数字の回転アニメーションを同時に終了させる

CODEPEN

「Run Pen」をクリックしてください。右下の「Rerun」で再生できます。

See the Pen date slot display in order at the same time by blue moon (@blue-moon) on CodePen.

HTML

1文字ずつに分割した数字を挿入するタグには、IDを割り当てています。
但し、2100年以降は考慮していないため西暦の1桁目と2桁目箇所にはIDは割り当てず、今日の数字の前のリールに並ぶ0~9の数字は最初からHTMLに入れています。

<body>
  <div class="counter">

    <div class="year">
      <div class="fix-number">
        <span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span><span>0</span><span>1</span><span>2</span>
      </div>
      <div class="fix-number">
        <span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span><span>0</span>
      </div>
      <div id="change-number-1" class="change-number"></div>
      <div id="change-number-2" class="change-number"></div>
    </div>

    <div class="month">
      <div id="change-number-3" class="change-number"></div>
      <div id="change-number-4" class="change-number"></div>
    </div>

    <div class="date">
      <div id="change-number-5" class="change-number"></div>
      <div id="change-number-6" class="change-number"></div>
    </div>

  </div>
</body>

CSS

body {
  background: #010353;
  font-family: sans-serif;
  font-size: 50px;
  font-weight: 700;
  line-height: 1.6;
  color: #ff53c3;
}

.counter {
  display: flex;
  width: fit-content;
  margin: 50px auto;
}

.counter > div {
  margin: 0 8px;
  width: fit-content;
  height: 76px;
  display: flex;
  overflow-y: hidden; /* 各リールに数字は縦に長く並ぶが、表示は1文字のみ */
}

.fix-number,
.change-number {
  width: 52px;
  height: fit-content;
  display: flex;
  flex-direction: column; /* スロットのリールに数字を縦に並べる */
  /* アニメーションは1回、弾むように始まり弾むように終わり、最後の状態をキープ */
  animation: displayAnim 3s cubic-bezier(0.55, -0.17, 0.74, 1.29) forwards;
}

/*
 * リールをY方向に移動するアニメーション
 * アニメーション最後の位置は、最後の数字の高さ分下げる
 * font-size: 50px; line-height: 1.6; より、50px × 1.6 = 80px と算出
 */
@keyframes displayAnim {
  0% { transform: translateY(0%); }
  100% { transform: translateY(calc(-100% + 80px)); }
}

span {
  display: inline-block;
  text-align: center;
}

JS

$(document).ready(function () {

  // 今日の年月日を取得
  const today = new Date();
  const yearNum = today.getFullYear();
  const monthNum = today.getMonth() + 1;
  const dateNum = today.getDate();

  //分割するため一旦文字列に変換
  const yearSt = String(yearNum); //西暦
  const monthSt = String(('0' + monthNum).slice(-2)); //月の前に0を付け足し後ろから2文字を取得
  const dateSt = String(('0' + dateNum).slice(-2)); //日の前に0を付け足し後ろから2文字を取得

  // 取得した年月日を1文字ずつに分割し数値に変換
  const yearNum3 = Number((yearSt).slice(2, 3)); //西暦の3桁目
  const yearNum4 = Number((yearSt).slice(3, 4)); //西暦の4桁目
  const monthNum1 = Number((monthSt).slice(0, 1)); //月の1桁目
  const monthNum2 = Number((monthSt).slice(1, 2)); //月の2桁目
  const dateNum1 = Number((dateSt).slice(0, 1)); //日の1桁目
  const dateNum2 = Number((dateSt).slice(1, 2)); //日の2桁目

  // 数字を代入する要素を全て取得
  const changeNum = $('.change-number');

  //0~9の数字をスロットの各リールに追加
  const beforeNum = '<span>0</span><span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span><span>8</span><span>9</span>';
  changeNum.each(function () {
    $(this).append(beforeNum);
  });

  // 今日の日付を分割した数字のオブジェクトを用意(上記の数字の後に追加するもの)
  const obj = {
    1: yearNum3,
    2: yearNum4,
    3: monthNum1,
    4: monthNum2,
    5: dateNum1,
    6: dateNum2,
  }

  // スロットの各リールに今日の日付の数字が最後になるまで数字を追加していく
  $.each(obj, function (key, val) {
    for (let i = 0; i < val + 1; i++) {
      $("#change-number-" + key).append(`<span>${i}</span>`);
    }
  });

});

日付の1桁目が数字の9の場合、HTMLは下記のように出力されます。

date_counter_html

各数字の回転アニメーションを順番に終了させる

CODEPEN

「Run Pen」をクリックしてください。

See the Pen date slot display in order by blue moon (@blue-moon) on CodePen.

CSS

CSSのみ下記を追記変更しています。

.fix-number,
.change-number {
  width: 52px;
  height: fit-content;
  /* アニメーション時間は個別に設定するため、durationを削除 */
  animation: displayAnim cubic-bezier(0.55, -0.17, 0.74, 1.29) forwards;
  display: flex;
  flex-direction: column;
}

.fix-number:nth-child(1) {
  animation-duration: 2.85s;
}

.fix-number:nth-child(2) {
  animation-duration: 2.9s;
}

.year .change-number:nth-of-type(3) {  /* 兄弟要素の中で3番目 */
  animation-duration: 2.95s;
}

.year .change-number:nth-of-type(4) {  /* 兄弟要素の中で4番目 */
  animation-duration: 3s;
}

.month .change-number:nth-child(1) {
  animation-duration: 3.05s;
}

.month .change-number:nth-child(2) {
  animation-duration: 3.1s;
}

.date .change-number:nth-child(1) {
  animation-duration: 3.15s;
}

.date .change-number:nth-child(2) {
  animation-duration: 3.2s;
}
タイトルとURLをコピーしました