WEBサイトにデジタル時計を表示 オブジェクトに関数を渡してループ処理、CSSで数字毎にバーを表示

JavaScriptで現在時間を取得し、jQueryとCSSでWEBサイト上に時刻をデジタル表示してみました。
単に時刻を表示するだけのノーマルなバージョンと、少し時計に見立てたバージョンを作成しました。
現在時刻をWEBサイトに表示する機会は少ないかもしれませんが、ご参考になれま幸いです。

digital-clock

使用するファイル

  • HTMLファイル
  • CSSファイル(今回はボリュームもあるためSCSSを使用しています。やはり慣れるとこちらの方が書きやすいです。)
    ベンダープレフィックスはある程度はつけていますが、省略している箇所もあると思いますので、必要に応じて加筆修正してください。
  • JSファイル
    jQueryを事前に読み込んでおいてください。

時刻をデジタル表示するだけのノーマルなバージョン

一応、取得した時刻とデジタル表示が一致しているか確認するため、下部に確認のための時間を表示していますが、確認できたら削除してください。

CODEPEN で実装と確認

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

See the Pen digital clock normal by blue moon (@blue-moon) on CodePen.

HTMLファイル

<body>
  <ul>
    <li id="hours-first">
      <div class="bar">
        <div class="top"></div>
        <div class="middle"></div>
        <div class="bottom"></div>
        <div class="left-top"></div>
        <div class="left-bottom"></div>
        <div class="right-top"></div>
        <div class="right-bottom"></div>
      </div>
    </li>
    <li id="hours-second">
      <div class="bar">
        <div class="top"></div>
        <div class="middle"></div>
        <div class="bottom"></div>
        <div class="left-top"></div>
        <div class="left-bottom"></div>
        <div class="right-top"></div>
        <div class="right-bottom"></div>
      </div>
    </li>
    <li class="colon">
      <div class="colon-top"></div>
      <div class="colon-bottom"></div>
    </li>
    <li id="minutes-first">
      <div class="bar">
        <div class="top"></div>
        <div class="middle"></div>
        <div class="bottom"></div>
        <div class="left-top"></div>
        <div class="left-bottom"></div>
        <div class="right-top"></div>
        <div class="right-bottom"></div>
      </div>
    </li>
    <li id="minutes-second">
      <div class="bar">
        <div class="top"></div>
        <div class="middle"></div>
        <div class="bottom"></div>
        <div class="left-top"></div>
        <div class="left-bottom"></div>
        <div class="right-top"></div>
        <div class="right-bottom"></div>
      </div>
    </li>  
  </ul>
  <div class="confirm">
    <div class="check">確認のための時間表示</div>
    <div class="time"></div>
  </div>
</body>

CSSファイル

body {
  background-color: #fefefe;
  font-size: 20px;
  color: #808080;
}

ul {
  margin: 30px auto;
  padding: 0;
  width: 320px;
  height: 110px;
  display: flex;
  list-style: none;
  justify-content: space-around;
  transform: skewX(-5deg);
}

li {
  width: 18%;
  height: 100%;
}

.bar {
  position: relative;
  width: 100%;
  height: 100%;
}

.top,
.middle,
.bottom,
.left-top,
.left-bottom,
.right-top,
.right-bottom {
  position: absolute;
  display: none;
  background-color: #808080;
  transition: all 0.5s ease-in-out;
}

.top,
.middle,
.bottom {
  left: 7%;
  width: 86%;
  height: 10px;
  clip-path: polygon(12.5% 0, 87.5% 0, 100% 50%, 87.5% 100%, 12.5% 100%, 0% 50%);
}

.left-top,
.left-bottom,
.right-top,
.right-bottom {
  height: 45%;
  width: 10px;
  clip-path: polygon(50% 0, 100% 10%, 100% 90%, 50% 100%, 0 90%, 0 10%);
}
.top {
  top: 0;
}

.middle {
  top: calc(50% - 5px);
}

.bottom {
  bottom: 0;
}

.left-top {
  top: 5%;
  left: -2.5%;
}

.left-bottom {
  bottom: 5%;
  left: -2.5%;
}

.right-top {
  top: 5%;
  right: -2.5%;
}

.right-bottom {
  bottom: 5%;
  right: -2.5%;
}
.zero .bar div:not(.middle) {
  display: block;
}

.one .bar .right-top,
.one .bar .right-bottom {
  display: block;
}

.two .bar .top,
.two .bar .middle,
.two .bar .bottom,
.two .bar .left-bottom,
.two .bar .right-top {
  display: block;
}

.three .bar .top,
.three .bar .middle,
.three .bar .bottom,
.three .bar .right-top,
.three .bar .right-bottom {
  display: block;
}

.four .bar .middle,
.four .bar .left-top,
.four .bar .right-top,
.four .bar .right-bottom {
  display: block;
}

.five .bar .top,
.five .bar .middle,
.five .bar .bottom,
.five .bar .left-top,
.five .bar .right-bottom {
  display: block;
}

.six .bar div:not(.right-top) {
  display: block;
}

.seven .bar .top,
.seven .bar .right-top,
.seven .bar .right-bottom {
  display: block;
}

.eight .bar div {
  display: block;
}

.nine .bar div:not(.left-bottom) {
  display: block;
}
.colon {
  width: 5%;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;
}

.colon-top,
.colon-bottom {
  width: 8px;
  height: 8px;
  border-radius: 3px;
  background-color: #808080;
}

.confirm {
  width: 320px;
  margin: 0 auto;
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
}

.time {
  width: 30%;
}

.check {
  width: 70%;
}

補足説明

数字の数だけ、数字を形作るバーの表示がそれぞれ異なるので、必然的に長くなってしまいました。
特筆すべき点は、バーの変形を clip-path: polygon() で作成している点です。幅や高さは別途設定しています。
バーの数が多い(7本!)ですから、疑似要素 ::befotre,::after で三角形を作って両端にくっつけて…とはしませんでした。

JSファイル

const time = () => {  // 時刻表示の関数作成
  
  // 2桁表記(8:10 を 08:10 とするための関数)
  const toDoubleNum = function(num) {
    num += "";
    if (num.length === 1) {
      num = "0" + num;
    }
   return num;     
  };

  const now = new Date(); //現在の日時を取得
  const h = toDoubleNum(now.getHours()); //時間のみ取得し2桁に
  const m = toDoubleNum(now.getMinutes()); //分のみ取得し2桁に
  
  const h1 = (h).slice(0,1); //1桁目の数値を取得
  const h2= (h).slice(-1); //2桁目の数値を取得
  const m1 = (m).slice(0,1);
  const m2= (m).slice(-1);
  
  // デジタル表示と実際の時間確認のため表示
  $('.time').text( h1 + h2 + ':' + m1 + m2 ); 

  const h1elem = $('#hours-first');
  const h2elem = $('#hours-second');
  const m1elem = $('#minutes-first');
  const m2elem = $('#minutes-second');

  // 時間の各数値と対応するクラスの組合わせのオブジェクトを作成
  const obj = [
    { time: h1, elem: h1elem },
    { time: h2, elem: h2elem },
    { time: m1, elem: m1elem },
    { time: m2, elem: m2elem },
  ];

  // クラスを付与する関数を作成
  function add (time, elem) {
    elem.removeClass(); //現在のクラスはここで一旦削除
    if (time == 1) {
      elem.addClass('one');
    } else if (time == 2) {
      elem.addClass('two');
    } else if (time == 3) {
      elem.addClass('three');
    } else if (time == 4) {
      elem.addClass('four');
    } else if (time == 5) {
      elem.addClass('five');
    } else if (time == 6) {
      elem.addClass('six');
    } else if (time == 7) {
      elem.addClass('seven');
    } else if (time == 8) {
      elem.addClass('eight');
    } else if (time == 9) {
      elem.addClass('nine');
    } else {
      elem.addClass('zero');
    }
  }

  // 先に作成したオブジェクトに対して関数を実行
  $.each(obj, function(index, val) {
    add(val.time, val.elem);
  });
    
};
time();  // 時刻表示の関数呼び出し

//最初に時刻表示した後は、1分後に表示を変更する
const timeUpdate = () => {  // 1分後に時刻表示の関数を呼び出す関数作成
  time();
  setTimeout(timeUpdate, 60000);  // 1分間隔
};

timeUpdate();

補足説明

下記のことを行っています。

  • 現在時刻を取得する関数を作成し、最初の1回実行
  • 取得した現在時刻のうち、使用する時間と分を2桁表示にし、それぞれ1文字ずつに分割
  • 各数値とそれを表示するHTML要素を組み合わせたオブジェクトを作成
  • バーを表示するためのクラスを付与する関数を作成
  • 作成しておいたオブジェクトに関数を渡し、ループ処理 eachメソッド
  • 現在時刻を取得する関数を1分間隔で処理する関数を作成し実行

時計に見立てたバージョン

時刻表示部分を少し凹ませ、よく見ないと気づきにくいですが、その上に透明なパネル(ガラス又はプラスチック)を被せた風に仕上げてみました。

CODEPEN で実装と確認

See the Pen digital clock arrange 1 by blue moon (@blue-moon) on CodePen.

HTMLファイル

<body>
  <div class="digital">
    <ul>
      <li id="hours-first">
        <div class="bar">
          <div class="top"></div>
          <div class="middle"></div>
          <div class="bottom"></div>
          <div class="left-top"></div>
          <div class="left-bottom"></div>
          <div class="right-top"></div>
          <div class="right-bottom"></div>
        </div>
      </li>
      <li id="hours-second">
        <div class="bar">
          <div class="top"></div>
          <div class="middle"></div>
          <div class="bottom"></div>
          <div class="left-top"></div>
          <div class="left-bottom"></div>
          <div class="right-top"></div>
          <div class="right-bottom"></div>
        </div>
      </li>
      <li class="colon">
        <div class="colon-top"></div>
        <div class="colon-bottom"></div>
      </li>
      <li id="minutes-first">
        <div class="bar">
          <div class="top"></div>
          <div class="middle"></div>
          <div class="bottom"></div>
          <div class="left-top"></div>
          <div class="left-bottom"></div>
          <div class="right-top"></div>
          <div class="right-bottom"></div>
        </div>
      </li>
      <li id="minutes-second">
        <div class="bar">
          <div class="top"></div>
          <div class="middle"></div>
          <div class="bottom"></div>
          <div class="left-top"></div>
          <div class="left-bottom"></div>
          <div class="right-top"></div>
          <div class="right-bottom"></div>
        </div>
      </li>
    </ul>
  </div>
  <div class="confirm">
    <div class="check">確認のための時間表示</div>
    <div class="time"></div>
  </div>
</body>

補足説明

前述のものからデジタル表示を入れるボックス(時計部分)のタグを追加しています。

SCSSファイル

.digital {
  margin: 30px auto;
  width: 370px;
  height: 160px;
  box-sizing: border-box;
  border: solid 10px #fefefe;
  border-radius: 10px;
  filter: drop-shadow(3px 3px 6px #808080);
  background-color: #fff;
}

ul {
  display: flex;
  margin: 5px auto;
  padding: 0;
  width: 340px;
  height: 130px;
  list-style: none;
  box-sizing: border-box;
  border-radius: 10px;
  background-color: #808080;
  justify-content: space-around;
  align-items: center;
  box-shadow: 3px 4px 8px 3px #000 inset;
  position: relative;
  &::before {
    position: absolute;
    top: 0;
    left: 0;
    content: "";
    height: 100%;
    width: 100%;
    z-index: 1;
    border-radius: 10px;
    opacity: 0.35;
    background: linear-gradient(135deg, rgba(193, 220, 242, 1) 0%, rgba(201, 223, 239, 1) 20%, rgba(255, 255, 255, 1) 50%, rgba(201, 223, 239, 1) 80%, rgba(189, 224, 249, 1) 100%
    );
  }
}

li {
  width: 16%;
  height: 80%;
  transform: skewX(-5deg);
}
.bar {
  position: relative;
  width: 100%;
  height: 100%;
  .top,
  .middle,
  .bottom,
  .left-top,
  .left-bottom,
  .right-top,
  .right-bottom {
    position: absolute;
    background-color: #fff;
    transition: all 0.5s ease-in-out;
    display: none;
  }
  .top,
  .middle,
  .bottom {
    left: 8%;
    width: 84%;
    height: 10px;
    clip-path: polygon(12.5% 0, 87.5% 0, 100% 50%, 87.5% 100%, 12.5% 100%, 0% 50%);
  }
  .left-top,
  .left-bottom,
  .right-top,
  .right-bottom {
    height: 44%;
    width: 10px;
    clip-path: polygon(50% 0, 100% 10%, 100% 90%, 50% 100%, 0 90%, 0 10%);
  }
  .top {
    top: 0;
  }
  .middle {
    top: calc(50% - 5px);
  }
  .bottom {
    bottom: 0;
  }
  .left-top {
    top: 5.5%;
    left: -2.5%;
  }
  .left-bottom {
    bottom: 5.5%;
    left: -2.5%;
  }
  .right-top {
    top: 5.5%;
    right: -2.5%;
  }
  .right-bottom {
    bottom: 5.5%;
    right: -2.5%;
  }
}

#hours-first {
  margin-left: 3%;
}

li#minutes-second {
  margin-right: 3%;
}
.zero .bar div:not(.middle) {
  display: block;
}

.one .bar {
  .right-top,
  .right-bottom {
    display: block;
  }
}

.two .bar {
  .top,
  .middle,
  .bottom,
  .left-bottom,
  .right-top {
    display: block;
  }
}

.three .bar {
  .top,
  .middle,
  .bottom,
  .right-top,
  .right-bottom {
    display: block;
  }
}

.four .bar {
  .middle,
  .left-top,
  .right-top,
  .right-bottom {
    display: block;
  }
}

.five .bar {
  .top,
  .middle,
  .bottom,
  .left-top,
  .right-bottom {
    display: block;
  }
}

.six .bar div:not(.right-top) {
  display: block;
}

.seven .bar {
  .top,
  .right-top,
  .right-bottom {
    display: block;
  }
}

.eight .bar div {
  display: block;
}

.nine .bar div:not(.left-bottom) {
  display: block;
}
.colon {
  width: 3%;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  align-items: center;
}

.colon-top,
.colon-bottom {
  width: 8px;
  height: 8px;
  border-radius: 3px;
  background-color: #fff;
}

.confirm {
  width: 320px;
  margin: 20px auto 0;
  display: flex;
}

.time {
  width: 30%;
}

.check {
  width: 70%;
}

補足説明

ボックス内にデジタル表示するため、要素の大きさや位置、影など、前述のものから細々と変更しています。
時計に被せる透明のパネルはグラデーションを生成し、opacityで透明度を調整しています。

JSファイル

前述のバージョンと変更ありません。

最後に

余談

腕時計や掛け時計であればアナログ表示が好みですが、デジタル時刻を壁や天井に投影する時計が便利です。
夜中に目が覚めてもスマホを見なくても天井や壁に投影された時間を確認できます。
吉高由里子主演ドラマ「わたし、定時で帰ります」(主人公が勤務するのはソフトウェア会社です)のオフィスで、時間が壁に投影されているようなのを見ていいなと思って調べてみたら、たくさん種類がありました。おすすめです。

参考: デジタルLED時計 時刻投影アラーム 壁/天井投影

睡眠時間にスマホに触ってしまうとついつい別のアプリも覗いてしまい、覚醒につながり寝つきが悪くなりますので、あまりよろしくないかと。

【後日追記】残り日数を表示する方法

サイト上で残り日数を表示する方法を下記で紹介していますので、ご参考までに。

タイトルとURLをコピーしました