← back to Camera following: Step8compare with ground truth →
model output
GPT-5.4
Camera following: Step8
A 0.84T 0.31
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>Three Orbiting Spheres</title>
7<style>
8 :root{
9 --w: 1024px;
10 --h: 768px;
11 --ball: 108px;
12 --cx: 512px;
13 --cy: 384px;
14 --rx: 205px;
15 --ry: 118px;
16 --dur: 3.2s;
17 }
18
19 html, body {
20 margin: 0;
21 width: 100%;
22 height: 100%;
23 overflow: hidden;
24 background:
25 radial-gradient(circle at 50% 58%, #ffffff 0 22%, #f5f5fb 42%, #e8e8f3 68%, #d8d8e8 100%);
26 }
27
28 body{
29 display:grid;
30 place-items:center;
31 font-family:sans-serif;
32 }
33
34 .scene{
35 position: relative;
36 width: min(100vw, calc(100vh * 4 / 3));
37 aspect-ratio: 4 / 3;
38 overflow: hidden;
39 background:
40 radial-gradient(circle at 50% 58%, #ffffff 0 22%, #f5f5fb 42%, #e8e8f3 68%, #d8d8e8 100%);
41 }
42
43 .orbit{
44 position:absolute;
45 inset:0;
46 animation: spin var(--dur) linear infinite;
47 transform-origin: 50% 50%;
48 }
49
50 .ball-wrap{
51 position:absolute;
52 left:50%;
53 top:50%;
54 width:0;
55 height:0;
56 }
57
58 .ball{
59 position:absolute;
60 width:var(--ball);
61 height:var(--ball);
62 border-radius:50%;
63 transform: translate(-50%, -50%);
64 background:
65 radial-gradient(circle at 38% 24%, #9fc4ff 0%, #7ea8ff 22%, #5f6dff 48%, #4b1fe8 68%, #35108f 100%);
66 box-shadow:
67 inset -8px -10px 14px rgba(0,0,0,.10),
68 inset 10px 10px 18px rgba(255,255,255,.18),
69 0 2px 6px rgba(0,0,0,.08);
70 }
71
72 .ball::after{
73 content:"";
74 position:absolute;
75 left:50%;
76 top:100%;
77 width:78%;
78 height:28%;
79 transform:translate(-50%, 10px);
80 border-radius:50%;
81 background: radial-gradient(ellipse at center, rgba(120,90,220,.16) 0%, rgba(120,90,220,.08) 45%, rgba(120,90,220,0) 75%);
82 filter: blur(3px);
83 }
84
85 /* positions around an ellipse, with slight vertical staggering to mimic perspective */
86 .b1 { transform: translate(calc(-50% + var(--rx)), calc(-50% + 0px)); }
87 .b2 { transform: translate(calc(-50% - .5 * var(--rx)), calc(-50% - .866 * var(--ry))); }
88 .b3 { transform: translate(calc(-50% - .5 * var(--rx)), calc(-50% + .866 * var(--ry))); }
89
90 /* depth / size changes over the cycle */
91 .ball-wrap:nth-child(1){ animation: depth1 var(--dur) linear infinite; }
92 .ball-wrap:nth-child(2){ animation: depth2 var(--dur) linear infinite; }
93 .ball-wrap:nth-child(3){ animation: depth3 var(--dur) linear infinite; }
94
95 @keyframes spin {
96 from { transform: rotate(0deg); }
97 to { transform: rotate(360deg); }
98 }
99
100 @keyframes depth1 {
101 0% { z-index: 3; transform: scale(1.00); }
102 16.6%{ z-index: 2; transform: scale(.90); }
103 33.3%{ z-index: 1; transform: scale(.82); }
104 50% { z-index: 1; transform: scale(.84); }
105 66.6%{ z-index: 2; transform: scale(.92); }
106 83.3%{ z-index: 3; transform: scale(1.02); }
107 100% { z-index: 3; transform: scale(1.00); }
108 }
109
110 @keyframes depth2 {
111 0% { z-index: 2; transform: scale(.90); }
112 16.6%{ z-index: 1; transform: scale(.82); }
113 33.3%{ z-index: 1; transform: scale(.84); }
114 50% { z-index: 2; transform: scale(.92); }
115 66.6%{ z-index: 3; transform: scale(1.02); }
116 83.3%{ z-index: 3; transform: scale(1.00); }
117 100% { z-index: 2; transform: scale(.90); }
118 }
119
120 @keyframes depth3 {
121 0% { z-index: 1; transform: scale(.82); }
122 16.6%{ z-index: 1; transform: scale(.84); }
123 33.3%{ z-index: 2; transform: scale(.92); }
124 50% { z-index: 3; transform: scale(1.02); }
125 66.6%{ z-index: 3; transform: scale(1.00); }
126 83.3%{ z-index: 2; transform: scale(.90); }
127 100% { z-index: 1; transform: scale(.82); }
128 }
129
130 /* subtle soft bloom in center like the reference */
131 .scene::before{
132 content:"";
133 position:absolute;
134 inset:-10%;
135 background:
136 radial-gradient(circle at 50% 60%, rgba(255,255,255,.95) 0 18%, rgba(255,255,255,.55) 28%, rgba(255,255,255,0) 52%);
137 pointer-events:none;
138 }
139</style>
140</head>
141<body>
142 <div class="scene">
143 <div class="orbit">
144 <div class="ball-wrap" style="left:50%;top:50%;">
145 <div class="ball b1"></div>
146 </div>
147 <div class="ball-wrap" style="left:50%;top:50%;">
148 <div class="ball b2"></div>
149 </div>
150 <div class="ball-wrap" style="left:50%;top:50%;">
151 <div class="ball b3"></div>
152 </div>
153 </div>
154 </div>
155</body>
156</html>