Synthwave sunset · grok-4.20
Create an animated synthwave sunset: a glowing gradient sun with scanlines setting over an infinite neon grid that scrolls toward the viewer, with a starfield and a reflected horizon.
transcript · 4 messages
Create an animated synthwave sunset: a glowing gradient sun with scanlines setting over an infinite neon grid that scrolls toward the viewer, with a starfield and a reflected horizon.
thinking
The task is: "Create an animated synthwave sunset: a glowing gradient sun with scanlines setting over an infinite neon grid that scrolls toward the viewer, with a starfield and a reflected horizon."
...The task is to create an animated synthwave sunset in a single HTML file with inline CSS and JS. It needs to be self-contained, no external resources.
Key elements:
- Glowing gradient sun with scanlines, setting over an infinite neon grid that scrolls toward the viewer.
- Starfield
- Reflected horizon (probably a reflection of the horizon/grid/sun below)
Synthwave: neon colors - pink, cyan, purple, magenta. Retro 80s vibe.
I'll use HTML5 Canvas for this.
Plan:
- Full-screen canvas.
- Dark background with gradient from deep blue/purple at top to black at bottom.
- 2D starfield: random stars twinkling.
- Sun: large circle at bottom, with gradient radial, glow with multiple layers, positioned setting (moving down), with horizontal scanlines overlay.
- Infinite grid: perspective grid lines in neon colors, moving towards viewer (scrolling in z).
- Reflected horizon: 180 degree flip or mirror of horizon elements below the horizon line.
- Scanlines: VHS effect, horizontal lines across the screen with some movement or static.
- Maybe some glow effects.
For the grid:
Use a loop to draw lines converging to horizon point.
For scrolling: animate the position of the grid lines moving up (as viewer moves forward, lines move down relative).
Standard infinite scrolling grid in canvas:
- Horizon at y = h
- Vanishing point at x = w/2, y = h
- Draw vertical lines: for each x offset, draw line from (x, h) to (x, bottom) -- but for perspective, actually the verticals are parallel, but to converge, wait.
For grid on ground:
- Horizontal lines (parallel to viewer direction? Wait.
Let's clarify:
Assume viewer looking down the z-axis, ground at z increasing away.
- Lines parallel to z (depth lines): converge to vanishing point 0.
- Lines parallel to x (transverse): are horizontal on screen, spaced by perspective.
So:
- Draw transverse lines: horizontal segments at y positions calculated by perspective, spanning x left to right based on y.
- Draw depth lines: from vanishing point down to bottom, at x positions spaced by perspective.
For depth lines, they are slanted lines from horizon to bottom left/right.
To animate scroll: shift the z offset for the transverse lines.
Yes.
For reflection: perhaps draw the same grid but flipped y below horizon, with lower opacity, and reflect the sun too.
Sun setting: sun starts high, moves down 1/2 way over time.
But for simplicity, sun fixed position, or slow move.
Let's code it.
I need to write the code.
Since complex, I'll use the tool to create and test.
First, create basic template.
Use tool to write index.html with skeleton.
But to save steps, I'll compose the full code in reasoning then write it.
Let me sketch JS code.
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
function resizeCanvas() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
resizeCanvas();
window .addEventListener('resize', resizeCanvas);
let time = 0;
const stars = [];
for (let i = 0; i < 500; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math .random() * 2,
twinkleSpeed: Math.random() * 0.02 + 0.01
});
}
function drawBackground() {
// Sky gradient
let grad = ctx.createLinearGradient(0,0,0,canvas.height/2);
grad.addColorStop 0, '#0b0b2b');
grad.addColorStop(1, '#1a0d3d');
ctx.fillStyle = grad;
ctx.fillRect(0,0,canvas.width,canvas.height/2);
// Ground
grad = ctx.createLinearGradient(0, canvas.height/2,0,canvas.height);
grad.addColorStop(0, '#0f0a1f');
grad.addColorStop(1, '#000');
ctx.fillStyle = grad;
ctx.fillRect(0,canvas.height/2,canvas.width,canvas.height/2);
// Horizon line
ctx.strokeStyle = '#ff00ff';
ctx.lineWidth = 2;
ctx.shadowBlur = 20;
ctx.shadowColor = '#ff00ff';
ctx.beginPath();
ctx.moveTo(0, canvas.height/2);
ctx.lineTo(canvas.width, canvas.height/2);
ctx.stroke();
}
function drawStars() {
for (let star of stars) {
let brightness = Math.sin(time * star.twinkleSpeed) * 0.5 + 0.5;
ctx.fillStyle = `rgba(255,255,255,${0 .5 + brightness * 0.5})`;
ctx.fillRect(star.x, star.y, star.size, star.size);
}
}
function drawSun() {
let sunY = canvas.height * 0.6 - time * 0.2; // slow descent
let sunX = canvas.width / 2;
let radius = 100;
// Glow
ctx.shadowBlur = 50;
ctx.shadowColor = '#ff00ff';
ctx.fillStyle = 'rgba(255,0,255,0.3)';
ctx.beginPath();
ctx.arc(s unX, sunY, radius * 1.5, 0, Math.PI*2);
ctx.fill();
// Sun body
let grad = ctx.createRadialGradient(sunX, sunY, 0, sunX, sunY, radius);
grad.addColorStop(0, '#ffff00');
grad.addColorStop(0.5, '#ffaa00');
grad.addColorStop(1, '#ff5500');
ctx.fillStyle = grad;
ctx.beginPath();
ctx.arc(sunX, sunY, radius, 0, Math.PI*2);
ctx.fill();
// Scanlines on sun
ctx.globalAlpha = 0.2;
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 1;
for(let y = sunY - radius; y < sunY + radius; y += 5) {
ctx.beginPath();
ctx.moveTo(sunX - radius, y);
ctx.lineTo(sunX + radius, y);
ctx.stroke();
}
ctx.globalAlpha = 1;
}
function drawGrid() {
let horizonY = canvas.height / 2;
let centerX = canvas.width / 2 ;
let speed = 0.5;
let numLines = 50;
ctx.shadowBlur = 10;
ctx.shadowColor = '#00ffff';
ctx.strokeStyle = '#00ffff';
ctx.lineWidth = 1.5;
for(let i = 1; i < 100; i++) {
let z = i * 20 - (time * speed % 20);
if(z < 0) continue;
let scale = 300 / z; // perspective scale
let y = horizonY + scale * 50; // height offset
let width = 400 * scale; // width at that depth
let leftX = centerX - width / 2;
let rightX = centerX + width / 2;
if(y > canvas.height) continue;
ctx.beginPath();
ctx.moveTo(leftX, y);
ctx.lineTo(right X, y);
ctx.stroke();
}
// Vertical lines
ctx.strokeStyle = '#ff00ff';
ctx.index.html (15746 bytes)Successfully wrote 15746 bytes to index.html
thinking
The task is complete. I've created a self-contained index.html file with an animated synthwave sunset featuring:
The single-file web app has been created as **index.html**. Open it in a browser to experience the full animated synthwave sunset (glowing sun, scrolling neon grid, twinkling starfield, reflective horizon, CRT scanlines, and retro VHS effects). Click or press any key to temporarily boost the grid speed. Press **P** to pause/resume. (Everything runs 100% offline in one self-contained HTML file with no external dependencies.)
TAKE IT TO CODE
A single self-contained HTML file — copy it and open in any browser, or reuse the prompt with your own pi-agent run.
RUN
EVALUATION
Glowing sun with scanlines over neon grid, starfield, and reflection; animates continuously but shows little input reactivity.
Vision grade · anthropic/claude-sonnet-5
MEASUREMENTS
Raw readings from the capture, not a verdict — the grade above is the only judgement. Percentages are how much of the screen changed; the measure under-reports sparse motion on a dark background.