Skip to content

Commit fe1f7de

Browse files
committed
update 02 JS clock
add the solution of hand twinkling
1 parent 24c8264 commit fe1f7de

File tree

2 files changed

+110
-6
lines changed

2 files changed

+110
-6
lines changed

02 - JS + CSS Clock/README.md

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
> 作者:©[缉熙Soyaine](https://github.com/soyaine)
44
> 简介:[JavaScript30](https://javascript30.com)[Wes Bos](https://github.com/wesbos) 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 2 篇。完整指南在 [GitHub](https://github.com/soyaine/JavaScript30),喜欢请 Star 哦♪(^∇^*)
55
6+
> 创建时间:2016-12-21
7+
最后更新:2017-01-06
8+
69
## 实现效果
710

811
![实现效果 by soyaine](https://cl.ly/0y1C2T1z3p2R/Screen%20recording%202016-12-23%20at%2012.30.25%20PM.gif)
@@ -101,5 +104,58 @@
101104
```
102105

103106
4. 将角度值赋值给 HTML 元素的 `style` 中的 `transform` 属性
107+
108+
## 延伸思考
109+
110+
> 2017-01-06 更新完善,感谢 [@cody1991 提的 issue](https://github.com/soyaine/JavaScript30/issues/1)
111+
112+
此处存在一个小瑕疵,当秒针旋转一圈之后回到初始位置,开始第二圈旋转,角度值的变化时 444° → 90° → 96° .... 这个过程中,指针会先逆时针从 444° 旋转至 90°,再继续我们期望的顺时针旋转,由于秒针变换时间只有 0.05s,所以呈现的效果就是秒针闪了一下,如果想要观察细节,可以将 `.second` 设为 `transition: all 1s`。要解决这个问题,目前找到了两种解决办法:
113+
114+
#### 方法一
115+
116+
在这个特殊点将指针的 `transition` 属性去掉,由于距离短、时间短,将逆时针回旋的过程瞬间完成。
117+
118+
```js
119+
if (secondDeg === 90) secHand.style.transition = 'all 0s';
120+
else secHand.style.transition = 'all 0.05s';
121+
122+
if (minDeg === 90) minHand.style.transition = 'all 0s';
123+
else minHand.style.transition = 'all 0.1s';
124+
```
125+
126+
#### 方法二
127+
128+
既然引发问题的是角度的大小变化,那就可以对这个值进行处理。此前的代码中,每秒都会重新 new 一个 Date 对象,用来计算角度值,但如果让这个角度值一直保持增长,也就不会出现逆时针回旋的问题了。
129+
130+
这是 @cody1991 提供的思路。只在页面第一次加载时 new 一次 Date 对象,此后每秒直接更新角度值。
131+
132+
```js
133+
let secondDeg = 0,
134+
minDeg = 0,
135+
hourDeg = 0;
136+
137+
function initDate() {
138+
const date = new Date();
139+
const second = date.getSeconds();
140+
secondDeg = 90 + (second / 60) * 360;
141+
const min = date.getMinutes();
142+
minDeg = 90 + (min / 60) * 360 + ((second / 60) / 60) * 360;
143+
const hour = date.getHours();
144+
hourDeg = 90 + (hour / 12) * 360 + ((min / 60) / 12) * 360 + (((second / 60) / 60) / 12) * 360;
145+
}
146+
147+
function updateDate() {
148+
secondDeg += (1 / 60) * 360;
149+
minDeg += ((1 / 60) / 60) * 360;
150+
hourDeg += (((1 / 60) / 60) / 12);
104151

105-
大功告成!
152+
secHand.style.transform = `rotate(${ secondDeg}deg)`;
153+
minHand.style.transform = `rotate(${ minDeg }deg)`;
154+
hourHand.style.transform = `rotate(${ hourDeg }deg)`;
155+
}
156+
157+
initDate();
158+
setInterval(updateDate, 1000);
159+
```
160+
161+
问题解决。大功告成!

02 - JS + CSS Clock/index-SOYAINE.html

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,28 +124,76 @@
124124
const secHand = document.querySelector('.second-hand');
125125
const minHand = document.querySelector('.min-hand');
126126
const hourHand = document.querySelector('.hour-hand');
127-
127+
128128
function setDate() {
129129
const date = new Date();
130-
130+
131131
const second = date.getSeconds();
132-
const secondDeg = (90 + (second / 60) * 360) % 360;
132+
const secondDeg = (90 + (second / 60) * 360);
133133

134134
const min = date.getMinutes();
135-
const minDeg = (90 + (min / 60) * 360) % 360;
135+
const minDeg = (90 + (min / 60) * 360);
136136

137137
const hour = date.getHours();
138138
const hourDeg = (90 + (hour / 12) * 360 + (min / 12 / 60) * 360);// 加入分钟所占的时间,使时针可以缓慢地移动
139139

140+
141+
// 解决指针跳顿问题【第一种方法】
142+
// 在发生跳顿的角度值处,将 CSS 的 `transition` 属性去掉
143+
if (secondDeg === 90) secHand.style.transition = 'all 0s';
144+
else secHand.style.transition = 'all 0.05s';
145+
146+
if (minDeg === 90) minHand.style.transition = 'all 0s';
147+
else minHand.style.transition = 'all 0.1s';
148+
149+
// 时针间距过大不做处理
150+
// if (hourDeg === 116.5) hourHand.style.transition = 'all 0s';
151+
// else hourHand.style.transition = 'all 3s';
152+
140153
secHand.style.transform = `rotate(${ secondDeg }deg)`;
141154
minHand.style.transform = `rotate(${ minDeg }deg)`;
142155
hourHand.style.transform = `rotate(${ hourDeg }deg)`;
143156

144-
// console.log(`${hour}:${min}:${second} - ${hourDeg}:${minDeg}:${secondDeg}` );
157+
console.log(`${hour}:${min}:${second} - ${hourDeg}:${minDeg}:${secondDeg}` );
145158
}
146159

147160
// setDate();
148161
setInterval(setDate, 1000);
149162
</script>
163+
164+
<script>
165+
// 解决指针跳帧问题的【第二种方法】:
166+
// 第一次加载时获取 Date 对象,
167+
// 此后每秒更新角度值
168+
169+
let secondDeg = 0,
170+
minDeg = 0,
171+
hourDeg = 0;
172+
173+
function initDate() {
174+
const date = new Date();
175+
const second = date.getSeconds();
176+
secondDeg = 90 + (second / 60) * 360;
177+
const min = date.getMinutes();
178+
minDeg = 90 + (min / 60) * 360 + ((second / 60) / 60) * 360;
179+
const hour = date.getHours();
180+
hourDeg = 90 + (hour / 12) * 360 + ((min / 60) / 12) * 360 + (((second / 60) / 60) / 12) * 360;
181+
}
182+
183+
function updateDate() {
184+
secondDeg += (1 / 60) * 360;
185+
minDeg += ((1 / 60) / 60) * 360;
186+
hourDeg += (((1 / 60) / 60) / 12);
187+
188+
secHand.style.transform = `rotate(${ s }deg)`;
189+
minHand.style.transform = `rotate(${ m }deg)`;
190+
hourHand.style.transform = `rotate(${ h }deg)`;
191+
192+
console.log(`${hourDeg}:${minDeg}:${secondDeg}` );
193+
}
194+
195+
// initDate();
196+
// setInterval(updateDate, 1000);
197+
</script>
150198
</body>
151199
</html>

0 commit comments

Comments
 (0)