iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 2
0
Modern Web

寫JS30天系列 第 2

JS 30 - 02 - JS and CSS Clock

  • 分享至 

  • xImage
  •  

今天我們要來做個時鐘,首先我們使用new Date()「在開啟網頁時」拿到當下時間

首先看到時鐘會發現秒針、分針、時針都是在9點鐘方向
所以要先記得一件事「之後要轉到12點鐘」
因為我們要從12點鐘(0度)開始轉
我們使用setInterval(fn, 1000)來設定1秒執行一次設定鐘面的function setDate

let secHand = document.querySelector('.second-hand'); //秒針
let minHand = document.querySelector('.min-hand'); //分針
let hrHand = document.querySelector('.hour-hand'); //時針
let now = new Date(); //當下時間
let secs = now.getSeconds();  //取得當下秒
let mins = now.getMinutes(); //取得當下分
let hrs = now.getHours(); //取得當下時

function setDate(){
    //計算各個指針應該有的角度
}
setInterval(setDate, 1000);//每隔1秒執行一次時鐘的設置

時鐘上顯示的刻度是「開啟網頁的當下時間」+「過了幾秒」
因此我們要算兩個角度之和

所以我們要使用一個計「秒」器secCount,來知道距離第一次擷取時間後「過了幾秒」
對於「秒」來說,一秒移動(360/60)度
對於「分」來說,一秒移動(360/60/60)度,一分移動(360 / 60)度
對於「時」來說,一秒移動約(360/60/60/12)度一分移動(360 / 60 / 12)度,一時移動(360 / 12)度

所以要計算出初始角度就會像下面的程式碼,並在計算好角度後,將secCount加一
算完角度記得要再將90度加上

let round = 0;
let secCount = 0
function setDate(){
    //90deg 是將指針從 9 時移動到 12 時
    //secCount 是每一秒的位移量
    let secsDegree = (secs + secCount) * 360 / 60 + 90;
    let minsDegree = (mins) * 360 / 60 + (secs + secCount) * 360 / 60 / 60 + 90;
    let hrsDegree = (hrs) * 360 / 12 + mins * 360 / 60 / 12 + (secs + secCount) * 360 / 60 / 60 / 12 + 90;
    secCount += 1;
}

會使用計秒器的方式是因為:如果一直使用getSecond()getMinute()getHours
在進位時會從59秒變成0秒;從59分變0分;從11時邊0時,這時候會因為 css 的transition動畫效果的計算,會將0~59切成59份,在1秒內播完,如果將transition改成2s 會很明顯發現指針逆時針旋轉了一圈

最後,再將算出的角度渲染到 html 上

function setDate(){
    secHand.style.transform = `rotate(${secsDegree}deg)`;
    minHand.style.transform = `rotate(${minsDegree}deg)`;
    hrsHand.style.transform = `rotate(${hrsDegree}deg)`;
}

這時你會發現一個問題,每次進入網頁時,指針都會從9時的位置轉到正確的時間上,這是因為我們並沒有在setInterval(setDate, 1000)之前先呼叫一次setDate(),所以0秒的時候,會直接用 css 的樣式,三種指針都是0deg,直到第一秒才會渲染角度上去,這時候因為transition效果產生了動畫,因此我們要在在第一時間就呼叫一次setDate()

function setDate(){
    //計算各個指針應該有的角度
}
setDate();
setInterval(setDate, 1000);

完整程式碼;
Demo


上一篇
JS 30 - 01 - drum kit
下一篇
JS 30 - 03 - CSS Variables
系列文
寫JS30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言