animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Only CSS: Codevember #6 Money Storm

model output

GPT-5.4

Only CSS: Codevember #6 Money Storm

A 0.56T 0.30
compare with ground truth →
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" />
6<title>Falling Money</title>
7<style>
8  :root{
9    --bg:#000;
10    --paper:#f4efe3;
11    --paper2:#ece4d4;
12    --paper3:#e6ddcc;
13    --ink:#5f6f57;
14  }
15  html,body{
16    margin:0;
17    width:100%;
18    height:100%;
19    overflow:hidden;
20    background:var(--bg);
21  }
22  body{
23    perspective: 900px;
24    perspective-origin: 50% 50%;
25    font-family: Arial, Helvetica, sans-serif;
26  }
27  #scene{
28    position:fixed;
29    inset:0;
30    overflow:hidden;
31    transform-style:preserve-3d;
32    background:#000;
33  }
34  .bill{
35    position:absolute;
36    left:0; top:0;
37    width:120px;
38    height:56px;
39    transform-style:preserve-3d;
40    will-change:transform;
41    pointer-events:none;
42  }
43  .bill .strip{
44    position:absolute;
45    left:0;
46    width:100%;
47    height:25%;
48    transform-style:preserve-3d;
49    backface-visibility:hidden;
50    background:
51      linear-gradient(180deg, rgba(255,255,255,.18), rgba(0,0,0,.03)),
52      var(--paper);
53    border-radius:1px;
54    box-sizing:border-box;
55    overflow:hidden;
56  }
57  .bill .strip:nth-child(1){ top:0; background:
58      linear-gradient(180deg, rgba(255,255,255,.18), rgba(0,0,0,.03)),
59      var(--paper);}
60  .bill .strip:nth-child(2){ top:25%; background:
61      linear-gradient(180deg, rgba(255,255,255,.12), rgba(0,0,0,.04)),
62      var(--paper2);}
63  .bill .strip:nth-child(3){ top:50%; background:
64      linear-gradient(180deg, rgba(255,255,255,.10), rgba(0,0,0,.05)),
65      var(--paper);}
66  .bill .strip:nth-child(4){ top:75%; background:
67      linear-gradient(180deg, rgba(255,255,255,.14), rgba(0,0,0,.03)),
68      var(--paper3);}
69  .face{
70    position:absolute;
71    inset:0;
72    display:flex;
73    align-items:center;
74    justify-content:center;
75    color:var(--ink);
76    font-weight:700;
77    font-size:22px;
78    letter-spacing:1px;
79    opacity:.95;
80    mix-blend-mode:normal;
81    text-shadow:0 0 .2px rgba(0,0,0,.2);
82  }
83  .face::before,
84  .face::after{
85    content:"¥10,000";
86    position:absolute;
87    font-size:12px;
88    opacity:.9;
89  }
90  .face::before{ left:8px; top:5px; }
91  .face::after{ right:8px; bottom:5px; transform:rotate(180deg); }
92</style>
93</head>
94<body>
95<div id="scene"></div>
96
97<script>
98(() => {
99  const scene = document.getElementById('scene');
100  const W = () => innerWidth;
101  const H = () => innerHeight;
102
103  const COUNT = 34;
104  const bills = [];
105  const rand = (a,b)=>a + Math.random()*(b-a);
106
107  function makeBill(scale){
108    const bill = document.createElement('div');
109    bill.className = 'bill';
110    bill.style.width = `${120*scale}px`;
111    bill.style.height = `${56*scale}px`;
112
113    for(let i=0;i<4;i++){
114      const s = document.createElement('div');
115      s.className = 'strip';
116      const face = document.createElement('div');
117      face.className = 'face';
118      if(i===1) face.textContent = '¥10,000';
119      s.appendChild(face);
120      bill.appendChild(s);
121    }
122    scene.appendChild(bill);
123    return bill;
124  }
125
126  function resetBill(b, initial=false){
127    const depth = rand(-500, 500);
128    const scale = rand(0.55, 2.8) * (depth > 180 ? 1.25 : 1);
129    if(!b.el){
130      b.el = makeBill(scale);
131    }else{
132      b.el.style.width = `${120*scale}px`;
133      b.el.style.height = `${56*scale}px`;
134    }
135
136    b.scale = scale;
137    b.x = rand(W()*0.52, W()*0.78);
138    b.y = initial ? rand(-H()*0.2, H()*0.9) : rand(-H()*0.35, -40);
139    b.z = depth;
140
141    b.vx = rand(-18, 18);
142    b.vy = rand(70, 145);
143    b.vz = rand(-18, 18);
144
145    b.ry = rand(0, Math.PI*2);
146    b.rx = rand(-0.8, 0.8);
147    b.rz = rand(-1.2, 1.2);
148
149    b.spinY = rand(-1.8, 1.8);
150    b.spinZ = rand(-1.2, 1.2);
151    b.flutter = rand(4.5, 8.5);
152    b.flutterSpeed = rand(3.2, 6.8);
153    b.phase = rand(0, Math.PI*2);
154    b.drift = rand(10, 40);
155    b.driftSpeed = rand(.4, 1.2);
156    b.tilt = rand(.15, .55);
157
158    b.segs = [...b.el.children];
159  }
160
161  for(let i=0;i<COUNT;i++){
162    const b = {};
163    resetBill(b, true);
164    bills.push(b);
165  }
166
167  let last = performance.now();
168
169  function frame(now){
170    const dt = Math.min(0.033, (now - last) / 1000);
171    last = now;
172    const t = now / 1000;
173
174    for(const b of bills){
175      b.y += b.vy * dt;
176      b.x += (b.vx + Math.sin(t*b.driftSpeed + b.phase) * b.drift) * dt;
177      b.z += b.vz * dt;
178
179      b.ry += b.spinY * dt;
180      b.rz += b.spinZ * dt;
181
182      const flap = Math.sin(t * b.flutterSpeed + b.phase) * b.flutter;
183      const flap2 = Math.sin(t * b.flutterSpeed + b.phase + .8) * b.flutter * .72;
184      const flap3 = Math.sin(t * b.flutterSpeed + b.phase + 1.6) * b.flutter * .52;
185
186      b.rx = Math.sin(t * 1.7 + b.phase) * b.tilt;
187
188      const segAngles = [flap, flap2, -flap2, -flap3];
189      for(let i=0;i<4;i++){
190        const s = b.segs[i];
191        const origin = i < 2 ? '50% 100%' : '50% 0%';
192        s.style.transformOrigin = origin;
193        s.style.transform = `perspective(300px) rotateX(${segAngles[i]}deg)`;
194      }
195
196      const perspectiveScale = 1 + (b.z / 1200);
197      b.el.style.transform =
198        `translate3d(${b.x}px, ${b.y}px, ${b.z}px)
199         rotateX(${b.rx}rad)
200         rotateY(${b.ry}rad)
201         rotateZ(${b.rz}rad)
202         scale(${perspectiveScale})`;
203
204      if (b.y > H() + 180 || b.x < -260 || b.x > W() + 260 || b.z < -900 || b.z > 900) {
205        resetBill(b, false);
206      }
207    }
208
209    requestAnimationFrame(frame);
210  }
211
212  addEventListener('resize', () => {
213    for (const b of bills) {
214      if (b.x > W()) b.x = rand(W()*0.45, W()*0.8);
215    }
216  });
217
218  requestAnimationFrame(frame);
219})();
220</script>
221</body>
222</html>