animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Only CSS: 3D Scan

model output

GPT-5.4

Only CSS: 3D Scan

A 0.79T 0.18
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>Wireframe Cube + Orbiting Rings</title>
7<style>
8  :root{
9    --bg1:#0a0d17;
10    --bg2:#102131;
11    --cube:#d7e6ff;
12    --cyan:#7fe7df;
13    --blue:#6f7cff;
14    --violet:#8a5cff;
15    --panel:#17365a;
16    --dur:6.4s;
17    --ease:cubic-bezier(.42,0,.58,1);
18  }
19
20  html,body{
21    margin:0;
22    height:100%;
23    overflow:hidden;
24    background:
25      radial-gradient(ellipse at center, #17304a 0%, #0d1624 42%, #090c15 100%);
26    font-family:system-ui,sans-serif;
27  }
28
29  .scene{
30    position:relative;
31    width:100vw;
32    height:100vh;
33    display:grid;
34    place-items:center;
35  }
36
37  .wrap{
38    position:relative;
39    width:min(54vmin,560px);
40    aspect-ratio:1;
41    transform:translateY(-1vmin);
42  }
43
44  svg{
45    width:100%;
46    height:100%;
47    overflow:visible;
48    filter: drop-shadow(0 0 .35vmin rgba(120,180,255,.08));
49  }
50
51  .cube line,
52  .cube rect{
53    stroke:rgba(220,235,255,.18);
54    stroke-width:1.1;
55    fill:none;
56    vector-effect:non-scaling-stroke;
57  }
58
59  .panel{
60    fill:rgba(40,95,155,.18);
61    stroke:none;
62  }
63
64  .rings ellipse{
65    fill:none;
66    stroke-width:2.2;
67    vector-effect:non-scaling-stroke;
68    mix-blend-mode:screen;
69    filter: drop-shadow(0 0 4px rgba(120,160,255,.12));
70  }
71
72  .rings .c1{ stroke:rgba(127,231,223,.72); }
73  .rings .c2{ stroke:rgba(111,124,255,.72); }
74  .rings .c3{ stroke:rgba(138,92,255,.68); }
75
76  .dot{
77    fill:none;
78    stroke-width:1.4;
79    vector-effect:non-scaling-stroke;
80    opacity:.9;
81  }
82
83  .dot.cyan{ stroke:rgba(127,231,223,.7); }
84  .dot.violet{ stroke:rgba(111,124,255,.7); }
85
86  .ringsGroup{
87    transform-origin:50% 50%;
88    animation: drift var(--dur) var(--ease) infinite;
89  }
90
91  .splitL,.splitR{
92    animation: split var(--dur) linear infinite;
93  }
94
95  .pulse{
96    animation: pulse var(--dur) linear infinite;
97  }
98
99  @keyframes drift{
100    0%   { transform:translateX(-7.5%) translateY(0); }
101    55%  { transform:translateX(8.5%) translateY(0); }
102    72%  { transform:translateX(10%) translateY(0); }
103    84%  { transform:translateX(2%) translateY(0); }
104    100% { transform:translateX(-7.5%) translateY(0); }
105  }
106
107  @keyframes split{
108    0%,72%   { opacity:0; }
109    73%      { opacity:0; }
110    80%      { opacity:1; }
111    92%      { opacity:1; }
112    100%     { opacity:0; }
113  }
114
115  @keyframes pulse{
116    0%,68%   { opacity:1; }
117    74%      { opacity:.95; }
118    80%      { opacity:.85; }
119    88%      { opacity:.55; }
120    100%     { opacity:1; }
121  }
122</style>
123</head>
124<body>
125<div class="scene">
126  <div class="wrap">
127    <svg viewBox="0 0 600 600" aria-label="abstract geometric animation">
128      <!-- cube -->
129      <g class="cube" id="cube"></g>
130
131      <!-- center panel -->
132      <rect class="panel" x="205" y="145" width="190" height="310" rx="10"></rect>
133
134      <!-- main moving ring cluster -->
135      <g class="ringsGroup pulse">
136        <g class="rings" id="rings"></g>
137      </g>
138
139      <!-- split phase overlays -->
140      <g class="splitL rings" id="splitLeft"></g>
141      <g class="splitR rings" id="splitRight"></g>
142    </svg>
143  </div>
144</div>
145
146<script>
147(() => {
148  const svgNS = "http://www.w3.org/2000/svg";
149
150  // --- Wireframe cube made from repeated rounded rectangles + connecting edges
151  const cube = document.getElementById("cube");
152  const front = { x: 205, y: 145, w: 190, h: 310, rx: 10 };
153  const dx = 10.5, dy = -5.2, layers = 18;
154
155  for(let i = layers - 1; i >= 0; i--){
156    const r = document.createElementNS(svgNS, "rect");
157    r.setAttribute("x", front.x - dx * i);
158    r.setAttribute("y", front.y - dy * i);
159    r.setAttribute("width", front.w);
160    r.setAttribute("height", front.h);
161    r.setAttribute("rx", front.rx);
162    cube.appendChild(r);
163  }
164
165  const corners = [
166    [front.x, front.y],
167    [front.x + front.w, front.y],
168    [front.x + front.w, front.y + front.h],
169    [front.x, front.y + front.h]
170  ];
171
172  corners.forEach(([x,y]) => {
173    const line = document.createElementNS(svgNS, "line");
174    line.setAttribute("x1", x);
175    line.setAttribute("y1", y);
176    line.setAttribute("x2", x - dx * (layers - 1));
177    line.setAttribute("y2", y - dy * (layers - 1));
178    cube.appendChild(line);
179  });
180
181  // --- Main ring cluster
182  const rings = document.getElementById("rings");
183  const cx = 300, cy = 300;
184  const colors = ["c1","c2","c3"];
185
186  // overlapping vertical ellipses to mimic the spherical stack
187  const offsets = [-72,-58,-44,-30,-16,0,16,30,44,58,72];
188  offsets.forEach((ox, i) => {
189    const e = document.createElementNS(svgNS, "ellipse");
190    e.setAttribute("cx", cx + ox);
191    e.setAttribute("cy", cy);
192    e.setAttribute("rx", 78);
193    e.setAttribute("ry", 118);
194    e.setAttribute("class", colors[i % colors.length]);
195    rings.appendChild(e);
196  });
197
198  // a few inner rings visible during the sweep
199  [
200    {x:cx-58, rx:42, ry:74, c:"c1"},
201    {x:cx-8,  rx:52, ry:92, c:"c3"},
202    {x:cx+42, rx:38, ry:62, c:"c1"}
203  ].forEach(o=>{
204    const e = document.createElementNS(svgNS, "ellipse");
205    e.setAttribute("cx", o.x);
206    e.setAttribute("cy", cy);
207    e.setAttribute("rx", o.rx);
208    e.setAttribute("ry", o.ry);
209    e.setAttribute("class", o.c);
210    rings.appendChild(e);
211  });
212
213  // tiny center dot ring
214  const dot = document.createElementNS(svgNS, "ellipse");
215  dot.setAttribute("cx", cx - 42);
216  dot.setAttribute("cy", cy);
217  dot.setAttribute("rx", 10);
218  dot.setAttribute("ry", 14);
219  dot.setAttribute("class", "dot cyan");
220  rings.appendChild(dot);
221
222  // --- Split phase: left purple cluster
223  const splitLeft = document.getElementById("splitLeft");
224  [
225    {cx:220, cy:300, rx:58, ry:82, c:"c3"},
226    {cx:232, cy:300, rx:42, ry:64, c:"c2"},
227    {cx:244, cy:300, rx:28, ry:42, c:"c3"}
228  ].forEach(o=>{
229    const e = document.createElementNS(svgNS, "ellipse");
230    e.setAttribute("cx", o.cx);
231    e.setAttribute("cy", o.cy);
232    e.setAttribute("rx", o.rx);
233    e.setAttribute("ry", o.ry);
234    e.setAttribute("class", o.c);
235    splitLeft.appendChild(e);
236  });
237
238  // --- Split phase: right cyan cluster
239  const splitRight = document.getElementById("splitRight");
240  [
241    {cx:392, cy:300, rx:54, ry:76, c:"c1"},
242    {cx:382, cy:300, rx:38, ry:56, c:"c1"},
243    {cx:372, cy:300, rx:22, ry:34, c:"c1"}
244  ].forEach(o=>{
245    const e = document.createElementNS(svgNS, "ellipse");
246    e.setAttribute("cx", o.cx);
247    e.setAttribute("cy", o.cy);
248    e.setAttribute("rx", o.rx);
249    e.setAttribute("ry", o.ry);
250    e.setAttribute("class", o.c);
251    splitRight.appendChild(e);
252  });
253
254  // small isolated ring appearing before the split
255  const lone = document.createElementNS(svgNS, "ellipse");
256  lone.setAttribute("cx", 190);
257  lone.setAttribute("cy", 300);
258  lone.setAttribute("rx", 22);
259  lone.setAttribute("ry", 34);
260  lone.setAttribute("class", "dot violet");
261  lone.style.animation = "split var(--dur) linear infinite";
262  lone.style.animationDelay = "-0.22s";
263  splitLeft.appendChild(lone);
264})();
265</script>
266</body>
267</html>