JavaScript 30 — Day 2

Chloe Lo
chloelo925
Published in
5 min readApr 15, 2019

JS and CSS Clock

教學來源: https://javascript30.com/

推薦快速導讀頻道:

[ Alex 宅幹嘛 ] 👨‍💻 深入淺出 Javascript30 快速導覽:Day 2:CSS + JS Clock

Day 2 實作主題:時鐘

畫面開啟就會顯示當前的時間,包含時、分、秒。

列出 todolist

  1. 將時針、分針、秒針初始位置的 css 設定好
  2. 查詢計時器的用法,取得當下時間,並換算時針、分針、秒針在時鐘上的角度,更改 css 旋轉樣式設定

此題原設定樣式如上,三個指針皆同樣粗細,同樣位置,自己微調了這部分的 css,途中遇到了一個小問題,在同一個父層 (相對定位) 的狀況下,子層 (絕對定位)各自因為寬度不同去做旋轉時,位置會偏移掉,該如何解決?

三個指針設定自身為父元素 (絕對定位),將實際指針樣式放置於偽元素 (絕對定位)中

可以參照原始碼如下,旋轉時 hour-hand、min-hand、second-hand 是整個區塊轉,樣式放在偽元素中不會被偏移,編碼也比較乾淨。

此篇實作主要用到數學與 JavaScript 計時器的概念

先算出:

360 度 / 60 (一圈 60 秒,分) => 一格 6 度 (秒,分)360 度 / 12 (一圈 12 小時) => 一格 30 度 (小時)

但分針與時針還有細節要處理,假設時間是 1 點 37 分 21 秒,時針不會剛好在 1 的位置,會因為 37 分 讓時針介於 1 與 2 之間,更靠近 2 一點,這個角度也要算進去才能算是精準的時針位置,同理可證,分針也會因為秒數位置要再計算角度。

  • 秒針角度 =
    佔整圈的百分比 (當前秒數 / 60 秒 (一圈)) * 360 度
  • 分針角度 =
    佔整圈的百分比 (當前分鐘數 / 60 分 (一圈)) * 360 度 + 分鐘累進角度 (當前秒數 / 60秒 (一圈) * 一格 6 度
  • 時針角度 =
    佔整圈的百分比 (當前小時數 / 12 小時 (一圈)) * 360 度 + 小時一格累進角度 (當前分鐘數 / 60分 (一圈) * 一格 30 度

困難的數學運算完之後就是取得確切的時、分、秒時間與運用計時器的方法,這題就可以完成了。

複習 new Date ( ) 的用法:(擷取提供的網址上幾個常用內容)

JavaScript 用來計算時間的方法有三個:

  1. setInterval ( )
  2. setTimeout( )
  3. window.requestAnimationFrame ( )

setInterval ( )

Interval:間隔。setInterval ( ) 表每隔一個設定的時間就會重複執行,不設定停止就會一直持續,常用在時間或是輪播。

setTimeout( )

timeout:暫停,延遲。setTimeout( ) 設定延遲,執行一次,如果要持續執行就要在 function 裡呼叫自己。

window.requestAnimationFrame ( )

專門處理畫面更新的 setTimeout (用法很像)
觸發的點是畫面硬體更新,不用再設定時間,但需要自己呼叫自己,不然也只會執行一次。

補充觀念:

程式的處理速度跟畫面的呈現速度不會一樣,程式可以負荷但螢幕不一定可以。

通常一般的畫面是 1000 毫秒 60Hz,表一秒可以更新 60 次,有些比較好的螢幕可以到 120Hz 甚至 144Hz,requestAnimationFrame() 就是依據畫面硬體更新才觸發。

假設是做 canvas 複雜的動畫,要畫面展現的比較流暢就建議使用window.requestAnimationFrame,但此範例其實用 setTimeout 或是setInterval 就足夠。

程式碼完整版

總結學習成果:

  1. 立即函式
    目的 - 作程式的封裝,把程式都包在立即函式裡面,一開啟就執行立即函式,code 就會被啟動,但程式又不會外露到外層,不會讓別人可以用console 去操控程式碼。
    在立即函式前加分號 (;) 是保護程式碼,如果有載入其他程式作封裝或是載入 library,立即函式可能會出錯,前面加分號比較安全,分號是避免跟別的 code 連在一起。
  2. JavaScript 三種計時器:
    setInterval ( )、setTimeout( )、window.requestAnimationFrame ( )

完成的實作範例:
https://chloelo.github.io/JavaScript30/02-JS_and_CSS_Clock/index-chloe.html

原始碼:
https://github.com/chloelo/JavaScript30/tree/master/02-JS_and_CSS_Clock

--

--