← back to SVG Multi-Dripcompare with ground truth →
model output
Gemini 3 Flash Preview
SVG Multi-Drip
A 0.86T 0.25
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>Gooey Wave Animation</title>
7 <style>
8 :root {
9 --bg-color: #222222;
10 --dot-count: 25;
11 --anim-duration: 4s;
12 }
13
14 body {
15 margin: 0;
16 padding: 0;
17 display: flex;
18 justify-content: center;
19 align-items: center;
20 height: 100vh;
21 background-color: var(--bg-color);
22 overflow: hidden;
23 }
24
25 .container {
26 display: flex;
27 position: relative;
28 /* Simple gooey-like effect using contrast and blur if desired,
29 but here direct overlap achieves the visual match better. */
30 }
31
32 .column {
33 position: relative;
34 width: 14px; /* Dots are 20px, so 14px width creates overlap */
35 height: 80px;
36 display: flex;
37 flex-direction: column;
38 align-items: center;
39 justify-content: flex-start;
40 }
41
42 .dot {
43 border-radius: 50%;
44 position: absolute;
45 transition: background 0.3s;
46 }
47
48 .dot.top {
49 width: 20px;
50 height: 20px;
51 top: 0;
52 z-index: 2;
53 animation: moveTop var(--anim-duration) infinite cubic-bezier(0.45, 0, 0.55, 1);
54 }
55
56 .dot.bottom {
57 width: 5px;
58 height: 5px;
59 top: 40px; /* Base distance between centers */
60 z-index: 1;
61 animation: moveBottom var(--anim-duration) infinite cubic-bezier(0.45, 0, 0.55, 1);
62 }
63
64 /*
65 The animation:
66 Top dot: stays big, drops down, shrinks, then returns.
67 Bottom dot: stays small, moves up, grows, then returns.
68 */
69
70 @keyframes moveTop {
71 0%, 15%, 45%, 100% {
72 transform: translateY(0) scale(1);
73 }
74 30% {
75 transform: translateY(40px) scale(0.25);
76 }
77 }
78
79 @keyframes moveBottom {
80 0%, 15%, 45%, 100% {
81 transform: translateY(0) scale(1);
82 }
83 30% {
84 transform: translateY(-40px) scale(4);
85 }
86 }
87
88 /* Helper to center the container */
89 .stage {
90 display: flex;
91 justify-content: center;
92 width: 100%;
93 }
94 </style>
95</head>
96<body>
97
98 <div class="stage">
99 <div class="container" id="dotContainer">
100 <!-- Columns generated by JS -->
101 </div>
102 </div>
103
104 <script>
105 const container = document.getElementById('dotContainer');
106 const dotCount = 25;
107 const delayStep = 0.08; // Seconds between each column's animation start
108
109 function createDots() {
110 for (let i = 0; i < dotCount; i++) {
111 const column = document.createElement('div');
112 column.className = 'column';
113
114 // Calculate color gradient from Pink (#FF00FF) to Red (#FF0000)
115 // Interpolating only the Blue channel from 255 to 0
116 const blueValue = Math.floor(255 - (i * (255 / (dotCount - 1))));
117 const color = `rgb(255, 0, ${blueValue})`;
118
119 const topDot = document.createElement('div');
120 topDot.className = 'dot top';
121 topDot.style.backgroundColor = color;
122 topDot.style.animationDelay = `${i * delayStep}s`;
123
124 const bottomDot = document.createElement('div');
125 bottomDot.className = 'dot bottom';
126 bottomDot.style.backgroundColor = color;
127 bottomDot.style.animationDelay = `${i * delayStep}s`;
128
129 column.appendChild(topDot);
130 column.appendChild(bottomDot);
131 container.appendChild(column);
132 }
133 }
134
135 createDots();
136 </script>
137</body>
138</html>