寫在系列開篇
在學(xué)習(xí)了基本的 HTML / CSS / JavaScript 之后沒有啥 side project 就直接開始學(xué) Angular 做項(xiàng)目。遇到最近很火的JavaScript30這個(gè)項(xiàng)目后決心好好實(shí)踐一下 Vanilla JavaScript球切。
對于每個(gè)挑戰(zhàn),我會自己在看過視頻了解原理后自己實(shí)現(xiàn)一遍并在 blog 里記錄過程、想法和相關(guān)資料。源碼放在我的 Github上,demo 通過 Github Pages 部署叨叙,點(diǎn)擊這里或 Github 的 readme 中連接可以訪問。
Objective
利用 CSS 和 JS 實(shí)現(xiàn)一個(gè)時(shí)鐘界面担敌,每秒更新三個(gè)指針的位置摔敛。
Steps
CSS 部分
- 設(shè)置指針旋轉(zhuǎn)的原點(diǎn)
transform-origin: right;
- 設(shè)置 CSS transition 模擬時(shí)鐘指針抖動廷蓉;
- 添加 CSS 樣式區(qū)別時(shí)針秒針全封。
JS 部分
- 獲取 Date 對象得到時(shí)間并計(jì)算需要轉(zhuǎn)動的角度马昙;
- 設(shè)置三個(gè)指針的 transform 屬性為
rotate(${xxxDegree}deg)
; - 在轉(zhuǎn)動角度歸零(90deg)時(shí)特殊處理 transition刹悴。
Things learned
CSS tranform
MDN document
通過設(shè)置 transform
為 translateX/Y
進(jìn)行平移行楞,rotate
進(jìn)行旋轉(zhuǎn),transform-origin
指定旋轉(zhuǎn)的圓心土匀。
transform function涵蓋了幾乎所有幾何變換子房,具體見文檔。
transition-timing-function
一般 transition-timing-function
可以設(shè)置為 ease
之類的就轧。利用 dev-tools
可以圖形化手動調(diào)節(jié)曲線的到想要的 cubic-bezier
证杭。
角度歸零的處理
以秒針為例,
因?yàn)樵O(shè)置了 transition妒御,在秒針從 444 跳動到下一秒時(shí)不是 450 度解愤,而是歸零為 0 + 90 = 90 度。設(shè)置的 transition 實(shí)際執(zhí)行結(jié)果是指針逆時(shí)針倒轉(zhuǎn)到90度乎莉。
視頻中 Wes 提到了兩種方法:
- 歸零時(shí)暫時(shí)取消 transition送讲;
- 角度只增不減。
Soyaine使用的解法是暫時(shí)取消 transition:
if (secondDeg === 90) secHand.style.transition = 'all 0s';
else secHand.style.transition = 'all 0.05s';
但這樣實(shí)際結(jié)果是那一秒沒有 transition 效果惋啃,我改進(jìn)了一下加入兩個(gè) setTimeout
完成角度的歸零哼鬓。
if (secDegree === 444) {
setTimeout(() => {
secHand.style.transition = 'all 0s';
secHand.style.transform = `rotate(${secDegree-360}deg)`;
}, 100);
setTimeout(() => {
secHand.style.transition = 'all .05s';
}, 500);
}