Try   HackMD

Day2: JS and CSS Clock

竹白記事本,Javascript 30,紀錄。

tags: Javascript 30

實現效果

用 JS 與 CSS 搭配製作一個實時的時鐘效果。

重點

  • 建立指針 CSS 樣式
  • 取得指針 DOM
  • 建立控制時鐘函式
    • 取得現在時間
    • 控制 DOM 樣式
  • 建立計時器重複執行函式

基礎語法

JavaScript

BOM

說明

1. 將指針原始樣式改成 12 點鐘方向

課程提供的原始 CSS,在計算角度時,要補 90度,因此這邊會稍作修改。

2. 計算角度

一個圓有 360 度:

  • 60 秒
    • 360 / 60 = 6
    • 每秒轉 6 度
  • 60 分鐘
    • 360 / 60 = 6
    • 每分鐘轉 6 度
  • 12 個小時
    • 360 / 12 = 30
    • 每一小時轉 30 度

實作

1. 步驟

Step 1  調整 CSS

.clock-face 新增一個中心點方便定位。

.clock-face::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-color: white;
  width: 10px;
  height: 10px;
}

將原本的 .hand 改掉,

.hand {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

新增 .hour-hand .min-hand .second-hand

我們將指針的樣式寫在偽元素,這樣旋轉容器時,就會以中心旋轉。

並且將指針起點改成 12 點鐘方向,這樣就不用額外計算多出來的角度。

.hour-hand::after {
  position: absolute;
  content: '';
  width: 10px;
  height: 100px;
  background-image: linear-gradient(black 50%, transparent 50% 100%);
}
.min-hand::after {
  position: absolute;
  content: '';
  width: 10px;
  height: 200px;
  background-image: linear-gradient(black 50%, transparent 50% 100%);
}
.second-hand::after {
  position: absolute;
  content: '';
  width: 4px;
  height: 160px;
  background-image: linear-gradient(black 50%, transparent 50% 100%);
}

Step 2  取得指針的 DOM 物件

const hour = document.querySelector('.hour-hand');
const min = document.querySelector('.min-hand');
const second = document.querySelector('.second-hand');

Step 3 建立函式 setClock()

function setClock() {
  const now = new Date();

  let hourDeg = now.getHours() * 30;
  let minDeg = now.getMinutes() * 6;
  let secondDeg = now.getSeconds() * 6;

  hour.style.transform = `rotate(${hourDeg}deg)`;
  min.style.transform = `rotate(${minDeg}deg)`;
  second.style.transform = `rotate(${secondDeg}deg)`;
}

JavaScript 的 Date 物件只能以建構式的方式來產生,因此這裡用到 new 關鍵字,取得現在時間。

分別取得秒、分、時的時間,並計算角度,用來控制指針的旋轉度數。

Step 4 呼叫函式並加上計時器

setClock(); // 初始化畫面

setInterval(setClock, 1000);

setInterval 計時器,可以設定每隔一段時間重複執行,這裡設 1 秒。

另外關於畫面顯示的計時器也可以使用 requestAnimationFrame,它會跟據硬體的效能來控制更新頻率,簡單來說就是會以你硬體能顯示最大 FPS 來刷新頻率。

目前已完成初步功能。

Step 5 微調

由於現實中指針不會是時間一到就直接跳到下一格,因此這裡的時針與分針還需要補上一些細節。

  • 時針
    • 每小時一格有 30 度
    • 一小時有 60 分鐘
    • 因此角度還要加上「目前幾分 * (30 / 60)」
  • 分針
    • 每分鐘有 6 度
    • 每分鐘有 60 秒
    • 因此角度還要加上「目前幾秒 * (6 / 60)」

稍作微調程式碼:

let secondDeg = now.getSeconds() * 6;
let minDeg = now.getMinutes() * 6 + now.getSeconds() * (6 / 60);
let hourDeg = now.getHours() * 30 + now.getMinutes() * (30 / 60);

Step END

(function() {
  const hour = document.querySelector('.hour-hand');
  const min = document.querySelector('.min-hand');
  const second = document.querySelector('.second-hand');

  function setClock() {
    const now = new Date();

    let secondDeg = now.getSeconds() * 6;
    let minDeg = now.getMinutes() * 6 + now.getSeconds() * (6 / 60);
    let hourDeg = now.getHours() * 30 + now.getMinutes() * (30 / 60);

    second.style.transform = `rotate(${secondDeg}deg)`;
    min.style.transform = `rotate(${minDeg}deg)`;
    hour.style.transform = `rotate(${hourDeg}deg)`;
  }

  setClock(); // 初始化畫面

  setInterval(setClock, 1000);
})();

2. 實作連結