animation2code benchmark
For best compatibility, please view this dashboard in a Chrome browser.
← back to Star Burst

model output

Gemini 3 Flash Preview

Star Burst

A 0.37T 0.17
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.0">
6    <title>Light Rays Animation</title>
7    <style>
8        body, html {
9            margin: 0;
10            padding: 0;
11            width: 100%;
12            height: 100%;
13            overflow: hidden;
14            background-color: #050a10;
15        }
16
17        canvas {
18            display: block;
19        }
20
21        /* Subtle vignette to match the video background */
22        .vignette {
23            position: fixed;
24            top: 0;
25            left: 0;
26            width: 100%;
27            height: 100%;
28            background: radial-gradient(circle, transparent 20%, rgba(0, 0, 0, 0.4) 100%);
29            pointer-events: none;
30            z-index: 10;
31        }
32    </style>
33</head>
34<body>
35    <div class="vignette"></div>
36    <canvas id="canvas"></canvas>
37
38    <script>
39        const canvas = document.getElementById('canvas');
40        const ctx = canvas.getContext('2d');
41
42        let width, height, centerX, centerY;
43        const particleCount = 150;
44        const particles = [];
45        const colors = [
46            '#ffffff', // White
47            '#00f2ff', // Bright Cyan
48            '#00d2ff', // Light Blue
49            '#3a7bd5', // Blue
50            '#ffffff'
51        ];
52
53        // Particle configuration
54        const speed = 15;
55        const focalLength = 400;
56
57        function init() {
58            resize();
59            for (let i = 0; i < particleCount; i++) {
60                particles.push(new Particle());
61            }
62            animate();
63        }
64
65        function resize() {
66            width = canvas.width = window.innerWidth;
67            height = canvas.height = window.innerHeight;
68            centerX = width / 2;
69            centerY = height / 2;
70        }
71
72        window.addEventListener('resize', resize);
73
74        class Particle {
75            constructor() {
76                this.reset();
77                // Randomize start Z so they don't all appear at once
78                this.z = Math.random() * focalLength * 2;
79            }
80
81            reset() {
82                // Spread particles in a 3D sphere/cone space
83                this.x = (Math.random() - 0.5) * 2000;
84                this.y = (Math.random() - 0.5) * 2000;
85                this.z = focalLength * 2;
86                
87                this.color = colors[Math.floor(Math.random() * colors.length)];
88                this.lineWidth = Math.random() * 2 + 1;
89                
90                // Track previous Z for the "streak" effect
91                this.prevZ = this.z;
92            }
93
94            update() {
95                this.prevZ = this.z;
96                this.z -= speed;
97
98                // Reset when particle passes "behind" the camera or gets too close
99                if (this.z <= 1) {
100                    this.reset();
101                }
102            }
103
104            draw() {
105                // Project 3D coordinates to 2D
106                const scale = focalLength / this.z;
107                const x2d = centerX + this.x * scale;
108                const y2d = centerY + this.y * scale;
109
110                const prevScale = focalLength / this.prevZ;
111                const prevX2d = centerX + this.x * prevScale;
112                const prevY2d = centerY + this.y * prevScale;
113
114                // Fade in as they move closer to prevent sudden pops
115                const opacity = Math.min(1, (focalLength * 2 - this.z) / 200);
116
117                ctx.beginPath();
118                ctx.strokeStyle = this.color;
119                ctx.globalAlpha = opacity;
120                ctx.lineWidth = this.lineWidth * scale * 0.5;
121                ctx.lineCap = 'round';
122                
123                ctx.moveTo(prevX2d, prevY2d);
124                ctx.lineTo(x2d, y2d);
125                ctx.stroke();
126            }
127        }
128
129        function drawCentralGlow() {
130            ctx.save();
131            ctx.globalCompositeOperation = 'lighter';
132            
133            // Core white glow
134            const grad1 = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, 15);
135            grad1.addColorStop(0, 'rgba(255, 255, 255, 0.8)');
136            grad1.addColorStop(1, 'rgba(0, 242, 255, 0)');
137            ctx.fillStyle = grad1;
138            ctx.beginPath();
139            ctx.arc(centerX, centerY, 15, 0, Math.PI * 2);
140            ctx.fill();
141
142            // Large cyan soft glow
143            const grad2 = ctx.createRadialGradient(centerX, centerY, 0, centerX, centerY, 60);
144            grad2.addColorStop(0, 'rgba(0, 242, 255, 0.3)');
145            grad2.addColorStop(1, 'rgba(0, 242, 255, 0)');
146            ctx.fillStyle = grad2;
147            ctx.beginPath();
148            ctx.arc(centerX, centerY, 60, 0, Math.PI * 2);
149            ctx.fill();
150            
151            ctx.restore();
152        }
153
154        function animate() {
155            // Clear screen with a slight fade to create motion blur trails
156            ctx.fillStyle = 'rgba(5, 10, 16, 0.4)';
157            ctx.fillRect(0, 0, width, height);
158
159            // Additive blending for the "glow" look of the streaks
160            ctx.globalCompositeOperation = 'lighter';
161
162            particles.forEach(p => {
163                p.update();
164                p.draw();
165            });
166
167            // Reset blending and draw the core center glow
168            ctx.globalAlpha = 1;
169            drawCentralGlow();
170
171            requestAnimationFrame(animate);
172        }
173
174        init();
175    </script>
176</body>
177</html>