Back to Blog

Can AI Build an Animated Clock? We put Sonnet 4.6 to the test. Claude Opus vs Sonnet vs Haiku

Sandy LaneSandy Lane

Video: Can AI Build an Animated Clock? We put Sonnet 4.6 to the test. Claude Opus vs Sonnet vs Haiku by Taught by Celeste AI - AI Coding Coach

Watch full page →

Building an Animated SVG Clock with AI Models

This example demonstrates how to create a fully animated analog clock using SVG and JavaScript in a single HTML file. The clock features hour, minute, and second hands, tick marks, hour labels, and a digital time display, all smoothly updated in real time with requestAnimationFrame.

Code

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Animated SVG Clock</title>
  <style>
    body {
      background: linear-gradient(135deg, #1e3c72, #2a5298);
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      color: #ddd;
    }
    svg {
      width: 320px;
      height: 320px;
      background: white;
      border-radius: 50%;
      box-shadow: 0 0 15px rgba(0,0,0,0.3);
    }
    .clock-face {
      fill: #f0f0f0;
      stroke: #333;
      stroke-width: 8px;
    }
    .tick {
      stroke: #666;
      stroke-width: 2;
    }
    .hour-tick {
      stroke: #333;
      stroke-width: 4;
    }
    .hand {
      stroke-linecap: round;
      stroke: #222;
      transform-origin: 160px 160px;
    }
    .hour-hand {
      stroke-width: 6;
    }
    .minute-hand {
      stroke-width: 4;
    }
    .second-hand {
      stroke-width: 2;
      stroke: #d33;
    }
    .center-dot {
      fill: #222;
    }
    .digital-time {
      font-size: 24px;
      text-anchor: middle;
      fill: #222;
      font-weight: bold;
      user-select: none;
    }
    .hour-label {
      fill: #444;
      font-size: 16px;
      text-anchor: middle;
      dominant-baseline: middle;
      user-select: none;
    }
  </style>
</head>
<body>

<svg viewBox="0 0 320 320" aria-label="Analog clock">
  <circle class="clock-face" cx="160" cy="160" r="150" />

  <g id="tick-marks"></g>
  <g id="hour-labels"></g>

  <line id="hour-hand" class="hand hour-hand" x1="160" y1="160" x2="160" y2="90" />
  <line id="minute-hand" class="hand minute-hand" x1="160" y1="160" x2="160" y2="60" />
  <line id="second-hand" class="hand second-hand" x1="160" y1="160" x2="160" y2="40" />

  <circle class="center-dot" cx="160" cy="160" r="8" />

  <text id="digital-time" class="digital-time" x="160" y="290">00:00:00</text>
</svg>

<script>
  const svgNS = "http://www.w3.org/2000/svg";
  const tickMarks = document.getElementById('tick-marks');
  const hourLabels = document.getElementById('hour-labels');

  // Create 60 minute tick marks, with every 5th as hour tick
  for (let i = 0; i < 60; i++) {
    const tick = document.createElementNS(svgNS, 'line');
    const angle = (i * 6) * Math.PI / 180; // 6 degrees per tick
    const rOuter = 150;
    const rInner = (i % 5 === 0) ? 135 : 142;
    const x1 = 160 + rOuter * Math.sin(angle);
    const y1 = 160 - rOuter * Math.cos(angle);
    const x2 = 160 + rInner * Math.sin(angle);
    const y2 = 160 - rInner * Math.cos(angle);
    tick.setAttribute('x1', x1);
    tick.setAttribute('y1', y1);
    tick.setAttribute('x2', x2);
    tick.setAttribute('y2', y2);
    tick.setAttribute('class', (i % 5 === 0) ? 'hour-tick' : 'tick');
    tickMarks.appendChild(tick);
  }

  // Create hour labels 1 to 12
  for (let h = 1; h <= 12; h++) {
    const label = document.createElementNS(svgNS, 'text');
    const angle = (h * 30) * Math.PI / 180; // 30 degrees per hour
    const rLabel = 115;
    const x = 160 + rLabel * Math.sin(angle);
    const y = 160 - rLabel * Math.cos(angle);
    label.setAttribute('x', x);
    label.setAttribute('y', y);
    label.textContent = h;
    label.setAttribute('class', 'hour-label');
    hourLabels.appendChild(label);
  }

  const hourHand = document.getElementById('hour-hand');
  const minuteHand = document.getElementById('minute-hand');
  const secondHand = document.getElementById('second-hand');
  const digitalTime = document.getElementById('digital-time');

  function updateClock() {
    const now = new Date();
    const h = now.getHours() % 12;
    const m = now.getMinutes();
    const s = now.getSeconds();
    const ms = now.getMilliseconds();

    // Calculate angles with smooth movement
    const hourAngle = (h + m / 60 + s / 3600) * 30; // 360/12 = 30 degrees per hour
    const minuteAngle = (m + s / 60 + ms / 60000) * 6; // 360/60 = 6 degrees per minute
    const secondAngle = (s + ms / 1000) * 6; // 6 degrees per second

    hourHand.setAttribute('transform', `rotate(${hourAngle} 160 160)`);
    minuteHand.setAttribute('transform', `rotate(${minuteAngle} 160 160)`);
    secondHand.setAttribute('transform', `rotate(${secondAngle} 160 160)`);

    // Update digital display with leading zeros
    const hh = now.getHours().toString().padStart(2, '0');
    const mm = m.toString().padStart(2, '0');
    const ss = s.toString().padStart(2, '0');
    digitalTime.textContent = `${hh}:${mm}:${ss}`;

    requestAnimationFrame(updateClock);
  }

  updateClock();
</script>

</body>
</html>

Key Points

  • SVG elements can be dynamically generated and styled to create clock faces with tick marks and hour labels.
  • JavaScript's requestAnimationFrame enables smooth, real-time animation of clock hands based on the current time.
  • Transform rotations around the clock center allow precise positioning of hour, minute, and second hands.
  • A digital time display complements the analog clock and updates every animation frame for accuracy.
  • Separating hour and minute tick marks visually enhances readability and clock aesthetics.