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

model output

Claude Sonnet 4.6

SVG Multi-Drip

A 0.70T 0.16
compare with ground truth →
1Looking at the animation, I can see:
2
31. A row of dots arranged horizontally, colored with a gradient from magenta/pink (left) to red (right)
42. Each dot animates with a "bounce" effect - it drops down from the main line, falls, and returns - creating a wave-like ripple effect traveling across the dots
53. The dots are connected in a chain/caterpillar shape when at rest
64. The animation creates a traveling wave where dots sequentially drop down and bounce back up
7
8<!DOCTYPE html>
9<html>
10<head>
11<style>
12  * { margin: 0; padding: 0; box-sizing: border-box; }
13  body { background: #333; display: flex; align-items: center; justify-content: center; height: 100vh; overflow: hidden; }
14  canvas { display: block; }
15</style>
16</head>
17<body>
18<canvas id="c"></canvas>
19<script>
20const canvas = document.getElementById('c');
21const ctx = canvas.getContext('2d');
22canvas.width = 1024;
23canvas.height = 768;
24
25const N = 16;
26const startX = 140;
27const baseY = 190;
28const spacing = 46;
29const radius = 22;
30const cycleTime = 2000; // ms for wave to travel across all dots
31
32function getColor(i) {
33  const t = i / (N - 1);
34  const r = Math.round(255);
35  const g = Math.round(0 + (1 - t) * 0);
36  const b = Math.round((1 - t) * 255 * 0);
37  // magenta = ff00ff, red = ff0000
38  const rr = 255;
39  const gg = Math.round((1 - t) * 0);
40  const bb = Math.round((1 - t) * 255);
41  return `rgb(${rr},${gg},${bb})`;
42}
43
44function easeInOutSine(t) {
45  return -(Math.cos(Math.PI * t) - 1) / 2;
46}
47
48function getDotY(i, time) {
49  // Wave travels left to right
50  // Each dot has a phase offset
51  const waveSpeed = cycleTime;
52  const dotDelay = waveSpeed / N;
53  
54  // Phase for this dot
55  const phase = (time - i * dotDelay) / waveSpeed;
56  const p = ((phase % 1) + 1) % 1;
57  
58  // Drop down and come back: sine wave, only positive half
59  const dropAmount = 120;
60  const dropY = Math.sin(p * Math.PI) * dropAmount;
61  
62  return baseY + dropY;
63}
64
65function getDotRadius(i, time) {
66  const waveSpeed = cycleTime;
67  const dotDelay = waveSpeed / N;
68  const phase = (time - i * dotDelay) / waveSpeed;
69  const p = ((phase % 1) + 1) % 1;
70  
71  // Shrink slightly when at bottom
72  const scale = 1 - 0.3 * Math.sin(p * Math.PI);
73  return radius * scale;
74}
75
76function draw(time) {
77  ctx.clearRect(0, 0, canvas.width, canvas.height);
78  
79  // Draw dots from right to left so left ones appear on top
80  for (let i = N - 1; i >= 0; i--) {
81    const x = startX + i * spacing;
82    const y = getDotY(i, time);
83    const r = getDotRadius(i, time);
84    
85    ctx.beginPath();
86    ctx.arc(x, y, r, 0, Math.PI * 2);
87    ctx.fillStyle = getColor(i);
88    ctx.fill();
89  }
90  
91  requestAnimationFrame(draw);
92}
93
94requestAnimationFrame(draw);
95</script>
96</body>
97</html>
98
99Wait, let me re-analyze and create a more accurate version:
100
101<!DOCTYPE html>
102<html>
103<head>
104<style>
105* { margin: 0; padding: 0; box-sizing: border-box; }
106body { background: #333; display: flex; align-items: center; justify-content: center; height: 100vh; }
107canvas { display: block; }
108</style>
109</head>
110<body>
111<canvas id="c" width="1024" height="768"></canvas>
112<script>
113const canvas = document.getElementById('c');
114const ctx = canvas.getContext('2d');
115const N = 16;
116const startX = 145;
117const baseY = 190;
118const spacing = 46;
119const radius = 22;
120const cycleDuration = 2200;
121
122function getColor(i) {
123  const t = i / (N - 1);
124  return `rgb(255,${Math.round((1-t)*0)},${Math.round((1-t)*255)})`;
125}
126
127function draw(time) {
128  ctx.clearRect(0, 0, canvas.width, canvas.height);
129  for (let i = N - 1; i >= 0; i--) {
130    const x = startX + i * spacing;
131    const offset = (i / N) * cycleDuration;
132    const p = ((time - offset) % cycleDuration + cycleDuration) % cycleDuration / cycleDuration;
133    const dropY = Math.sin(p * Math.PI) * 130;
134    const r = radius * (1 - 0.35 * Math.sin(p * Math.PI));
135    const y = baseY + dropY;
136    ctx.beginPath();
137    ctx.arc(x, y, r, 0, Math.PI * 2);
138    ctx.fillStyle = getColor(i);
139    ctx.fill();
140  }
141  requestAnimationFrame(draw);
142}
143requestAnimationFrame(draw);
144</script>
145</body>
146</html>