JavaScript 30 — Day 2
JS and CSS Clock
教學來源: https://javascript30.com/。
推薦快速導讀頻道:
Day 2 實作主題:時鐘
畫面開啟就會顯示當前的時間,包含時、分、秒。
列出 todolist
- 將時針、分針、秒針初始位置的 css 設定好
- 查詢計時器的用法,取得當下時間,並換算時針、分針、秒針在時鐘上的角度,更改 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 用來計算時間的方法有三個:
- setInterval ( )
- setTimeout( )
- window.requestAnimationFrame ( )
Interval:間隔。setInterval ( ) 表每隔一個設定的時間就會重複執行,不設定停止就會一直持續,常用在時間或是輪播。
timeout:暫停,延遲。setTimeout( ) 設定延遲,執行一次,如果要持續執行就要在 function 裡呼叫自己。
專門處理畫面更新的 setTimeout (用法很像)
觸發的點是畫面硬體更新,不用再設定時間,但需要自己呼叫自己,不然也只會執行一次。
補充觀念:
程式的處理速度跟畫面的呈現速度不會一樣,程式可以負荷但螢幕不一定可以。
通常一般的畫面是 1000 毫秒 60Hz,表一秒可以更新 60 次,有些比較好的螢幕可以到 120Hz 甚至 144Hz,requestAnimationFrame() 就是依據畫面硬體更新才觸發。
假設是做 canvas 複雜的動畫,要畫面展現的比較流暢就建議使用window.requestAnimationFrame,但此範例其實用 setTimeout 或是setInterval 就足夠。
總結學習成果:
- 立即函式
目的 - 作程式的封裝,把程式都包在立即函式裡面,一開啟就執行立即函式,code 就會被啟動,但程式又不會外露到外層,不會讓別人可以用console 去操控程式碼。
在立即函式前加分號 (;) 是保護程式碼,如果有載入其他程式作封裝或是載入 library,立即函式可能會出錯,前面加分號比較安全,分號是避免跟別的 code 連在一起。 - 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