← back to Only CSS: Bicyclecompare with ground truth →
model output
Gemini 3 Flash Preview
Only CSS: Bicycle
A 0.87T 0.36
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>Bicycle Animation</title>
7 <style>
8 :root {
9 --bg-color: #efeeff;
10 --purple-main: #9b68e6;
11 --purple-dark: #7a44cf;
12 --black: #333;
13 --speed-line: rgba(155, 104, 230, 0.4);
14 }
15
16 body {
17 margin: 0;
18 padding: 0;
19 height: 100vh;
20 display: flex;
21 justify-content: center;
22 align-items: center;
23 background-color: var(--bg-color);
24 font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
25 overflow: hidden;
26 }
27
28 .container {
29 position: relative;
30 width: 600px;
31 height: 600px;
32 display: flex;
33 flex-direction: column;
34 justify-content: center;
35 align-items: center;
36 perspective: 1200px;
37 }
38
39 .text {
40 font-size: 80px;
41 color: var(--purple-dark);
42 margin-bottom: 40px;
43 user-select: none;
44 z-index: 10;
45 }
46
47 /* 3D Scene */
48 .scene {
49 position: relative;
50 width: 300px;
51 height: 200px;
52 transform-style: preserve-3d;
53 animation: rotateBike 8s linear infinite;
54 }
55
56 @keyframes rotateBike {
57 0% { transform: rotateY(0deg); }
58 100% { transform: rotateY(-360deg); }
59 }
60
61 .shadow {
62 position: absolute;
63 width: 280px;
64 height: 40px;
65 background: rgba(0, 0, 0, 0.05);
66 border-radius: 50%;
67 bottom: -80px;
68 left: 10px;
69 filter: blur(8px);
70 transform: rotateX(90deg);
71 }
72
73 /* Bicycle Parts */
74 .bike-part {
75 position: absolute;
76 transform-style: preserve-3d;
77 }
78
79 /* Wheels */
80 .wheel {
81 width: 120px;
82 height: 120px;
83 border: 5px solid var(--black);
84 border-radius: 50%;
85 background: repeating-conic-gradient(from 0deg, transparent 0deg 5deg, #bbb 5deg 6deg, transparent 6deg 15deg);
86 box-shadow: inset 0 0 0 4px #555;
87 display: flex;
88 justify-content: center;
89 align-items: center;
90 }
91
92 .wheel::after {
93 content: '';
94 width: 10px;
95 height: 10px;
96 background: #666;
97 border-radius: 50%;
98 }
99
100 .wheel-front { transform: translate3d(100px, 40px, 0); }
101 .wheel-back { transform: translate3d(-100px, 40px, 0); }
102
103 /* Frame */
104 .frame-tube {
105 background-color: var(--purple-main);
106 height: 10px;
107 position: absolute;
108 border-radius: 5px;
109 box-shadow: inset -2px -2px 5px rgba(0,0,0,0.2);
110 }
111
112 /* Main Triangle */
113 .top-tube { width: 140px; transform: translate3d(-40px, 20px, 0) rotate(0deg); }
114 .down-tube { width: 150px; transform: translate3d(-50px, 60px, 0) rotate(-45deg); transform-origin: left; }
115 .seat-tube { width: 120px; transform: translate3d(-55px, 20px, 0) rotate(80deg); transform-origin: left; }
116
117 /* Rear Triangle */
118 .seat-stay { width: 110px; transform: translate3d(-100px, 95px, 0) rotate(-60deg); transform-origin: left; }
119 .chain-stay { width: 105px; transform: translate3d(-100px, 95px, 0) rotate(0deg); transform-origin: left; }
120
121 /* Handlebars & Fork */
122 .fork { width: 115px; transform: translate3d(100px, 95px, 0) rotate(-110deg); transform-origin: left; }
123 .handlebar-stem { width: 30px; transform: translate3d(63px, -15px, 0) rotate(-20deg); }
124 .handlebar-grip {
125 width: 60px;
126 height: 12px;
127 background: var(--purple-main);
128 transform: translate3d(40px, -20px, 0) rotateY(90deg);
129 border-radius: 6px;
130 }
131
132 /* Seat */
133 .seat {
134 width: 40px;
135 height: 15px;
136 background: #222;
137 border-radius: 5px 15px 5px 5px;
138 transform: translate3d(-75px, -15px, 0);
139 }
140
141 /* Speed Lines */
142 .speed-lines-container {
143 position: absolute;
144 top: 0;
145 left: 0;
146 width: 100%;
147 height: 100%;
148 pointer-events: none;
149 }
150
151 .line {
152 position: absolute;
153 height: 2px;
154 background: var(--speed-line);
155 border-radius: 2px;
156 animation: lineMove linear forwards;
157 }
158
159 @keyframes lineMove {
160 0% { transform: translateX(0) scaleX(0); opacity: 0; }
161 20% { opacity: 1; transform: translateX(-50px) scaleX(1); }
162 100% { transform: translateX(-400px) scaleX(1.5); opacity: 0; }
163 }
164
165 </style>
166</head>
167<body>
168
169 <div class="container">
170 <div class="text">Bicycle</div>
171
172 <div class="scene">
173 <div class="shadow"></div>
174
175 <!-- Frame Construction -->
176 <div class="bike-part frame-tube top-tube"></div>
177 <div class="bike-part frame-tube down-tube"></div>
178 <div class="bike-part frame-tube seat-tube"></div>
179 <div class="bike-part frame-tube seat-stay"></div>
180 <div class="bike-part frame-tube chain-stay"></div>
181 <div class="bike-part frame-tube fork"></div>
182 <div class="bike-part frame-tube handlebar-stem"></div>
183
184 <!-- Details -->
185 <div class="bike-part handlebar-grip"></div>
186 <div class="bike-part seat"></div>
187
188 <!-- Wheels -->
189 <div class="bike-part wheel wheel-front"></div>
190 <div class="bike-part wheel wheel-back"></div>
191 </div>
192
193 <div class="speed-lines-container" id="speedLines"></div>
194 </div>
195
196 <script>
197 const speedLinesContainer = document.getElementById('speedLines');
198
199 function createLine() {
200 const line = document.createElement('div');
201 line.className = 'line';
202
203 // Random positioning
204 const x = Math.random() * 800 + 400; // Start from right
205 const y = Math.random() * 600;
206 const width = Math.random() * 100 + 50;
207 const duration = Math.random() * 0.5 + 0.5;
208
209 line.style.left = `${x}px`;
210 line.style.top = `${y}px`;
211 line.style.width = `${width}px`;
212 line.style.animationDuration = `${duration}s`;
213
214 speedLinesContainer.appendChild(line);
215
216 // Cleanup
217 setTimeout(() => {
218 line.remove();
219 }, duration * 1000);
220 }
221
222 // Periodically spawn lines to match the video's acceleration feel
223 setInterval(() => {
224 createLine();
225 }, 150);
226
227 // Add 3D depth to frame tubes manually for simple "3D" effect
228 // In a complex app, we'd use a 3D library, but for a single file:
229 // We ensure the bike components are spaced slightly on Z axis for volume.
230 document.querySelector('.handlebar-grip').style.transform = 'translate3d(40px, -20px, 0) rotateY(90deg)';
231
232 </script>
233</body>
234</html>