oneshotlm
Compare all models on this prompt →

Mandelbrot explorer · gemini-3.1-flash-lite

Render the Mandelbrot set with a smooth color gradient on a full-screen canvas, with click-and-drag to pan and mouse-wheel to zoom.

⛨ sandboxed Open in new tab ↗
transcript · 4 messages
user

Render the Mandelbrot set with a smooth color gradient on a full-screen canvas, with click-and-drag to pan and mouse-wheel to zoom.

assistant
thinking
**Developing the Mandelbrot App**

I'm making good progress on the single-page web app. The basic HTML structure and full-screen canvas are set. Next, I'm focusing on implementing a smooth color gradient to make the fractal visually appealing. Once I get the colors right, I'll integrate click-and-drag panning and mouse-wheel zoom for interactivity.


**Defining the Coordinate System**

I've got the basic HTML structure set, and the canvas is ready to go. I'm deep diving into defining the coordinate system, mapping pixel coordinates to the complex plane. I am getting the `draw()` function ready, to translate the user input into visible output, handling the `zoom` and `center` variables for interactive manipulation. The next step is fleshing out the pixel mapping logic.


write index.html (4205 bytes)
toolResult

Successfully wrote 4205 bytes to index.html

assistant

The Mandelbrot set renderer has been created as `index.html`. You can open this file in any web browser to interact with it. ### Features * **Smooth Coloring:** Uses a fractional iteration count to create a continuous gradient rather than stepped bands. * **Controls:** * **Click & Drag:** Pan across the fractal coordinate space. * **Mouse Wheel:** Zoom in and out. * **Adaptive Performance:** Automatically increases the calculation depth (`maxIter`) as you zoom deeper to maintain detail. ```html <!-- index.html --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mandelbrot Explorer</title> <style> body, html { margin: 0; padding: 0; overflow: hidden; background: #000; } canvas { display: block; cursor: crosshair; } </style> </head> <body> <canvas id="canvas"></canvas> <script> const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); let width, height; let centerX = -0.5, centerY = 0; let zoom = 200; let maxIter = 100; function resize() { width = canvas.width = window.innerWidth; height = canvas.height = window.innerHeight; draw(); } window.addEventListener('resize', resize); resize(); function mandelbrot(cx, cy) { let x = 0, y = 0; let iter = 0; while (x * x + y * y <= 4 && iter < maxIter) { let xTemp = x * x - y * y + cx; y = 2 * x * y + cy; x = xTemp; iter++; } if (iter === maxIter) return -1; // Fractional iteration for smooth coloring return iter + 1 - Math.log(Math.log(x * x + y * y) / 2) / Math.log(2); } function draw() { const imageData = ctx.createImageData(width, height); const data = imageData.data; for (let py = 0; py < height; py++) { for (let px = 0; px < width; px++) { const cx = centerX + (px - width / 2) / zoom; const cy = centerY + (py - height / 2) / zoom; const m = mandelbrot(cx, cy); const idx = (py * width + px) * 4; if (m === -1) { data[idx] = data[idx + 1] = data[idx + 2] = 0; } else { const hue = (m * 10) % 360; const rgb = hslToRgb(hue / 360, 0.8, 0.5); data[idx] = rgb[0]; data[idx + 1] = rgb[1]; data[idx + 2] = rgb[2]; } data[idx + 3] = 255; } } ctx.putImageData(imageData, 0, 0); } function hslToRgb(h, s, l) { let r, g, b; if (s === 0) r = g = b = l; else { const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1/3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1/3); } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; } function hue2rgb(p, q, t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1/6) return p + (q - p) * 6 * t; if (t < 1/2) return q; if (t < 2/3) return p + (q - p) * (2/3 - t) * 6; return p; } let isDragging = false; let lastMouseX, lastMouseY; canvas.addEventListener('mousedown', e => { isDragging = true; lastMouseX = e.clientX; lastMouseY = e.clientY; }); window.addEventListener('mouseup', () => isDragging = false); canvas.addEventListener('mousemove', e => { if (!isDragging) return; centerX -= (e.clientX - lastMouseX) / zoom; centerY -= (e.clientY - lastMouseY) / zoom; lastMouseX = e.clientX; lastMouseY = e.clientY; draw(); }); canvas.addEventListener('wheel', e => { e.preventDefault(); const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1; zoom *= zoomFactor; maxIter = Math.floor(100 + Math.log10(zoom) * 50); draw(); }, { passive: false }); </script> </body> </html> ```

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

modelgemini-3.1-flash-lite
vendorGoogle
harnesspi-agent
generated2026-07-22

EVALUATION

4/5 working

Mandelbrot renders with smooth color gradient; drag pans and wheel zooms correctly; click/keys have no effect (expected).

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.

idle motion0.0%
on click0.0%
on drag72.5%
on wheel6.4%
on enter + space0.0%
on arrow keys0.0%
on w/a/s/d0.0%
frame spread39.2 / 255
console errors0
js errors none

METRICS

runtime10.5s
tokens in4.7k
tokens out3.3k
cached0
cost / run$0.0062