← back to Only CSS: Japanese "人力車"compare with ground truth →
model output
Claude Sonnet 4.6
Only CSS: Japanese "人力車"
A 0.67T 0.43
1Looking at the animation frames, I can see a 3D chair-like object (with a back panel, seat, two wheels/circles, and axles) that rotates continuously. The object consists of:
2- A gradient rectangle (yellow to red) as the back
3- A red rectangle as the seat
4- Two black ellipses as wheels
5- Black rectangles as axles
6- A parallelogram outline as the base/floor
7
8The whole assembly rotates around a vertical axis continuously.
9
10<!DOCTYPE html>
11<html>
12<head>
13<style>
14 body { margin: 0; background: white; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; }
15 canvas { display: block; }
16</style>
17</head>
18<body>
19<canvas id="c" width="1024" height="768"></canvas>
20<script>
21const canvas = document.getElementById('c');
22const ctx = canvas.getContext('2d');
23
24let angle = 0;
25const cx = 512, cy = 400;
26
27function project(x, y, z) {
28 // Simple perspective projection
29 const fov = 600;
30 const camZ = 800;
31 const scale = fov / (fov + z);
32 return {
33 x: cx + x * scale,
34 y: cy + y * scale,
35 scale: scale
36 };
37}
38
39function rotateY(x, y, z, a) {
40 return {
41 x: x * Math.cos(a) + z * Math.sin(a),
42 y: y,
43 z: -x * Math.sin(a) + z * Math.cos(a)
44 };
45}
46
47function drawScene(a) {
48 ctx.clearRect(0, 0, 1024, 768);
49
50 // Define chair geometry in 3D
51 // Chair back: rectangle from (-80,-200,-10) to (80,0,-10)
52 // Chair seat: rectangle from (-80,0,-10) to (80,0,100)
53 // Two wheels: ellipses at x=-90 and x=90, centered at y=0, z=50
54 // Axles: rectangles connecting wheels
55 // Base frame: parallelogram on ground
56
57 const backW = 160, backH = 200;
58 const seatD = 110;
59 const wheelRY = 100, wheelRZ = 100;
60 const axleW = 50, axleH = 30;
61
62 // Back panel corners (in local space before rotation)
63 function makeBack() {
64 return [
65 {x:-80, y:-200, z:0},
66 {x: 80, y:-200, z:0},
67 {x: 80, y: 0, z:0},
68 {x:-80, y: 0, z:0}
69 ];
70 }
71
72 function makeSeat() {
73 return [
74 {x:-80, y:0, z:0},
75 {x: 80, y:0, z:0},
76 {x: 80, y:0, z:110},
77 {x:-80, y:0, z:110}
78 ];
79 }
80
81 function makeBase() {
82 return [
83 {x:-120, y:30, z:-30},
84 {x: 120, y:30, z:-30},
85 {x: 180, y:30, z:150},
86 {x:-180, y:30, z:150}
87 ];
88 }
89
90 function transform(pts) {
91 return pts.map(p => {
92 const r = rotateY(p.x, p.y, p.z, a);
93 return project(r.x, r.y, r.z);
94 });
95 }
96
97 function transform3(pts) {
98 return pts.map(p => {
99 return rotateY(p.x, p.y, p.z, a);
100 });
101 }
102
103 // Draw base frame
104 const basePts = transform(makeBase());
105 ctx.beginPath();
106 ctx.moveTo(basePts[0].x, basePts[0].y);
107 for(let i=1;i<basePts.length;i++) ctx.lineTo(basePts[i].x, basePts[i].y);
108 ctx.closePath();
109 ctx.strokeStyle = '#000';
110 ctx.lineWidth = 6;
111 ctx.stroke();
112
113 // Draw seat
114 const seatPts = transform(makeSeat());
115 ctx.beginPath();
116 ctx.moveTo(seatPts[0].x, seatPts[0].y);
117 for(let i=1;i<seatPts.length;i++) ctx.lineTo(seatPts[i].x, seatPts[i].y);
118 ctx.closePath();
119 ctx.fillStyle = 'red';
120 ctx.fill();
121
122 // Draw back panel with gradient
123 const backPts3 = transform3(makeBack());
124 const backPts = backPts3.map(p => project(p.x, p.y, p.z));
125
126 // Create gradient for back
127 const grad = ctx.createLinearGradient(
128 (backPts[0].x+backPts[1].x)/2, backPts[0].y,
129 (backPts[2].x+backPts[3].x)/2, backPts[2].y
130 );
131 grad.addColorStop(0, 'yellow');
132 grad.addColorStop(1, 'red');
133
134 ctx.beginPath();
135 ctx.moveTo(backPts[0].x, backPts[0].y);
136 for(let i=1;i<backPts.length;i++) ctx.lineTo(backPts[i].x, backPts[i].y);
137 ctx.closePath();
138 ctx.fillStyle = grad;
139 ctx.fill();
140
141 // Draw wheels as ellipses
142 function drawWheel(wx, wy, wz) {
143 const r3 = rotateY(wx, wy, wz, a);
144 const center = project(r3.x, r3.y, r3.z);
145
146 // Wheel is in YZ plane locally, so we need to find the projected axes
147 // Top of wheel
148 const top3 = rotateY(wx, wy - wheelRY, wz, a);
149 const topP = project(top3.x, top3.y, top3.z);
150 const front3 = rotateY(wx, wy, wz + wheelRZ, a);
151 const frontP = project(front3.x, front3.y, front3.z);
152
153 const rx = Math.sqrt(Math.pow(frontP.x - center.x,2) + Math.pow(frontP.y - center.y,2));
154 const ry = Math.sqrt(Math.pow(topP.x - center.x,2) + Math.pow(topP.y - center.y,2));
155 const rot = Math.atan2(frontP.y - center.y, frontP.x - center.x);
156
157 ctx.save();
158 ctx.translate(center.x, center.y);
159 ctx.rotate(rot);
160 ctx.beginPath();
161 ctx.ellipse(0, 0, Math.max(rx,5), Math.max(ry,5), 0, 0, Math.PI*2);
162 ctx.strokeStyle = '#000';
163 ctx.lineWidth = 6;
164 ctx.stroke();
165 ctx.restore();
166 }
167
168 // Axle boxes
169 function drawAxle(wx, wy, wz) {
170 const pts = [
171 {x:wx-15, y:wy-20, z:wz-15},
172 {x:wx+15, y:wy-20, z:wz-15},
173 {x:wx+15, y:wy+10, z:wz-15},
174 {x:wx-15, y:wy+10, z:wz-15},
175 ];
176 const top = [
177 {x:wx-15, y:wy-20, z:wz+15},
178 {x:wx+15, y:wy-20, z:wz+15},
179 {x:wx+15, y:wy+10, z:wz+15},
180 {x:wx-15, y:wy+10, z:wz+15},
181 ];
182 const front = transform([pts[0],pts[1],top[1],top[0]]);
183 const face = transform(pts);
184 ctx.beginPath();
185 ctx.moveTo(face[0].x,face[0].y);
186 face.forEach(p=>ctx.lineTo(p.x,p.y));
187 ctx.closePath();
188 ctx.fillStyle='#111';
189 ctx.fill();
190 ctx.beginPath();
191 ctx.moveTo(front[0].x,front[0].y);
192 front.forEach(p=>ctx.lineTo(p.x,p.y));
193 ctx.closePath();
194 ctx.fillStyle='#333';
195 ctx.fill();
196 }
197
198 drawAxle(-90, 0, 55);
199 drawAxle(90, 0, 55);
200
201 drawWheel(-90, 0, 55);
202 drawWheel(90, 0, 55);
203}
204
205function animate() {
206 angle += 0.02;
207 drawScene(angle);
208 requestAnimationFrame(animate);
209}
210
211animate();
212</script>
213</body>
214</html>