Skip to content

Commit 157d318

Browse files
committed
clock
1 parent 9c33085 commit 157d318

5 files changed

Lines changed: 74 additions & 111 deletions

File tree

_includes/clocks.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
<script>
2929
show_date_and_time();
3030
document.getElementById('current-year').innerHTML = new Date().getFullYear();
31+
3132
</script>
3233

3334
<style>

assets/js/clock.js

Lines changed: 32 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"use strict";
2+
const TAU = 2 * Math.PI;
23
const CLOCK_CONFIG = {
34
radius: 144,
45
center: { x: 0, y: 0 },
@@ -26,60 +27,45 @@ const CLOCK_CONFIG = {
2627
clockTypes: {
2728
hour: {
2829
segmentNames: ['12', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'],
29-
segmentCount: 12,
30-
segmentFractions: Array.from({ length: 12 }, (_, i) => i / 12),
3130
markCount: 48
3231
},
3332
month: {
3433
segmentNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
35-
segmentCount: 12,
36-
segmentFractions: Array.from({ length: 12 }, (_, i) => i / 12),
3734
markCount: 48
3835
},
3936
year: {
4037
segmentNames: ['2000', '', '2010', '', '2020', '', '2030', '', '2040', '', '2050', ''],
41-
segmentCount: 12,
42-
segmentFractions: Array.from({ length: 12 }, (_, i) => i / 12),
4338
markCount: 60
4439
},
4540
decimal: {
4641
segmentNames: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10'],
47-
segmentCount: 10,
48-
segmentFractions: Array.from({ length: 10 }, (_, i) => i / 10),
4942
markCount: 100
5043
},
5144
decade: {
5245
segmentNames: ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90', ''],
53-
segmentCount: 10,
54-
segmentFractions: Array.from({ length: 10 }, (_, i) => i / 10),
5546
markCount: 20
5647
},
5748
century: {
5849
segmentNames: ['1200', '', '', '1500', '', '', '1800', '', '', '2100', '', '', ''],
59-
segmentCount: 12,
60-
segmentFractions: Array.from({ length: 12 }, (_, i) => i / 12),
6150
markCount: 48
6251
},
6352
millennia: {
6453
segmentNames: ['', '', '', '', '', '', '', '', '', '', '', '', ''],
65-
segmentCount: 12,
66-
segmentFractions: Array.from({ length: 12 }, (_, i) => i / 12),
6754
markCount: 60
6855
}
6956
}
7057
};
58+
const POSITION_FUNCTIONS = {
59+
'hour': getHourPosition,
60+
'month': getMonthPosition,
61+
'year': getYearPosition,
62+
'decimal': getDecimalPosition,
63+
'decade': getDecadePosition,
64+
'century': getCenturyPosition,
65+
'millennia': getMillenniaPosition
66+
};
7167
function getCurrentPosition(type) {
72-
const positionFunctions = {
73-
'hour': getHourPosition,
74-
'month': getMonthPosition,
75-
'year': getYearPosition,
76-
'decimal': getDecimalPosition,
77-
'decade': getDecadePosition,
78-
'century': getCenturyPosition,
79-
'millennia': getMillenniaPosition
80-
};
81-
const positionFunction = positionFunctions[type] || positionFunctions['year'];
82-
return positionFunction();
68+
return (POSITION_FUNCTIONS[type] || POSITION_FUNCTIONS['year'])();
8369
}
8470
function getClockSetup(type) {
8571
return CLOCK_CONFIG.clockTypes[type] || CLOCK_CONFIG.clockTypes.year;
@@ -92,11 +78,10 @@ function drawLine(ctx, startX, startY, endX, endY, color, width, opacity = 1.0)
9278
ctx.strokeStyle = color;
9379
ctx.lineWidth = width;
9480
ctx.stroke();
95-
return ctx;
9681
}
9782
function drawCircle(ctx, x, y, radius, color, fill = true, opacity = 1.0) {
9883
ctx.beginPath();
99-
ctx.arc(x, y, radius, 0, 2 * Math.PI);
84+
ctx.arc(x, y, radius, 0, TAU);
10085
ctx.globalAlpha = opacity;
10186
if (fill) {
10287
ctx.fillStyle = color;
@@ -106,7 +91,6 @@ function drawCircle(ctx, x, y, radius, color, fill = true, opacity = 1.0) {
10691
ctx.strokeStyle = color;
10792
ctx.stroke();
10893
}
109-
return ctx;
11094
}
11195
function drawText(ctx, text, x, y, color, fontSize, opacity = 1.0) {
11296
ctx.font = `${fontSize}px sans-serif`;
@@ -115,7 +99,6 @@ function drawText(ctx, text, x, y, color, fontSize, opacity = 1.0) {
11599
ctx.textBaseline = 'middle';
116100
ctx.globalAlpha = opacity;
117101
ctx.fillText(text, x, y);
118-
return ctx;
119102
}
120103
function getPointFromAngle(center, angle, distance) {
121104
return {
@@ -128,13 +111,13 @@ function getHourPosition() {
128111
const hour = now.hour() % 12;
129112
const minute = now.minute();
130113
const second = now.second();
131-
return ((hour * 60 + minute + second / 60) / 720) * 2 * Math.PI;
114+
return ((hour * 60 + minute + second / 60) / 720) * TAU;
132115
}
133116
function getMonthPosition() {
134117
const now = moment();
135118
const month = now.month();
136119
const day = now.date();
137-
return (month + day / now.daysInMonth()) / 12 * 2 * Math.PI;
120+
return (month + day / now.daysInMonth()) / 12 * TAU;
138121
}
139122
function getYearPosition() {
140123
const now = moment();
@@ -143,7 +126,7 @@ function getYearPosition() {
143126
const day = now.date();
144127
const yearsSince2000 = year - 2000;
145128
const fractionOfYear = (month * 30 + day) / 365;
146-
return ((yearsSince2000 + fractionOfYear) / 60) * 2 * Math.PI;
129+
return ((yearsSince2000 + fractionOfYear) / 60) * TAU;
147130
}
148131
function getDecimalPosition() {
149132
return 0;
@@ -152,39 +135,40 @@ function getDecadePosition() {
152135
const now = moment();
153136
const year = now.year();
154137
const month = now.month();
155-
return (year + month / 12 - 2000) / 100 * 2 * Math.PI;
138+
return (year + month / 12 - 2000) / 100 * TAU;
156139
}
157140
function getCenturyPosition() {
158141
const now = moment();
159142
const year = now.year();
160143
const month = now.month();
161-
return (year + month / 12 - 1200) / 1200 * 2 * Math.PI;
144+
return (year + month / 12 - 1200) / 1200 * TAU;
162145
}
163146
function getMillenniaPosition() {
164-
const year = moment().year();
165-
return (year) / 12000 * 2 * Math.PI;
147+
return moment().year() / 12000 * TAU;
166148
}
167149
function drawClockDial(ctx, config, clockSetup) {
168150
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
169151
drawCircle(ctx, config.center.x, config.center.y, config.radius, config.colors.dial, false, config.opacities.dial);
170-
for (let segment = 0; segment < clockSetup.segmentCount; segment++) {
171-
drawMarks(ctx, config, clockSetup, segment);
152+
const segmentCount = clockSetup.segmentNames.length;
153+
for (let segment = 0; segment < segmentCount; segment++) {
154+
drawMarks(ctx, config, clockSetup, segment / segmentCount);
172155
}
173156
drawMiniMarks(ctx, config, clockSetup);
174157
}
175-
function drawMarks(ctx, config, clockSetup, segment) {
158+
function drawMarks(ctx, config, clockSetup, fraction) {
176159
const { sizes, colors, opacities } = config;
177-
const segmentAngle = clockSetup.segmentFractions[segment] * 2 * Math.PI;
160+
const segmentAngle = fraction * TAU;
178161
const innerPoint = getPointFromAngle(config.center, segmentAngle, config.radius - sizes.markLength);
179162
const outerPoint = getPointFromAngle(config.center, segmentAngle, config.radius - sizes.markLength / 2);
180163
drawLine(ctx, innerPoint.x, innerPoint.y, outerPoint.x, outerPoint.y, colors.marks, sizes.markWidth, opacities.marks);
181164
const labelPoint = getPointFromAngle(config.center, segmentAngle, config.radius - sizes.markLength - sizes.labelPadding);
182-
drawText(ctx, clockSetup.segmentNames[segment], labelPoint.x, labelPoint.y, colors.marks, sizes.labelFontSize, opacities.labels);
165+
const segmentIndex = Math.round(fraction * clockSetup.segmentNames.length) % clockSetup.segmentNames.length;
166+
drawText(ctx, clockSetup.segmentNames[segmentIndex], labelPoint.x, labelPoint.y, colors.marks, sizes.labelFontSize, opacities.labels);
183167
}
184168
function drawMiniMarks(ctx, config, clockSetup) {
185169
const { sizes, colors, opacities } = config;
186170
for (let i = 0; i < clockSetup.markCount; i++) {
187-
const angle = (i / clockSetup.markCount) * 2 * Math.PI;
171+
const angle = (i / clockSetup.markCount) * TAU;
188172
const innerPoint = getPointFromAngle(config.center, angle, config.radius - sizes.markLength);
189173
const outerPoint = getPointFromAngle(config.center, angle, config.radius - sizes.markLength * 0.5);
190174
drawLine(ctx, innerPoint.x, innerPoint.y, outerPoint.x, outerPoint.y, colors.marks, sizes.markWidth, opacities.miniMarks);
@@ -201,8 +185,7 @@ function drawHand(ctx, config, angle) {
201185
drawLine(ctx, config.center.x, config.center.y, handPoint.x, handPoint.y, colors.hands, sizes.handWidth, 1.0);
202186
drawLine(ctx, handPoint.x, handPoint.y, handEnd.x, handEnd.y, colors.highlight, sizes.handWidth * 0.5, 1.0);
203187
const circleRadius = config.radius * sizes.handCircleRadius;
204-
const circleDistance = handLength * tip;
205-
const circlePoint = getPointFromAngle(config.center, angle, circleDistance);
188+
const circlePoint = getPointFromAngle(config.center, angle, handLength * tip);
206189
drawCircle(ctx, circlePoint.x, circlePoint.y, circleRadius, colors.highlight, true, 1.0);
207190
}
208191
function drawCenterDot(ctx, config) {
@@ -226,7 +209,8 @@ function updateClock(ctx, config, clockSetup, type) {
226209
drawCenterDot(ctx, config);
227210
requestAnimationFrame(() => updateClock(ctx, config, clockSetup, type));
228211
}
229-
function initClock(options) {
212+
let themeObserver = null;
213+
function draw_clock(options) {
230214
const id = options.id || 'default';
231215
const type = options.type || 'year';
232216
const canvas = document.getElementById(`clockCanvas-${id}`);
@@ -238,10 +222,8 @@ function initClock(options) {
238222
canvas.width = canvas.height = config.radius * 2 * dpr;
239223
ctx.scale(dpr, dpr);
240224
syncThemeColors(config);
241-
const observer = new MutationObserver(() => syncThemeColors(config));
242-
observer.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
225+
themeObserver === null || themeObserver === void 0 ? void 0 : themeObserver.disconnect();
226+
themeObserver = new MutationObserver(() => syncThemeColors(config));
227+
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] });
243228
updateClock(ctx, config, clockSetup, type);
244229
}
245-
function draw_clock(options) {
246-
initClock(options);
247-
}

0 commit comments

Comments
 (0)