-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscript.js
More file actions
132 lines (90 loc) · 2.68 KB
/
Copy pathscript.js
File metadata and controls
132 lines (90 loc) · 2.68 KB
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
const clock = document.getElementById("clock");
// Generate 60 markers
for (let i = 0; i < 60; i++) {
const mark = document.createElement("div");
mark.classList.add("mark");
// Every 5th = hour marker
if (i % 5 === 0) {
mark.classList.add("hour-mark");
}
mark.style.transform = `rotate(${i * 6}deg)`;
clock.appendChild(mark);
}
let selectedTimeZone = Intl.DateTimeFormat().resolvedOptions().timeZone;
const secondHand = document.querySelector('.second');
const minuteHand = document.querySelector('.minute');
const hourHand = document.querySelector('.hour');
// Track accumulated rotations
let currentHourDeg = 0;
let currentMinuteDeg = 0;
// CLOCK MECHANICS
function updateClock() {
const now = new Date();
const formatter = new Intl.DateTimeFormat("en-US", {
timeZone: selectedTimeZone,
hour: "numeric",
minute: "numeric",
second: "numeric",
hour12: false
});
const parts = formatter.formatToParts(now);
const hours = parseInt(
parts.find(p => p.type === "hour").value
) % 12;
const minutes = parseInt(
parts.find(p => p.type === "minute").value
);
const seconds = parseInt(
parts.find(p => p.type === "second").value
);
// Smooth seconds sweep
const smoothSeconds =
seconds + now.getMilliseconds() / 1000;
const secDeg = smoothSeconds * 6;
let minDeg =
minutes * 6 + smoothSeconds * 0.1;
let hourDeg =
hours * 30 + minutes * 0.5;
// Prevent backward jump of hands
while(minDeg < currentMinuteDeg){
minDeg += 360;
}
while(hourDeg < currentHourDeg){
hourDeg += 360;
}
currentMinuteDeg = minDeg;
currentHourDeg = hourDeg;
secondHand.style.transform =
`rotate(${secDeg}deg)`;
minuteHand.style.transform =
`rotate(${currentMinuteDeg}deg)`;
hourHand.style.transform =
`rotate(${currentHourDeg}deg)`;
requestAnimationFrame(updateClock);
}
updateClock();
// TIME ZONE LIST
const select = document.getElementById("countrySelect");
const countries = Intl.supportedValuesOf("timeZone");
countries.sort();
countries.forEach(zone => {
const option = document.createElement("option");
option.value = zone;
option.textContent = zone;
select.appendChild(option);
});
select.value = selectedTimeZone;
// TIME ZONE SELECTION
select.addEventListener("change", (e) => {
selectedTimeZone = e.target.value;
// temporary smooth glide when switching zones
minuteHand.style.transition =
"transform 1.2s ease-in-out";
hourHand.style.transition =
"transform 1.8s ease-in-out";
// remove transition after glide so live sweep stays smooth
setTimeout(() => {
minuteHand.style.transition = "";
hourHand.style.transition = "";
},1800);
});