animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Animated Dot Loaders

model output

Claude Sonnet 4.6

Animated Dot Loaders

A 0.87T 0.22
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.0">
6<title>Loading Animation</title>
7<style>
8  * {
9    margin: 0;
10    padding: 0;
11    box-sizing: border-box;
12  }
13
14  body {
15    width: 100vw;
16    height: 100vh;
17    background: radial-gradient(ellipse at center, #1a0a2e 0%, #0d0818 40%, #080610 100%);
18    display: flex;
19    align-items: center;
20    justify-content: center;
21    overflow: hidden;
22  }
23
24  .glow-bg {
25    position: absolute;
26    width: 300px;
27    height: 300px;
28    border-radius: 50%;
29    background: radial-gradient(ellipse at center, rgba(80, 20, 120, 0.3) 0%, transparent 70%);
30    border: 1px solid rgba(100, 40, 150, 0.15);
31    top: 50%;
32    left: 50%;
33    transform: translate(-50%, -50%);
34  }
35
36  .dots-container {
37    display: flex;
38    align-items: center;
39    gap: 10px;
40    position: relative;
41    z-index: 1;
42  }
43
44  .dot {
45    width: 14px;
46    height: 14px;
47    border-radius: 50%;
48    background: #7a7a9a;
49    animation: dotPulse 1.5s ease-in-out infinite;
50  }
51
52  .dot:nth-child(1) { animation-delay: 0s; }
53  .dot:nth-child(2) { animation-delay: 0.15s; }
54  .dot:nth-child(3) { animation-delay: 0.3s; }
55  .dot:nth-child(4) { animation-delay: 0.45s; }
56  .dot:nth-child(5) { animation-delay: 0.6s; }
57
58  @keyframes dotPulse {
59    0% {
60      background: #5a5a7a;
61      transform: scale(0.85);
62      opacity: 0.5;
63    }
64    50% {
65      background: #ffffff;
66      transform: scale(1.1);
67      opacity: 1;
68    }
69    100% {
70      background: #5a5a7a;
71      transform: scale(0.85);
72      opacity: 0.5;
73    }
74  }
75
76  /* The animation shows dots appearing/disappearing - the bright dot travels from right to left */
77  /* We'll use a wave that moves the bright spot from right to left */
78</style>
79</head>
80<body>
81  <div class="glow-bg"></div>
82  <div class="dots-container">
83    <div class="dot"></div>
84    <div class="dot"></div>
85    <div class="dot"></div>
86    <div class="dot"></div>
87    <div class="dot"></div>
88  </div>
89
90  <script>
91    // Looking at the frames: dots collapse from left (disappear) while bright dot moves right to left
92    // Frame 1: 5 dots visible, rightmost bright
93    // Frame 2: 4 dots, rightmost bright  
94    // Frame 3: 3 dots, rightmost bright
95    // Frame 4: 1 dot (center), very bright
96    // Frame 5: 1 dot (center), bright
97    // Frame 6: 3 dots appear, rightmost bright
98    // Frame 7: 4 dots, rightmost bright
99    // Frame 8: 3 dots, rightmost bright
100
101    // This looks like dots are collapsing to center then expanding
102    // Let's implement with JS for precise control
103
104    const container = document.querySelector('.dots-container');
105    const dots = document.querySelectorAll('.dot');
106
107    // Override CSS animation with JS-controlled animation
108    dots.forEach(d => {
109      d.style.animation = 'none';
110      d.style.background = '#5a5a7a';
111      d.style.opacity = '0.5';
112      d.style.transform = 'scale(0.85)';
113    });
114
115    // The bright "active" dot travels: from right side, collapses to center, then expands back
116    // Total cycle: ~2s
117    // Phase 1 (0-0.8s): bright dot moves from index 4 to index 0 (right to left), dots disappear
118    // Phase 2 (0.8-1.0s): single bright dot at center
119    // Phase 3 (1.0-1.8s): dots reappear, bright dot at rightmost visible
120    // Phase 4 (1.8-2.0s): pause
121
122    function lerp(a, b, t) { return a + (b - a) * t; }
123
124    const CYCLE = 2000;
125    const NUM_DOTS = 5;
126    const CENTER = 2; // index of center dot
127
128    function easeInOut(t) {
129      return t < 0.5 ? 2*t*t : -1+(4-2*t)*t;
130    }
131
132    function update() {
133      const now = performance.now();
134      const t = (now % CYCLE) / CYCLE; // 0 to 1
135
136      // Phase 1: collapse (0 to 0.45) - dots disappear from left, bright moves left
137      // Phase 2: single dot (0.45 to 0.55)
138      // Phase 3: expand (0.55 to 1.0) - dots appear from center outward, bright at right
139
140      dots.forEach((dot, i) => {
141        dot.style.display = 'block';
142      });
143
144      if (t < 0.45) {
145        // Collapsing: bright dot moves from right (index 4) toward center (index 2)
146        const p = t / 0.45; // 0 to 1
147        const ep = easeInOut(p);
148        
149        // Number of visible dots decreases from 5 to 1
150        const visibleCount = Math.round(lerp(5, 1, ep));
151        const startIdx = CENTER - Math.floor((visibleCount - 1) / 2);
152        
153        dots.forEach((dot, i) => {
154          const visible = i >= startIdx && i < startIdx + visibleCount;
155          dot.style.opacity = visible ? '0.5' : '0';
156          dot.style.transform = visible ? 'scale(0.85)' : 'scale(0)';
157          dot.style.background = '#5a5a7a';
158        });
159
160        // Bright dot is at the rightmost visible
161        const brightIdx = startIdx + visibleCount - 1;
162        if (brightIdx >= 0 && brightIdx < NUM_DOTS) {
163          const bright = dots[brightIdx];
164          bright.style.background = '#ffffff';
165          bright.style.opacity = '1';
166          bright.style.transform = 'scale(1.1)';
167        }
168
169      } else if (t < 0.55) {
170        // Single bright dot at center
171        dots.forEach((dot, i) => {
172          if (i === CENTER) {
173            dot.style.opacity = '1';
174            dot.style.transform = 'scale(1.1)';
175            dot.style.background = '#ffffff';
176          } else {
177            dot.style.opacity = '0';
178            dot.style.transform = 'scale(0)';
179            dot.style.background = '#5a5a7a';
180          }
181        });
182
183      } else {
184        // Expanding: dots appear from center outward, bright at rightmost
185        const p = (t - 0.55) / 0.45; // 0 to 1
186        const ep = easeInOut(p);
187        
188        const visibleCount = Math.round(lerp(1, 5, ep));
189        const startIdx = CENTER - Math.floor((visibleCount - 1) / 2);
190        
191        dots.forEach((dot, i) => {
192          const visible = i >= startIdx && i < startIdx + visibleCount;
193          dot.style.opacity = visible ? '0.5' : '0';
194          dot.style.transform = visible ? 'scale(0.85)' : 'scale(0)';
195          dot.style.background = '#5a5a7a';
196        });
197
198        // Bright dot at rightmost visible
199        const brightIdx = startIdx + visibleCount - 1;
200        if (brightIdx >= 0 && brightIdx < NUM_DOTS) {
201          const bright = dots[brightIdx];
202          bright.style.background = '#ffffff';
203          bright.style.opacity = '1';
204          bright.style.transform = 'scale(1.1)';
205        }
206      }
207
208      requestAnimationFrame(update);
209    }
210
211    requestAnimationFrame(update);
212  </script>
213</body>
214</html>