animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Thinking about SVG-preloaders

model output

Claude Sonnet 4.6

Thinking about SVG-preloaders

A 0.77T 0.21
compare with ground truth →
1<!DOCTYPE html>
2<html>
3<head>
4<style>
5  * { margin: 0; padding: 0; box-sizing: border-box; }
6  body {
7    background: #0a0a0a;
8    display: flex;
9    justify-content: center;
10    align-items: center;
11    width: 100vw;
12    height: 100vh;
13    overflow: hidden;
14  }
15  canvas {
16    display: block;
17  }
18</style>
19</head>
20<body>
21<canvas id="c"></canvas>
22<script>
23const canvas = document.getElementById('c');
24const ctx = canvas.getContext('2d');
25canvas.width = window.innerWidth;
26canvas.height = window.innerHeight;
27
28const cx = canvas.width / 2;
29const cy = canvas.height / 2;
30
31const NUM_DOTS = 12;
32const RADIUS = 38; // orbit radius
33const DOT_SIZE_MAX = 10;
34const DOT_SIZE_MIN = 5;
35const SPEED = 0.8; // rotations per second (radians per ms)
36
37// The "snake" spans about 200 degrees
38// Head is bright yellow, tail fades to dark red
39// Head dots are hollow (ring), tail dots are filled
40
41function getColor(t) {
42  // t=0 is head (yellow), t=1 is tail (dark red)
43  const r = Math.round(255 * (1 - t * 0.3));
44  const g = Math.round(200 * (1 - t));
45  const b = 0;
46  return `rgb(${r},${g},${b})`;
47}
48
49function getAlpha(t) {
50  return 1.0 - t * 0.5;
51}
52
53function getDotSize(t) {
54  // head is smaller (ring), tail is larger (filled)
55  return DOT_SIZE_MIN + (DOT_SIZE_MAX - DOT_SIZE_MIN) * t;
56}
57
58let startTime = null;
59const ANGULAR_SPAN = (200 * Math.PI) / 180; // span of the snake in radians
60const ANGULAR_SPEED = (2 * Math.PI) / 2000; // full rotation in 2 seconds
61
62function draw(timestamp) {
63  if (!startTime) startTime = timestamp;
64  const elapsed = timestamp - startTime;
65
66  ctx.clearRect(0, 0, canvas.width, canvas.height);
67
68  // Head angle advances over time
69  const headAngle = (elapsed * ANGULAR_SPEED) % (2 * Math.PI);
70
71  for (let i = 0; i < NUM_DOTS; i++) {
72    const t = i / (NUM_DOTS - 1); // 0=head, 1=tail
73    // tail is behind head
74    const angle = headAngle - t * ANGULAR_SPAN;
75
76    const x = cx + Math.cos(angle) * RADIUS;
77    const y = cy + Math.sin(angle) * RADIUS;
78
79    const size = getDotSize(t);
80    const color = getColor(t);
81    const alpha = getAlpha(t);
82
83    ctx.save();
84    ctx.globalAlpha = alpha;
85
86    if (t < 0.25) {
87      // Head dots: hollow rings
88      ctx.beginPath();
89      ctx.arc(x, y, size, 0, Math.PI * 2);
90      ctx.strokeStyle = color;
91      ctx.lineWidth = 2;
92      ctx.stroke();
93    } else {
94      // Tail dots: filled circles
95      ctx.beginPath();
96      ctx.arc(x, y, size, 0, Math.PI * 2);
97      ctx.fillStyle = color;
98      ctx.fill();
99    }
100
101    ctx.restore();
102  }
103
104  requestAnimationFrame(draw);
105}
106
107requestAnimationFrame(draw);
108</script>
109</body>
110</html>