← back to Only CSS: Flex Breezecompare with ground truth →
model output
Claude Sonnet 4.6
Only CSS: Flex Breeze
A 0.85T 0.52
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>Breeze Animation</title>
7<style>
8 * { margin: 0; padding: 0; box-sizing: border-box; }
9
10 body {
11 background: white;
12 display: flex;
13 justify-content: center;
14 align-items: center;
15 min-height: 100vh;
16 font-family: Arial, sans-serif;
17 }
18
19 .container {
20 position: relative;
21 width: 700px;
22 height: 420px;
23 }
24
25 .title {
26 position: absolute;
27 top: 20px;
28 left: 50%;
29 transform: translateX(-20%);
30 font-size: 32px;
31 font-weight: 900;
32 font-style: italic;
33 color: #00CFFF;
34 letter-spacing: 3px;
35 }
36
37 canvas {
38 position: absolute;
39 top: 70px;
40 left: 0;
41 }
42</style>
43</head>
44<body>
45<div class="container">
46 <div class="title">BREEZE</div>
47 <canvas id="c" width="700" height="340"></canvas>
48</div>
49
50<script>
51const canvas = document.getElementById('c');
52const ctx = canvas.getContext('2d');
53
54const NUM_BARS = 42;
55const BAR_WIDTH = 7;
56const BAR_RADIUS = 3.5;
57const GAP = 9;
58const START_X = 30;
59
60// Three rows
61const rows = [
62 { color: '#00CFFF', baseY: 30, heightBase: 90, waveAmp: 40, waveSpeed: 1.0, waveOffset: 0 },
63 { color: '#FFB6C8', baseY: 120, heightBase: 70, waveAmp: 35, waveSpeed: 1.0, waveOffset: Math.PI * 0.6 },
64 { color: '#4CD137', baseY: 200, heightBase: 90, waveAmp: 40, waveSpeed: 1.0, waveOffset: Math.PI * 1.2 },
65];
66
67let time = 0;
68
69function drawBar(x, y, h, color) {
70 ctx.beginPath();
71 ctx.roundRect(x - BAR_WIDTH/2, y, BAR_WIDTH, h, BAR_RADIUS);
72 ctx.fillStyle = color;
73 ctx.fill();
74}
75
76function animate() {
77 ctx.clearRect(0, 0, canvas.width, canvas.height);
78
79 time += 0.03;
80
81 for (let row of rows) {
82 for (let i = 0; i < NUM_BARS; i++) {
83 const x = START_X + i * (BAR_WIDTH + GAP);
84 const phase = (i / NUM_BARS) * Math.PI * 2 - time + row.waveOffset;
85
86 // Wave affects the vertical position (top of bar)
87 const waveY = Math.sin(phase) * row.waveAmp;
88
89 // Height varies slightly with wave
90 const h = row.heightBase + Math.sin(phase + 0.5) * 10;
91
92 const y = row.baseY + waveY;
93
94 drawBar(x, y, h, row.color);
95 }
96 }
97
98 requestAnimationFrame(animate);
99}
100
101// Polyfill roundRect if needed
102if (!ctx.roundRect) {
103 CanvasRenderingContext2D.prototype.roundRect = function(x, y, w, h, r) {
104 this.beginPath();
105 this.moveTo(x + r, y);
106 this.lineTo(x + w - r, y);
107 this.quadraticCurveTo(x + w, y, x + w, y + r);
108 this.lineTo(x + w, y + h - r);
109 this.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
110 this.lineTo(x + r, y + h);
111 this.quadraticCurveTo(x, y + h, x, y + h - r);
112 this.lineTo(x, y + r);
113 this.quadraticCurveTo(x, y, x + r, y);
114 this.closePath();
115 };
116}
117
118animate();
119</script>
120</body>
121</html>