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

model output

GPT-5.4

Thinking about SVG-preloaders

A 0.62T 0.35
compare with ground truth →
1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8" />
5<meta name="viewport" content="width=device-width,initial-scale=1" />
6<title>Rotating Ring Trail</title>
7<style>
8  html, body {
9    margin: 0;
10    width: 100%;
11    height: 100%;
12    overflow: hidden;
13    background:
14      linear-gradient(45deg, rgba(255,255,255,.035) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.035) 75%, rgba(255,255,255,.035)),
15      linear-gradient(45deg, rgba(255,255,255,.035) 25%, transparent 25%, transparent 75%, rgba(255,255,255,.035) 75%, rgba(255,255,255,.035));
16    background-color: #020304;
17    background-size: 18px 18px;
18    background-position: 0 0, 9px 9px;
19  }
20
21  body {
22    display: grid;
23    place-items: center;
24  }
25
26  canvas {
27    display: block;
28    width: 100vw;
29    height: 100vh;
30  }
31</style>
32</head>
33<body>
34<canvas id="c"></canvas>
35
36<script>
37const canvas = document.getElementById('c');
38const ctx = canvas.getContext('2d');
39
40function resize() {
41  const dpr = Math.min(devicePixelRatio || 1, 2);
42  canvas.width = innerWidth * dpr;
43  canvas.height = innerHeight * dpr;
44  canvas.style.width = innerWidth + 'px';
45  canvas.style.height = innerHeight + 'px';
46  ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
47}
48addEventListener('resize', resize);
49resize();
50
51const COUNT = 12;
52const R = 40;
53const DOT_R = 9;
54const SPEED = Math.PI * 0.72; // ~8.7s per revolution
55const spacing = 0.22; // radians between dots
56
57function ringColor(t) {
58  // t: 0 = head, 1 = tail
59  const hue = 52 - t * 42;      // yellow -> orange/red
60  const sat = 92 - t * 18;
61  const light = 56 - t * 26;
62  const alpha = 0.95 - t * 0.82;
63  return `hsla(${hue}, ${sat}%, ${light}%, ${alpha})`;
64}
65
66function fillColor(t) {
67  const hue = 42 - t * 28;
68  const sat = 88 - t * 20;
69  const light = 50 - t * 22;
70  const alpha = 0.22 - t * 0.18;
71  return `hsla(${hue}, ${sat}%, ${light}%, ${Math.max(alpha, 0)})`;
72}
73
74function draw(now) {
75  now *= 0.001;
76
77  ctx.clearRect(0, 0, innerWidth, innerHeight);
78
79  const cx = innerWidth * 0.5;
80  const cy = innerHeight * 0.37;
81
82  // slight vertical ellipse like the reference
83  const rx = R;
84  const ry = R * 0.98;
85
86  // orient so the bright head sits around upper-right and rotates clockwise
87  const base = -Math.PI * 0.15 + now * SPEED;
88
89  for (let i = COUNT - 1; i >= 0; i--) {
90    const t = i / (COUNT - 1);
91    const a = base - i * spacing;
92
93    const x = cx + Math.cos(a) * rx;
94    const y = cy + Math.sin(a) * ry;
95
96    const r = DOT_R + (1 - t) * 1.2;
97
98    // soft glow
99    const glow = ctx.createRadialGradient(x, y, 0, x, y, r * 2.2);
100    glow.addColorStop(0, fillColor(t));
101    glow.addColorStop(1, 'rgba(0,0,0,0)');
102    ctx.fillStyle = glow;
103    ctx.beginPath();
104    ctx.arc(x, y, r * 2.2, 0, Math.PI * 2);
105    ctx.fill();
106
107    // some trail dots are filled, head dots are hollow rings
108    const hollowMix = t < 0.42;
109    if (!hollowMix || t > 0.75) {
110      ctx.fillStyle = fillColor(t * 0.9);
111      ctx.beginPath();
112      ctx.arc(x, y, r * 0.95, 0, Math.PI * 2);
113      ctx.fill();
114    }
115
116    ctx.strokeStyle = ringColor(t);
117    ctx.lineWidth = 3;
118    ctx.beginPath();
119    ctx.arc(x, y, r * 0.78, 0, Math.PI * 2);
120    ctx.stroke();
121  }
122
123  requestAnimationFrame(draw);
124}
125
126requestAnimationFrame(draw);
127</script>
128</body>
129</html>