From 31b326b090f56aaa0d14247e5059b23bd4f0d59d Mon Sep 17 00:00:00 2001 From: Kiyomichi Kosaka Date: Sun, 15 Jun 2025 11:28:02 +0200 Subject: [PATCH 1/2] refactor clock layout using unified radius --- clock.js | 43 ++++++++++++++++++++++--------------------- style.css | 2 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/clock.js b/clock.js index b0ae1ba..db38343 100644 --- a/clock.js +++ b/clock.js @@ -40,38 +40,39 @@ ticks = clock.querySelectorAll('.tick'); } - // Position markers based on the current clock size - // Move markers slightly inward and tweak the center position so - // the ring of ticks lines up perfectly with the border. - const borderOffset = clock.offsetWidth > 300 ? 45 : 26; - const centerAdjust = { x: -3, y: -2 }; - const markerRadius = clock.offsetWidth / 2 - borderOffset; + // Unified radius based on the actual clock size + const rect = clock.getBoundingClientRect(); + const baseRadius = rect.width / 2; + + // Tick lengths relative to the clock radius + const lenBig = baseRadius * 0.12; + const lenMid = baseRadius * 0.08; + const lenSmall = baseRadius * 0.05; + + const outerR = baseRadius - 2; // just inside the border + + // Distance from center for the marker digits so they sit just inside big ticks + const markerSize = markers[0] ? markers[0].offsetWidth : 0; + const markerRadius = outerR - lenBig - markerSize / 2; + markers.forEach((m, i) => { const angle = (i / 16) * 2 * Math.PI; - const x = markerRadius * Math.sin(angle); - const y = -markerRadius * Math.cos(angle); - m.style.left = `${clock.offsetWidth / 2 + x + centerAdjust.x}px`; - m.style.top = `${clock.offsetHeight / 2 + y + centerAdjust.y}px`; + m.style.left = '50%'; + m.style.top = '50%'; + m.style.transform = + `translate(-50%, -50%) rotate(${angle}rad) translate(0, -${markerRadius}px) rotate(${-angle}rad)`; }); - // Tick lengths based on the marker radius - const lenBig = markerRadius * 0.12; - const lenMid = markerRadius * 0.08; - const lenSmall = markerRadius * 0.05; - ticks.forEach((t, i) => { let len = lenSmall; if (t.classList.contains('big')) len = lenBig; else if (t.classList.contains('mid')) len = lenMid; - const outerR = clock.offsetWidth / 2 - 2; const innerR = outerR - len; const angle = (i / 256) * 2 * Math.PI; - const x = innerR * Math.sin(angle); - const y = -innerR * Math.cos(angle); t.style.height = `${len}px`; - t.style.left = `${clock.offsetWidth / 2 + x - t.offsetWidth / 2 + centerAdjust.x}px`; - t.style.top = `${clock.offsetHeight / 2 + y + centerAdjust.y}px`; - t.style.transform = `rotate(${angle}rad)`; + t.style.left = '50%'; + t.style.top = '50%'; + t.style.transform = `translate(-50%, 0) rotate(${angle}rad) translate(0, -${innerR}px)`; if (clock.offsetWidth < 200 && !t.classList.contains('big') && !t.classList.contains('mid')) { t.style.display = 'none'; } else { diff --git a/style.css b/style.css index 20d7f1c..ba3081c 100644 --- a/style.css +++ b/style.css @@ -445,7 +445,7 @@ body.fullscreen-clock .clock-label { border-radius: 0; text-shadow: 0 0 6px rgba(0, 255, 255, 0.9), 0 0 12px rgba(0, 255, 255, 0.7); box-shadow: none; - transform: translate(-50%, -50%); + transform-origin: center; z-index: 1; } From 59ba29e5a08f7f8255f845127c4ada8d8f4bcccc Mon Sep 17 00:00:00 2001 From: Oleksandr Kozachuk Date: Sun, 15 Jun 2025 13:31:18 +0200 Subject: [PATCH 2/2] Small improvements --- clock.js | 39 ++++++++++++++++++++++++++++++++++++--- style.css | 4 ++-- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/clock.js b/clock.js index db38343..86c4f7e 100644 --- a/clock.js +++ b/clock.js @@ -9,7 +9,40 @@ toCobiets } = window.Cobie; - // CoBiE helpers pulled from cobie.js + function getMarkerOffset(width) { + const points = [ + { width: 1024, value: 2 }, + { width: 450, value: 1.3 }, + { width: 200, value: 0.8 } + ]; + + // Sort points by width descending for easier handling + points.sort((a, b) => b.width - a.width); + + for (let i = 0; i < points.length - 1; i++) { + const p1 = points[i]; + const p2 = points[i + 1]; + if (width <= p1.width && width >= p2.width) { + // Linear interpolation + const t = (width - p2.width) / (p1.width - p2.width); + return p2.value + t * (p1.value - p2.value); + } + } + + // Extrapolation for width > max known + if (width > points[0].width) { + const p1 = points[0]; + const p2 = points[1]; + const slope = (p1.value - p2.value) / (p1.width - p2.width); + return p1.value + slope * (width - p1.width); + } + + // Extrapolation for width < min known + const p1 = points[points.length - 2]; + const p2 = points[points.length - 1]; + const slope = (p2.value - p1.value) / (p2.width - p1.width); + return p2.value + slope * (width - p2.width); + } function placeMarkers() { const clock = document.getElementById('clock'); @@ -53,7 +86,7 @@ // Distance from center for the marker digits so they sit just inside big ticks const markerSize = markers[0] ? markers[0].offsetWidth : 0; - const markerRadius = outerR - lenBig - markerSize / 2; + const markerRadius = outerR - lenBig - markerSize * getMarkerOffset(rect.width); markers.forEach((m, i) => { const angle = (i / 16) * 2 * Math.PI; @@ -68,7 +101,7 @@ if (t.classList.contains('big')) len = lenBig; else if (t.classList.contains('mid')) len = lenMid; const innerR = outerR - len; - const angle = (i / 256) * 2 * Math.PI; + const angle = ((i + 1) / 256) * 2 * Math.PI; t.style.height = `${len}px`; t.style.left = '50%'; t.style.top = '50%'; diff --git a/style.css b/style.css index ba3081c..d2188dc 100644 --- a/style.css +++ b/style.css @@ -414,11 +414,11 @@ .clock-label { position: absolute; - bottom: 23%; + bottom: 30%; left: 50%; transform: translateX(-50%); font-family: 'Great Vibes', cursive; - font-size: calc(var(--clock-size) * 0.08); + font-size: calc(var(--clock-size) * 0.06); color: #ffaaff; text-shadow: 0 0 6px rgba(255, 0, 255, 0.6); pointer-events: none;