animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Motion Table - Solid Rotation

model output

GPT-5.4

Motion Table - Solid Rotation

A 0.75T 0.27
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>Geometric Orbit Loop</title>
7<style>
8  :root{
9    --bg:#4a4648;
10    --line:rgba(255,255,255,.72);
11    --line-soft:rgba(255,255,255,.38);
12  }
13  html,body{
14    margin:0;
15    height:100%;
16    background:var(--bg);
17    overflow:hidden;
18  }
19  body{
20    display:grid;
21    place-items:center;
22  }
23  canvas{
24    width:100vw;
25    height:100vh;
26    display:block;
27  }
28</style>
29</head>
30<body>
31<canvas id="c"></canvas>
32<script>
33const canvas = document.getElementById('c');
34const ctx = canvas.getContext('2d');
35
36function resize(){
37  const dpr = Math.min(devicePixelRatio || 1, 2);
38  canvas.width = innerWidth * dpr;
39  canvas.height = innerHeight * dpr;
40  canvas.style.width = innerWidth + 'px';
41  canvas.style.height = innerHeight + 'px';
42  ctx.setTransform(dpr,0,0,dpr,0,0);
43}
44addEventListener('resize', resize);
45resize();
46
47const TAU = Math.PI * 2;
48const cycle = 6.4; // smooth looping duration
49
50function easeInOut(t){ return 0.5 - 0.5 * Math.cos(Math.PI * t); }
51function mix(a,b,t){ return a + (b-a)*t; }
52function clamp(v,a,b){ return Math.max(a, Math.min(b, v)); }
53function seg(t,a,b){
54  return clamp((t-a)/(b-a),0,1);
55}
56
57function drawEllipseOrbit(cx, cy, r, rot, sx, sy, alpha, dashed=false, lw=1){
58  ctx.save();
59  ctx.translate(cx, cy);
60  ctx.rotate(rot);
61  ctx.scale(sx, sy);
62  ctx.beginPath();
63  ctx.arc(0, 0, r, 0, TAU);
64  ctx.lineWidth = lw;
65  ctx.strokeStyle = dashed ? `rgba(255,255,255,${alpha*0.55})` : `rgba(255,255,255,${alpha})`;
66  ctx.setLineDash(dashed ? [2.2, 6.2] : []);
67  ctx.stroke();
68  ctx.restore();
69}
70
71function drawPolygon(cx, cy, radius, sides, rot, alpha, lw=1){
72  ctx.save();
73  ctx.translate(cx, cy);
74  ctx.rotate(rot);
75  ctx.beginPath();
76  for(let i=0;i<sides;i++){
77    const a = -Math.PI/2 + i*TAU/sides;
78    const x = Math.cos(a)*radius;
79    const y = Math.sin(a)*radius;
80    if(i===0) ctx.moveTo(x,y); else ctx.lineTo(x,y);
81  }
82  ctx.closePath();
83  ctx.lineWidth = lw;
84  ctx.strokeStyle = `rgba(255,255,255,${alpha})`;
85  ctx.stroke();
86  ctx.restore();
87}
88
89function render(ms){
90  const w = innerWidth, h = innerHeight;
91  const t = (ms/1000 % cycle) / cycle;
92
93  ctx.clearRect(0,0,w,h);
94
95  const cx = w * 0.5;
96  const cy = h * 0.5;
97  const baseR = Math.min(w,h) * 0.125;
98
99  // overall scale breathes slightly like the reference
100  const scale =
101    1
102    - 0.12 * easeInOut(seg(t, .18, .34))
103    + 0.08 * easeInOut(seg(t, .34, .52))
104    - 0.06 * easeInOut(seg(t, .72, .90));
105
106  const R = baseR * scale;
107
108  // outer ring always present
109  ctx.beginPath();
110  ctx.arc(cx, cy, R, 0, TAU);
111  ctx.lineWidth = 1.15;
112  ctx.strokeStyle = 'rgba(255,255,255,.82)';
113  ctx.stroke();
114
115  // phase envelopes
116  const p1 = easeInOut(seg(t, .14, .34)); // first emergence
117  const p2 = easeInOut(seg(t, .30, .58)); // dense ring
118  const p3 = easeInOut(seg(t, .52, .82)); // star / inner detail
119  const p4 = easeInOut(seg(t, .76, 1.00)); // fade back
120
121  // 6 main orbiting ellipses
122  const n = 6;
123  for(let i=0;i<n;i++){
124    const a = i * TAU / n;
125    const rot =
126      a
127      + TAU * (0.18*t)
128      + 0.22 * Math.sin(TAU*(t*2 + i*0.13));
129
130    const sx = mix(1, 0.62, p1);
131    const sy = mix(1, 0.62, p1);
132
133    let alpha = 0;
134    alpha += 0.34 * p1;
135    alpha += 0.22 * p2;
136    alpha *= (1 - 0.25*p4);
137
138    drawEllipseOrbit(cx, cy, R, rot, sx, sy, alpha, false, 1);
139
140    // dotted inner guides appear later
141    const dAlpha = 0.34 * p3 * (1 - 0.35*p4);
142    if(dAlpha > 0.002){
143      const dsx = mix(0.62, 0.42, p3);
144      const dsy = mix(0.62, 0.42, p3);
145      drawEllipseOrbit(cx, cy, R*0.98, -rot*1.08 + 0.35, dsx, dsy, dAlpha, true, 1);
146    }
147  }
148
149  // extra dense outer traces during middle / late frames
150  const dense = Math.round(mix(0, 6, p2 + p4*0.7));
151  for(let i=0;i<dense;i++){
152    const a = i * TAU / Math.max(1,dense) + TAU*t*0.11;
153    drawEllipseOrbit(
154      cx, cy, R,
155      a,
156      0.88 + 0.18*Math.sin(i*1.7 + t*TAU),
157      0.88 + 0.18*Math.cos(i*1.3 + t*TAU),
158      0.18 + 0.12*p2,
159      false, 1
160    );
161  }
162
163  // central polygon/star transitions
164  const starA = 0.42 * p3 * (1 - 0.55*p4);
165  if(starA > 0.002){
166    const sides = t < 0.62 ? 6 : 7;
167    drawPolygon(cx, cy, R * mix(0.18, 0.34, p3), sides, TAU*t*0.35, starA, 1);
168  }
169
170  // subtle inner ticks / spark points
171  const tickA = 0.42 * p3 * (1 - 0.4*p4);
172  if(tickA > 0.002){
173    ctx.save();
174    ctx.translate(cx, cy);
175    ctx.rotate(TAU*t*0.12);
176    ctx.strokeStyle = `rgba(255,255,255,${tickA})`;
177    ctx.lineWidth = 1;
178    const m = 12;
179    for(let i=0;i<m;i++){
180      const a = i * TAU / m;
181      const r0 = R * 0.28;
182      const r1 = R * 0.33;
183      ctx.beginPath();
184      ctx.moveTo(Math.cos(a)*r0, Math.sin(a)*r0);
185      ctx.lineTo(Math.cos(a)*r1, Math.sin(a)*r1);
186      ctx.stroke();
187    }
188    ctx.restore();
189  }
190
191  requestAnimationFrame(render);
192}
193requestAnimationFrame(render);
194</script>
195</body>
196</html>