← back to Only CSS: Grid Template Animationcompare with ground truth →
model output
Claude Sonnet 4.6
Only CSS: Grid Template Animation
A 0.80T 0.33
1Looking at the animation, I can see a 10x10 grid of rounded rectangle cells, each containing a dot in the center. The animation cycles through different states where cells morph between square and wide/tall rectangular shapes in a wave-like pattern, creating a breathing/pulsing effect across the grid.
2
3Key observations:
4- Dark navy background
5- Cyan/teal colored cell borders with glow effect
6- Cyan dots in center of each cell
7- Cells animate between square (~40px) and wide rectangle (~120px wide) or tall rectangle shapes
8- The pattern repeats with alternating columns/rows expanding
9- Animation has a smooth sinusoidal quality
10- The whole grid slightly rotates during some frames
11
12<!DOCTYPE html>
13<html>
14<head>
15<style>
16* { margin: 0; padding: 0; box-sizing: border-box; }
17body {
18 background: #0a1628;
19 display: flex;
20 align-items: center;
21 justify-content: center;
22 width: 100vw;
23 height: 100vh;
24 overflow: hidden;
25}
26canvas {
27 display: block;
28}
29</style>
30</head>
31<body>
32<canvas id="c"></canvas>
33<script>
34const canvas = document.getElementById('c');
35const ctx = canvas.getContext('2d');
36canvas.width = 1024;
37canvas.height = 680;
38
39const COLS = 10;
40const ROWS = 10;
41const BASE_SIZE = 42;
42const GAP = 8;
43const BORDER_COLOR = '#1a9fc0';
44const DOT_COLOR = '#4dffd4';
45const BORDER_RADIUS = 8;
46const ANIM_DURATION = 4000; // ms for full cycle
47
48function drawRoundRect(x, y, w, h, r) {
49 r = Math.min(r, w/2, h/2);
50 ctx.beginPath();
51 ctx.moveTo(x + r, y);
52 ctx.lineTo(x + w - r, y);
53 ctx.quadraticCurveTo(x + w, y, x + w, y + r);
54 ctx.lineTo(x + w, y + h - r);
55 ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
56 ctx.lineTo(x + r, y + h);
57 ctx.quadraticCurveTo(x, y + h, x, y + h - r);
58 ctx.lineTo(x, y + r);
59 ctx.quadraticCurveTo(x, y, x + r, y);
60 ctx.closePath();
61}
62
63function easeInOut(t) {
64 return t < 0.5 ? 2*t*t : -1+(4-2*t)*t;
65}
66
67function render(ts) {
68 ctx.clearRect(0, 0, canvas.width, canvas.height);
69
70 // Background gradient
71 const bg = ctx.createRadialGradient(512, 340, 50, 512, 340, 600);
72 bg.addColorStop(0, '#0d1f35');
73 bg.addColorStop(1, '#060e1a');
74 ctx.fillStyle = bg;
75 ctx.fillRect(0, 0, canvas.width, canvas.height);
76
77 const t = (ts % ANIM_DURATION) / ANIM_DURATION; // 0..1
78
79 // Phase: 0=square, 0.25=wide, 0.5=square, 0.75=tall, 1=square
80 // Each cell has offset based on position
81
82 const gridW = COLS * BASE_SIZE + (COLS - 1) * GAP;
83 const gridH = ROWS * BASE_SIZE + (ROWS - 1) * GAP;
84 const startX = (canvas.width - gridW) / 2;
85 const startY = (canvas.height - gridH) / 2;
86
87 // Slight rotation based on phase
88 const rotAngle = Math.sin(t * Math.PI * 2) * 0.04;
89
90 ctx.save();
91 ctx.translate(canvas.width/2, canvas.height/2);
92 ctx.rotate(rotAngle);
93 ctx.translate(-canvas.width/2, -canvas.height/2);
94
95 for (let row = 0; row < ROWS; row++) {
96 for (let col = 0; col < COLS; col++) {
97 // Each cell gets a phase offset based on column (for horizontal wave)
98 const colPhase = col / COLS;
99 const rowPhase = row / ROWS;
100
101 // Two wave patterns: horizontal expansion and vertical expansion
102 // alternating columns expand wide, alternating rows expand tall
103 const isWideCol = col % 3 === 1; // columns 1,4,7 expand wide
104 const isTallRow = row % 3 === 1; // rows 1,4,7 expand tall
105
106 // Wave traveling across columns
107 const waveT = (t + colPhase * 0.3) % 1;
108 const waveT2 = (t + rowPhase * 0.3 + 0.5) % 1;
109
110 // Width expansion: sine wave
111 let wFactor = 0;
112 let hFactor = 0;
113
114 if (isWideCol) {
115 // Expand width based on wave
116 wFactor = Math.max(0, Math.sin(waveT * Math.PI * 2)) * 2.2;
117 }
118 if (isTallRow) {
119 hFactor = Math.max(0, Math.sin(waveT2 * Math.PI * 2)) * 1.8;
120 }
121
122 const cellW = BASE_SIZE + wFactor * BASE_SIZE;
123 const cellH = BASE_SIZE + hFactor * BASE_SIZE;
124
125 // Calculate position - cells in expanding columns push neighbors
126 // Simplified: use fixed grid positions but vary cell size
127 const cx = startX + col * (BASE_SIZE + GAP);
128 const cy = startY + row * (BASE_SIZE + GAP);
129
130 // Center the cell at its grid position
131 const x = cx + (BASE_SIZE - cellW) / 2;
132 const y = cy + (BASE_SIZE - cellH) / 2;
133
134 // Draw cell border with glow
135 ctx.save();
136 ctx.shadowColor = '#1a9fc0';
137 ctx.shadowBlur = 6;
138 ctx.strokeStyle = BORDER_COLOR;
139 ctx.lineWidth = 1.5;
140 drawRoundRect(x, y, cellW, cellH, BORDER_RADIUS);
141 ctx.stroke();
142 ctx.restore();
143
144 // Draw dot
145 const dotX = cx + BASE_SIZE / 2;
146 const dotY = cy + BASE_SIZE / 2;
147 const dotR = 3.5;
148
149 ctx.save();
150 ctx.shadowColor = DOT_COLOR;
151 ctx.shadowBlur = 8;
152 ctx.fillStyle = DOT_COLOR;
153 ctx.beginPath();
154 ctx.arc(dotX, dotY, dotR, 0, Math.PI * 2);
155 ctx.fill();
156 ctx.restore();
157 }
158 }
159
160 ctx.restore();
161 requestAnimationFrame(render);
162}
163
164requestAnimationFrame(render);
165</script>
166</body>
167</html>