Chapter 56: Clock Face
Clock Face in the most detailed, clear, and patient way possible.
Imagine we’re sitting together at a desk, and I’m your favorite teacher who wants you to really understand how a clock face is built — not just copy a finished clock, but know exactly why every line, circle, number, and tick is placed where it is.
Today we’re going to explain and build only the static clock face — the background part that doesn’t move. (The moving hands come in a separate lesson so we don’t mix everything at once.)
What is a Clock Face? (The background / dial of an analog clock — everything except the moving hands)
The clock face is the fixed circular background that shows:
- The outer ring / bezel
- The main face (usually with a subtle gradient or color)
- 12 hour markers (longer/thicker lines or bigger numbers)
- 60 minute markers (shorter/thinner lines)
- Usually numbers at 12, 3, 6, 9 (sometimes all 12)
- Sometimes small decorations (dots, Roman numerals, brand logo, etc.)
In Canvas, we draw the face only once at the beginning — we never redraw it every second. We only redraw the hands (and maybe a small center dot) every second.
Mental Model – Think of it like a real wall clock
- Big outer metal/plastic ring (decorative border)
- Slightly smaller inner circle (the actual dial)
- 12 long lines/marks at every hour
- 60 small lines/marks at every minute (skip the hour ones)
- Numbers placed along the inner edge
- Everything is perfectly symmetric around the center
Step-by-step: How we draw a nice modern clock face in Canvas
Here’s a complete, self-contained example that draws only the face — no hands yet.
|
0 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 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Canvas Clock Face – Explained</title> <style> body { margin: 0; height: 100vh; display: flex; justify-content: center; align-items: center; background: #0d1117; /* dark modern background */ } canvas { border: 6px solid #30363d; /* dark border like premium watch */ border-radius: 50%; box-shadow: 0 0 80px rgba(0,0,0,0.9); } </style> </head> <body> <canvas id="clock" width="500" height="500"></canvas> <script> const canvas = document.getElementById('clock'); const ctx = canvas.getContext('2d'); // Center & radius helpers (used everywhere) const cx = canvas.width / 2; // 250 const cy = canvas.height / 2; // 250 const radius = canvas.width / 2 - 40; // leave space for thick border // ──────────────────────────────────────────────── // 1. Outer ring / bezel (dark metallic look) ctx.beginPath(); ctx.arc(cx, cy, radius + 35, 0, Math.PI * 2); ctx.fillStyle = '#161b22'; // very dark gray ctx.fill(); ctx.strokeStyle = '#8b949e'; // silver/gray border ctx.lineWidth = 18; ctx.stroke(); // ──────────────────────────────────────────────── // 2. Main clock face (subtle radial gradient for depth) const faceGrad = ctx.createRadialGradient(cx, cy, 0, cx, cy, radius); faceGrad.addColorStop(0, '#22272e'); // lighter center faceGrad.addColorStop(1, '#0d1117'); // darker edge ctx.fillStyle = faceGrad; ctx.beginPath(); ctx.arc(cx, cy, radius, 0, Math.PI * 2); ctx.fill(); // ──────────────────────────────────────────────── // 3. Hour ticks – longer & thicker for (let i = 0; i < 12; i++) { const angle = (i * Math.PI / 6) - Math.PI / 2; // 0° = top (12 o'clock) const innerRadius = radius - 40; const outerRadius = radius - 8; const x1 = cx + Math.cos(angle) * innerRadius; const y1 = cy + Math.sin(angle) * innerRadius; const x2 = cx + Math.cos(angle) * outerRadius; const y2 = cy + Math.sin(angle) * outerRadius; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.strokeStyle = '#c9d1d9'; // light gray-white ctx.lineWidth = 10; ctx.lineCap = 'round'; ctx.stroke(); } // ──────────────────────────────────────────────── // 4. Minute ticks – shorter & thinner (skip every 5th) for (let i = 0; i < 60; i++) { if (i % 5 === 0) continue; // skip hour ticks const angle = (i * Math.PI / 30) - Math.PI / 2; const innerRadius = radius - 20; const outerRadius = radius - 8; const x1 = cx + Math.cos(angle) * innerRadius; const y1 = cy + Math.sin(angle) * innerRadius; const x2 = cx + Math.cos(angle) * outerRadius; const y2 = cy + Math.sin(angle) * outerRadius; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.strokeStyle = '#8b949e'; // medium gray ctx.lineWidth = 4; ctx.stroke(); } // ──────────────────────────────────────────────── // 5. Numbers (only 12, 3, 6, 9 – clean & modern look) ctx.fillStyle = '#c9d1d9'; // light gray-white ctx.font = 'bold 48px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; const positions = [12, 3, 6, 9]; positions.forEach((num, i) => { const angle = (i * Math.PI / 2) - Math.PI / 2; // 12 at top const x = cx + Math.cos(angle) * (radius - 70); const y = cy + Math.sin(angle) * (radius - 70); ctx.fillText(num, x, y); }); // Optional center dot (for later hands) ctx.beginPath(); ctx.arc(cx, cy, 12, 0, Math.PI*2); ctx.fillStyle = '#c9d1d9'; ctx.fill(); // Title (optional) ctx.fillStyle = '#8b949e'; ctx.font = 'bold 24px Arial'; ctx.fillText('Canvas Clock Face', cx, cy + radius + 60); </script> </body> </html> |
What you should see & remember forever:
- Thick dark outer ring → gives premium/watch-like feel
- Subtle radial gradient on face → adds depth (lighter center, darker edge)
- 12 long thick hour ticks
- 48 short thin minute ticks (skipping every 5th)
- Big numbers only at 12, 3, 6, 9 → clean & modern
- Everything perfectly centered using cx, cy helpers
- No hands yet — that’s next lesson
Key Techniques Used Here
- arc() for perfect circles
- save() / restore()not needed here (no transformations yet)
- Math.cos() / Math.sin() + angle math for placing ticks & numbers
- lineCap = ’round’ for smooth tick ends
- textBaseline = ‘middle’ for perfect vertical centering of numbers
Your mini homework (try tonight – 10–20 minutes)
- Make the hour numbers bigger & bolder (only 12, 3, 6, 9)
- Add small dots instead of lines for minute ticks
- Change the face gradient to a lighter silver/gray theme
- (Bonus) Add Roman numerals (XII, III, VI, IX) instead of Arabic
Paste your modified code here if you want feedback — I’ll review it like we’re pair-programming together 😄
Any part confusing?
- Why we use radius – 35 for inner tick position?
- Angle math (why -Math.PI/2)?
- Why we draw face only once?
- How to place numbers exactly on the circle?
- Something else?
Tell me — we’ll zoom in until the clock face feels perfect to you.
You just built the static foundation of a real analog clock — the moving hands are next, and it’s going to look amazing! 🚀
