Skip to content

Instantly share code, notes, and snippets.

@a70437043b
Created April 9, 2026 05:06
Show Gist options
  • Select an option

  • Save a70437043b/0d90d376694d16c0391d24096068565f to your computer and use it in GitHub Desktop.

Select an option

Save a70437043b/0d90d376694d16c0391d24096068565f to your computer and use it in GitHub Desktop.
My Notion Orbit Clock
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8">
<style>
:root {
--bg-color: #d9e9f2; /* 背景:淡藍色 */
--hour-ring: #FF5733; /* 外環:橙色 */
--min-ring: #2ECC71; /* 中環:綠色 */
--sec-ring: #3498DB; /* 內環:藍色 */
--text-color: #2c3e50; /* 文字顏色 */
}
body {
margin: 0; padding: 0; background: var(--bg-color);
display: flex; flex-direction: column; justify-content: center; align-items: center;
height: 100vh; font-family: 'Helvetica Neue', Arial, sans-serif; overflow: hidden;
}
.clock-container { position: relative; width: 380px; height: 380px; }
svg { width: 100%; height: 100%; }
/* 軌道樣式 */
.ring-h { fill: none; stroke: var(--hour-ring); stroke-width: 1.5; opacity: 0.15; }
.ring-m { fill: none; stroke: var(--min-ring); stroke-width: 1.5; opacity: 0.15; }
.ring-s { fill: none; stroke: var(--sec-ring); stroke-width: 1.5; opacity: 0.15; }
/* 刻度文字樣式 */
.tick-text { fill: var(--text-color); font-size: 11px; font-weight: bold; text-anchor: middle; dominant-baseline: middle; }
.tick-line { stroke: #333; stroke-width: 1; opacity: 0.3; }
/* 【修正重點】中央數字時間字體縮小 */
.digital-time {
position: absolute; top: 46%; left: 50%; transform: translate(-50%, -50%);
font-size: 20px; /* 從 28px 縮小到 20px */
font-weight: bold; display: flex; gap: 3px;
}
.t-h { color: var(--hour-ring); }
.t-m { color: var(--min-ring); }
.t-s { color: var(--sec-ring); }
.day-label {
position: absolute; top: 56%; left: 50%; transform: translate(-50%, -50%);
font-size: 12px; color: #7f8c8d; font-weight: 500;
}
</style>
</head>
<body>
<div class="clock-container">
<svg id="clock-svg" viewBox="0 0 400 400">
<circle class="ring-h" cx="200" cy="200" r="140" />
<circle class="ring-m" cx="200" cy="200" r="108" />
<circle class="ring-s" cx="200" cy="200" r="75" />
<g id="ticks-group"></g>
<circle id="ball-h" r="7" fill="#E74C3C" stroke="white" stroke-width="1.5" />
<circle id="ball-m" r="6" fill="#27AE60" stroke="white" stroke-width="1.5" />
<g id="airplane">
<path d="M0,-8 L2,-4 L8,-2 L8,0 L2,0 L2,6 L5,8 L5,9 L0,8 L-5,9 L-5,8 L-2,6 L-2,0 L-8,0 L-8,-2 L-2,-4 Z" fill="#2980B9" stroke="white" stroke-width="0.5"/>
</g>
</svg>
<div class="digital-time">
<span id="txt-h" class="t-h">00</span><span style="color:#bdc3c7">:</span>
<span id="txt-m" class="t-m">00</span><span style="color:#bdc3c7">:</span>
<span id="txt-s" class="t-s">00</span>
</div>
<div id="txt-day" class="day-label">Thursday</div>
</div>
<script>
function setupTicks() {
const g = document.getElementById('ticks-group');
const cx = 200, cy = 200;
// 小時數字:12, 3, 6, 9
const hLabels = { 0: "12", 90: "3", 180: "6", 270: "9" };
for (let a = 0; a < 360; a += 30) {
const rad = (a - 90) * Math.PI / 180;
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
line.setAttribute("class", "tick-line");
line.setAttribute("x1", cx + 135 * Math.cos(rad)); line.setAttribute("y1", cy + 135 * Math.sin(rad));
line.setAttribute("x2", cx + 145 * Math.cos(rad)); line.setAttribute("y2", cy + 145 * Math.sin(rad));
g.appendChild(line);
if (hLabels[a]) {
const tx = cx + 160 * Math.cos(rad), ty = cy + 160 * Math.sin(rad);
const t = document.createElementNS("http://www.w3.org/2000/svg", "text");
t.setAttribute("class", "tick-text"); t.setAttribute("x", tx); t.setAttribute("y", ty);
t.textContent = hLabels[a]; g.appendChild(t);
}
}
// 分鐘數字:60, 10, 20...
const mLabels = { 0: "60", 60: "10", 120: "20", 180: "30", 240: "40", 300: "50" };
for (let a = 0; a < 360; a += 6) {
const rad = (a - 90) * Math.PI / 180;
const isMajor = a % 30 === 0;
const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
line.setAttribute("class", "tick-line");
const rIn = isMajor ? 103 : 105, rOut = isMajor ? 113 : 110;
line.setAttribute("x1", cx + rIn * Math.cos(rad)); line.setAttribute("y1", cy + rIn * Math.sin(rad));
line.setAttribute("x2", cx + rOut * Math.cos(rad)); line.setAttribute("y2", cy + rOut * Math.sin(rad));
g.appendChild(line);
if (isMajor && mLabels[a]) {
const tx = cx + 125 * Math.cos(rad), ty = cy + 125 * Math.sin(rad);
const t = document.createElementNS("http://www.w3.org/2000/svg", "text");
t.setAttribute("class", "tick-text"); t.setAttribute("x", tx); t.setAttribute("y", ty);
t.textContent = mLabels[a]; g.appendChild(t);
}
}
}
function update() {
const now = new Date();
const h = now.getHours(), m = now.getMinutes(), s = now.getSeconds(), ms = now.getMilliseconds();
const cx = 200, cy = 200;
document.getElementById('txt-h').innerText = String(h).padStart(2, '0');
document.getElementById('txt-m').innerText = String(m).padStart(2, '0');
document.getElementById('txt-s').innerText = String(s).padStart(2, '0');
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
document.getElementById('txt-day').innerText = days[now.getDay()];
const s_progress = (s + ms/1000) / 60;
const sRad = (s_progress * 360 - 90) * Math.PI / 180;
const mRad = ((m + s/60) / 60 * 360 - 90) * Math.PI / 180;
const hRad = (((h % 12) + m/60) / 12 * 360 - 90) * Math.PI / 180;
// 更新球體
document.getElementById('ball-h').setAttribute('cx', cx + 140 * Math.cos(hRad));
document.getElementById('ball-h').setAttribute('cy', cy + 140 * Math.sin(hRad));
document.getElementById('ball-m').setAttribute('cx', cx + 108 * Math.cos(mRad));
document.getElementById('ball-m').setAttribute('cy', cy + 108 * Math.sin(mRad));
// 更新小飛機 (位置與轉向)
const plane = document.getElementById('airplane');
const px = cx + 75 * Math.cos(sRad), py = cy + 75 * Math.sin(sRad);
const pDeg = (s_progress * 360); // 修正旋轉角度計算
plane.setAttribute('transform', `translate(${px},${py}) rotate(${pDeg})`);
requestAnimationFrame(update);
}
setupTicks();
update();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment