Day2 JS and CSS Clock


Demo

設定CSS

文件一開始的CSS並還沒設定好,在.hand這個class有留下幾個關鍵的屬性讓我們自己去操作/認識:

  1. transform-origin:調整旋轉的軸心位置。更多transform-origin介紹
  2. transform: rotate(90deg):將指針重設到00:00
  3. transition-timing-function : 動畫變換的速度。可以從開發者工具去嘗試不同的速度變化。
  4. transition的4個屬性
    1
    transition: property duration timing-function delay;

取得時間

在這個範例中並沒有透過setInterval不斷地去取得時間,只在載入畫面時去取得一次當下的時間,後續變化時間再透過setInterval()去遞加上去。

在作者提供的原始Code當中,我們會發現秒針在59跳回0秒的時候,會出現一個神奇的情況。秒針會瞬間逆時針轉回0度再馬上轉回到目前的位置。這是因為作者在旋轉角度的寫法,是將當下的時間換算成角度,因此當秒針從59秒要跳回0秒的時候,transform的rotate角度會由接近360轉回接近0度,以致於逆時針旋轉的產生。而在我們的code當中,因為旋轉角度是用每秒增加的方式加上去,因此不會有此現象的產生,各位讀者如果是依照JS30作者的方法練習的話,可以嘗試參考我們文章中的設定內容,便可以消除秒針的在位置的小插曲。

資料來源-王郁翔-好想工作室

所以我們先在全域中取得時間

1
2
3
4
const now = new Date()
const seconds = now.getSeconds()
const mins = now.getMinutes()
const hours = now.getHours()

算數學

整個範例的關鍵應該就是要把時間值轉換成角度
60秒=360度,所以每秒轉6度
60分=360度,所以每分轉6度
12時=360度,所以每時轉30度
+90是因為一開始我們已經手動將指針旋轉90度至00:00,所以起點是從90度開始

個人習慣用乘法比較容易理解

一樣在全域中先轉換成角度

1
2
3
4
5
6
var s_deg = seconds*(360/60) + 90
var m_deg = mins*(360/60) + 90
var h_deg = hours*(360/12) + 90
//秒*6度
//分*6度
//時*30度

但是!分針和時針不可能永遠只在6、12、18或30、60、90..這些位置呀!

以15:40:29秒為例,時針卻直挺挺的指在三點整的位置,顯然不是太正確的時鐘。

所以我們需要加入現在秒數對分針而言多幾度以及現在的分數對時針而言要多幾度。(有點饒舌)
1.分針需要加入秒針走的角度,每60秒,分針加6度;每1秒,分針加6/60度

(seconds/60)*6 或 seconds*(6/60)

2.時針需要加入分針走的角度,每60分,時針加30度;每1分,時針加30/60(1/2)度

(mins/60)*30 或 mins*(30/60)

加完後

1
2
3
var s_deg = seconds*(360/60) + 90
var m_deg = mins*(360/60) + seconds*(6/60) + 90
var h_deg = hours*(360/12) + mins*(30/60) + 90

細節

  • 延遲
    這個範例中我們只用setInterval呼叫timeSet()
    也就是畫面載入後1秒,時間才會顯示,所以我們可以一開始就先跑一次timeSet()

  • transition
    按照原本案例寫的話,每當秒數從59-0的時候,會有一個小bug
    這裡有很好的說明(小插曲)

讓時鐘動起來

最後我們每秒呼叫一次timeSet讓各個角度不斷地累加上去

1
2
3
4
5
6
7
8
9
10
function timeSet(){
s_deg += 360/60 //每秒6度
m_deg += 360/(60*60) //每秒6/60度;每60秒6度;
h_deg += 360/(60*60*12)

secondPin.style.transform = `rotate(${s_deg}deg)`
minPin.style.transform = `rotate(${m_deg}deg)`
hourPin.style.transform = `rotate(${h_deg}deg)`
}
setInterval(timeSet,1000)

程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
const secondPin = document.querySelector('.second-hand')
const minPin = document.querySelector('.min-hand')
const hourPin = document.querySelector('.hour-hand')

const now = new Date()
const seconds = now.getSeconds()
const mins = now.getMinutes()
const hours = now.getHours()

var s_deg = (seconds/60)*360 + 90
var m_deg = (mins/60)*360 + seconds*(6/60) + 90
var h_deg = (hours/12)*360 + mins*(30/60) + 90

function timeSet(){

s_deg += 360/60
m_deg += 360/(60*60)
h_deg += 360/(60*60*12)

secondPin.style.transform = `rotate(${s_deg}deg)`
minPin.style.transform = `rotate(${m_deg}deg)`
hourPin.style.transform = `rotate(${h_deg}deg)`
}
timeSet()
setInterval(timeSet,1000)

不負責任聲明ಥ◡ಥ:
純屬個人筆記,每個範例都有不同的寫法,還有很多細節可以加入,甚至可能有看不到的bug,有任何問題都歡迎提出一起研究哦,我會很感謝您的!沒有好不好,只有適不適合 - 2018.08.08

祝爸爸父親節快樂<3 原本想說要回家替爸爸慶祝一下,但我爸說只要不要讓他操心就是孝順了(因為我剛離職XD),但這個離職就是為了找到更好的工作不讓他擔心我的未來呀ಥ◡ಥ

0%