← Fractal Explorer results

Fractal Explorer

GPT 5.6 Luna Pro · typescript

Initial view of Fractal Explorer

Reviews & generation details

Reviews

No human review yet. Unreviewed does not mean unsuccessful.

Generation context

Imported historical artifact. Its exact original instructions and lineage are not known.

Generation prompt · exact text unavailable

See the current prompt for reference. It may differ from the instructions used to generate this artifact.

Inspect original source 20,087 bytes · SHA-256 66b77517c3be
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fractal Atlas — Mandelbrot &amp; Julia Explorer</title>
<style>
/* ── css: main ── */
*{box-sizing:border-box}html,body,#app{margin:0;width:100%;height:100%;overflow:hidden;background:#05070b;color:#f5f2e9;font-family:Inter,ui-sans-serif,system-ui,-apple-system,Segoe UI,sans-serif}#shell{position:relative;width:100%;height:100%;background:#05070b}canvas{display:block;width:100%;height:100%;cursor:crosshair;image-rendering:auto}.glass{background:linear-gradient(135deg,rgba(19,25,35,.82),rgba(10,13,20,.64));border:1px solid rgba(255,255,255,.13);box-shadow:0 18px 70px #0008, inset 0 1px #fff1;backdrop-filter:blur(18px);border-radius:16px}.glass#hud{position:absolute;left:24px;top:22px;width:min(720px,calc(100% - 48px));padding:18px 20px 15px;transition:opacity .5s;z-index:3}.brand{display:flex;align-items:end;gap:15px}.eyebrow{font-size:10px;letter-spacing:.25em;color:#9cabc1}.brand h1{font-size:19px;letter-spacing:.16em;margin:0;font-weight:600}.metrics{display:flex;gap:25px;margin:18px 0 14px}.metrics div{display:flex;flex-direction:column;gap:4px}.metrics span,label{font-size:9px;letter-spacing:.16em;color:#93a1b5}.metrics strong{font-size:14px;font-weight:500;color:#fff}.toolbar,.controls{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.toolbar{border-top:1px solid #fff1;padding-top:13px}button,select{font:inherit;color:#e7e8e5;background:#ffffff0a;border:1px solid #fff2;border-radius:7px;padding:7px 10px;font-size:10px;letter-spacing:.08em;cursor:pointer}button:hover,select:hover{background:#fff1;border-color:#fff5}button:focus-visible,select:focus-visible,input:focus-visible{outline:2px solid #c9edda;outline-offset:2px}kbd{font-size:9px;border:1px solid #fff4;border-radius:3px;padding:1px 4px;color:#bbc7d8}.controls{margin-top:14px;gap:15px}.controls label{display:flex;align-items:center;gap:7px}input[type=range]{accent-color:#c8e7d2;width:100px}.palettes{display:flex;gap:5px;margin-left:auto}.swatch{width:25px;height:20px;padding:0;border-radius:5px}.swatch.active{outline:2px solid #fff;outline-offset:2px}.swatch[data-palette=fire]{background:linear-gradient(90deg,#150b2c,#ef3b24,#ffd166)}.swatch.ocean{background:linear-gradient(90deg,#031b33,#1f9cae,#e4ffe5)}.swatch.mono{background:linear-gradient(90deg,#030405,#8793a8,#fff)}.swatch.acid{background:linear-gradient(90deg,#ff166b,#6dff45,#5e4bff)}.hint{color:#78869b;font-size:10px;letter-spacing:.05em;margin:13px 0 0}.hint kbd{color:#c3d1dd}#selection{position:absolute;display:none;border:1px solid #fff;box-shadow:0 0 0 1px #000,inset 0 0 20px #fff2;pointer-events:none;z-index:4}#reticle{position:absolute;display:none;width:22px;height:22px;border:1px solid #d8ffe7;border-radius:50%;transform:translate(-50%,-50%);pointer-events:none;z-index:4;box-shadow:0 0 15px #aaffd488}#reticle:before,#reticle:after{content:'';position:absolute;background:#d8ffe7}.reticle:before{}#reticle:before{width:34px;height:1px;left:-7px;top:10px}#reticle:after{height:34px;width:1px;left:10px;top:-7px}#toast{position:absolute;bottom:28px;left:50%;transform:translateX(-50%);padding:9px 14px;border-radius:20px;background:#111923dd;color:#dceee6;font-size:11px;opacity:0;transition:opacity .3s;pointer-events:none;z-index:6}#toast.show{opacity:1}#bookmarks{position:absolute;right:24px;top:22px;width:260px;padding:15px;display:none;z-index:5}.aside-title{font-size:10px;letter-spacing:.18em;color:#aebacc;border-bottom:1px solid #fff2;padding-bottom:10px}.aside-title button{float:right;padding:0 5px;border:0}.bookmark-row{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid #fff1;padding:10px 0;font-size:11px}.bookmark-row button{font-size:9px;padding:4px 7px}@media(max-width:650px){#hud{left:10px!important;top:10px!important;width:calc(100% - 20px)!important;padding:13px!important}.metrics{gap:12px;margin:13px 0}.metrics strong{font-size:11px}.hint{display:none}.controls{gap:9px}.palettes{margin-left:0}}
/* ── css: animations ── */
@keyframes pulse{0%,100%{opacity:.5}50%{opacity:1}}
</style>
</head>
<body>
<main id="shell"><canvas id="fractalCanvas" aria-label="Interactive fractal canvas"></canvas><div id="hud" class="glass"><div class="brand"><span class="eyebrow">FRACTAL ATLAS</span><h1 id="modeTitle">MANDELBROT</h1></div><div class="metrics"><div><span>MAGNIFICATION</span><strong id="mag">×1</strong></div><div><span>CENTER</span><strong id="center">−0.5000 + 0.0000i</strong></div><div><span>ITERATIONS</span><strong id="iterReadout">420</strong></div><div><span>FPS</span><strong id="fps">—</strong></div></div><div class="toolbar"><button id="backBtn" title="Back (Alt+Left)">← BACK</button><button id="resetBtn">RESET</button><button id="juliaBtn">OPEN JULIA <kbd>J</kbd></button><button id="saveBtn">BOOKMARK +</button><select id="bookmarkSelect" aria-label="Saved bookmarks"><option value="">Bookmarks…</option></select></div><div class="controls"><label>ITERATIONS <input id="iterSlider" type="range" min="120" max="1800" value="420" step="10"><output id="iterOut">420</output></label><label>COLOR DRIFT <input id="driftSlider" type="range" min="0" max="1" value="0" step="0.001"></label><div class="palettes" role="group" aria-label="Palettes"><button class="swatch active" data-palette="fire" title="Fire"></button><button class="swatch ocean" data-palette="ocean" title="Ocean"></button><button class="swatch mono" data-palette="mono" title="Monochrome"></button><button class="swatch acid" data-palette="acid" title="Psychedelic"></button></div></div><p class="hint">DRAG to zoom · SHIFT+DRAG to pan · WHEEL to zoom · ARROWS to pan · <kbd>J</kbd> Julia preview</p></div><div id="selection"></div><div id="reticle"></div><div id="toast" role="status"></div><aside id="bookmarks" class="glass"><div class="aside-title">SAVED VIEWS <button id="closeBookmarks">×</button></div><div id="bookmarkList"></div></aside></main>
<script>
(function () {
'use strict';
var __mods = {};
var __cache = {};
var __map = {};
function __require(id) {
  if (__cache[id]) return __cache[id].exports;
  var module = __cache[id] = { exports: {} };
  var factory = __mods[id];
  if (!factory) throw new Error("Module not found: " + id);
  factory(module.exports, function (spec) {
    var target = (__map[id] && __map[id][spec]) || spec;
    return __require(target);
  }, module);
  return module.exports;
}

// ── module: src/main.ts ──
__mods["src/main.ts"] = function (exports, require, module) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CFG = { baseIter: 420, iterScale: 42, maxIter: 1800, maxMag: 1e13, zoomSpeed: 1.16, chunkRows: 18, coarse: 4 };
const palettes = {
    fire: [[12, 7, 35], [64, 20, 102], [210, 45, 54], [255, 140, 40], [255, 238, 156]],
    ocean: [[2, 10, 30], [4, 61, 100], [18, 153, 164], [134, 235, 198], [238, 255, 226]],
    mono: [[0, 0, 0], [29, 37, 51], [111, 126, 151], [220, 226, 231], [255, 255, 255]],
    acid: [[28, 2, 31], [255, 20, 105], [110, 255, 57], [45, 225, 255], [107, 44, 255]]
};
const canvas = document.querySelector('#fractalCanvas'), ctx = canvas.getContext('2d', { alpha: false });
const hud = document.querySelector('#hud'), selection = document.querySelector('#selection'), reticle = document.querySelector('#reticle');
const magEl = document.querySelector('#mag'), centerEl = document.querySelector('#center'), iterEl = document.querySelector('#iterReadout'), fpsEl = document.querySelector('#fps'), toast = document.querySelector('#toast');
let view = { re: -.5, im: 0, sx: 3.5 / innerWidth, sy: 3.5 / innerWidth, type: 'mandelbrot', juliaRe: 0, juliaIm: 0 };
let history = [];
let iterations = CFG.baseIter, manualIterations = false, palette = 'fire', drift = 0, generation = 0, raf = 0, renderStart = 0, frames = 0;
let bitmap, pixels, W = 0, H = 0;
let drag = false, pan = false, startX = 0, startY = 0, lastX = 0, lastY = 0, hoverX = 0, hoverY = 0;
const clone = (v) => ({ ...v });
const clamp = (n, a, b) => Math.max(a, Math.min(b, n));
function resize() { const d = devicePixelRatio || 1; W = Math.max(1, Math.floor(innerWidth * d)); H = Math.max(1, Math.floor(innerHeight * d)); canvas.width = W; canvas.height = H; canvas.style.width = innerWidth + 'px'; canvas.style.height = innerHeight + 'px'; bitmap = ctx.createImageData(W, H); pixels = bitmap.data; render(); }
function maxIterations() { return clamp(Math.round(CFG.baseIter + Math.log10(CFG.maxMag / (view.sx * innerWidth)) * CFG.iterScale), 120, CFG.maxIter); }
function map(x, y) { return { re: view.re + (x - innerWidth / 2) * view.sx, im: view.im + (y - innerHeight / 2) * view.sy }; }
function escape(re, im) {
    let zr = view.type === 'julia' ? re : 0, zi = view.type === 'julia' ? im : 0, cr = view.type === 'julia' ? view.juliaRe : re, ci = view.type === 'julia' ? view.juliaIm : im;
    const cap = iterations;
    let n = 0, zr2 = 0, zi2 = 0;
    for (; n < cap; n++) {
        zi2 = zi * zi;
        zr2 = zr * zr;
        if (zr2 + zi2 > 256)
            break;
        zi = 2 * zr * zi + ci;
        zr = zr2 - zi2 + cr;
    }
    if (n >= cap)
        return cap;
    const mag = Math.sqrt(zr * zr + zi * zi);
    return n + 1 - Math.log2(Math.log2(mag));
}
function color(t, out, p) {
    if (t >= iterations) {
        out[p] = 0;
        out[p + 1] = 0;
        out[p + 2] = 0;
        out[p + 3] = 255;
        return;
    }
    const stops = palettes[palette], q = ((t * .032 + drift) * stops.length) % stops.length, i = Math.floor(q), f = q - i, a = stops[i % stops.length], b = stops[(i + 1) % stops.length];
    out[p] = a[0] + (b[0] - a[0]) * f;
    out[p + 1] = a[1] + (b[1] - a[1]) * f;
    out[p + 2] = a[2] + (b[2] - a[2]) * f;
    out[p + 3] = 255;
}
function render() {
    generation++;
    const g = generation;
    cancelAnimationFrame(raf);
    if (!pixels || !bitmap)
        return;
    pixels.fill(0);
    renderStart = performance.now();
    const step = CFG.coarse;
    let y = 0;
    const coarse = () => { if (g !== generation)
        return; frames++; let end = Math.min(H, y + CFG.chunkRows * step); for (let py = y; py < H && py < end; py += step)
        for (let px = 0; px < W; px += step) {
            const z = map(px / (devicePixelRatio || 1), py / (devicePixelRatio || 1)), t = escape(z.re, z.im), p = (py * W + px) * 4;
            color(t, pixels, p);
            for (let yy = 0; yy < step && py + yy < H; yy++)
                for (let xx = 0; xx < step && px + xx < W; xx++) {
                    const k = ((py + yy) * W + px + xx) * 4;
                    pixels[k] = pixels[p];
                    pixels[k + 1] = pixels[p + 1];
                    pixels[k + 2] = pixels[p + 2];
                    pixels[k + 3] = 255;
                }
        } y = end; ctx.putImageData(bitmap, 0, 0); if (y < H)
        raf = requestAnimationFrame(coarse);
    else {
        y = 0;
        raf = requestAnimationFrame(full);
    } };
    const full = () => { if (g !== generation)
        return; frames++; let end = Math.min(H, y + CFG.chunkRows); for (let py = y; py < end; py++)
        for (let px = 0; px < W; px++) {
            const z = map(px / (devicePixelRatio || 1), py / (devicePixelRatio || 1)), p = (py * W + px) * 4;
            color(escape(z.re, z.im), pixels, p);
        } y = end; ctx.putImageData(bitmap, 0, 0); if (y < H)
        raf = requestAnimationFrame(full);
    else
        updateHUD(); };
    raf = requestAnimationFrame(coarse);
    updateHUD();
}
function updateHUD() { magEl.textContent = '×' + (3.5 / view.sx / innerWidth).toExponential(2); centerEl.textContent = `${view.re.toPrecision(7)} ${view.im < 0 ? '−' : '+'} ${Math.abs(view.im).toPrecision(7)}i`; iterEl.textContent = String(iterations); (document.querySelector('#modeTitle')).textContent = view.type.toUpperCase(); fpsEl.textContent = frames ? String(Math.round(frames / ((performance.now() - renderStart) / 1000))) : '—'; frames = 0; }
function notice(s) { toast.textContent = s; toast.classList.add('show'); setTimeout(() => toast.classList.remove('show'), 1800); }
function navigate(next, save = true) { if (Math.abs(next.sx) < 3.5 / innerWidth / CFG.maxMag) {
    notice('Precision limit reached — zoom capped');
    return;
} if (save)
    history.push(clone(view)); view = next; if (!manualIterations)
    iterations = maxIterations(); render(); }
function zoomAt(x, y, f) { const z = map(x, y); const n = clone(view); n.sx *= f; n.sy *= f; n.re = z.re + (view.re - z.re) * f; n.im = z.im + (view.im - z.im) * f; navigate(n); }
function screenPoint(e) { const r = canvas.getBoundingClientRect(); return { x: e.clientX - r.left, y: e.clientY - r.top }; }
canvas.addEventListener('pointerdown', e => { const p = screenPoint(e); drag = true; pan = e.shiftKey || e.button === 1; startX = lastX = p.x; startY = lastY = p.y; selection.style.display = pan ? 'none' : 'block'; selection.style.left = p.x + 'px'; selection.style.top = p.y + 'px'; selection.style.width = '0'; selection.style.height = '0'; canvas.setPointerCapture(e.pointerId); });
canvas.addEventListener('pointermove', e => { const p = screenPoint(e); hoverX = p.x; hoverY = p.y; if (view.type === 'mandelbrot') {
    reticle.style.display = 'block';
    reticle.style.left = p.x + 'px';
    reticle.style.top = p.y + 'px';
} if (!drag)
    return; if (pan) {
    const n = clone(view);
    n.re -= (p.x - lastX) * view.sx;
    n.im -= (p.y - lastY) * view.sy;
    lastX = p.x;
    lastY = p.y;
    navigate(n, false);
}
else {
    const x = Math.min(startX, p.x), y = Math.min(startY, p.y);
    selection.style.left = x + 'px';
    selection.style.top = y + 'px';
    selection.style.width = Math.abs(p.x - startX) + 'px';
    selection.style.height = Math.abs(p.y - startY) + 'px';
} });
canvas.addEventListener('pointerup', e => { if (!drag)
    return; drag = false; selection.style.display = 'none'; if (pan)
    return; const p = screenPoint(e), rw = Math.abs(p.x - startX), rh = Math.abs(p.y - startY); if (rw < 8 || rh < 8) {
    const z = map(p.x, p.y);
    navigate({ ...view, re: z.re, im: z.im, type: view.type === 'julia' ? 'julia' : 'mandelbrot' });
    return;
} const n = clone(view); n.re = view.re + (Math.min(startX, p.x) + rw / 2 - innerWidth / 2) * view.sx; n.im = view.im + (Math.min(startY, p.y) + rh / 2 - innerHeight / 2) * view.sy; n.sx = view.sx * rw / innerWidth; n.sy = view.sy * rh / innerHeight; navigate(n); });
canvas.addEventListener('wheel', e => { e.preventDefault(); zoomAt(screenPoint(e).x, screenPoint(e).y, Math.pow(CFG.zoomSpeed, e.deltaY > 0 ? 1 : -1)); }, { passive: false });
function openJulia() { const z = map(hoverX || innerWidth / 2, hoverY || innerHeight / 2); history.push(clone(view)); view = { re: 0, im: 0, sx: 3.5 / innerWidth, sy: 3.5 / innerWidth, type: 'julia', juliaRe: z.re, juliaIm: z.im }; reticle.style.display = 'none'; notice(`Julia c = ${z.re.toFixed(5)} ${z.im < 0 ? '−' : '+'} ${Math.abs(z.im).toFixed(5)}i`); render(); }
window.addEventListener('keydown', e => { if ((e.key === 'j' || e.key === 'J') && view.type === 'mandelbrot')
    openJulia(); if (e.key === 'Escape' && view.type === 'julia') {
    const old = history.pop();
    if (old) {
        view = old;
        render();
    }
} if (e.key === '+' || e.key === '=')
    zoomAt(innerWidth / 2, innerHeight / 2, .8); if (e.key === '-' || e.key === '_')
    zoomAt(innerWidth / 2, innerHeight / 2, 1.25); const step = innerWidth * .08; if (['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'].includes(e.key)) {
    e.preventDefault();
    const n = clone(view);
    if (e.key === 'ArrowUp')
        n.im -= view.sy * step;
    if (e.key === 'ArrowDown')
        n.im += view.sy * step;
    if (e.key === 'ArrowLeft')
        n.re -= view.sx * step;
    if (e.key === 'ArrowRight')
        n.re += view.sx * step;
    navigate(n, false);
} });
(document.querySelector('#backBtn')).addEventListener('click', () => { const old = history.pop(); if (old) {
    view = old;
    render();
}
else
    notice('No earlier view'); });
(document.querySelector('#resetBtn')).addEventListener('click', () => { history = []; view = { re: -.5, im: 0, sx: 3.5 / innerWidth, sy: 3.5 / innerWidth, type: 'mandelbrot', juliaRe: 0, juliaIm: 0 }; render(); });
(document.querySelector('#juliaBtn')).addEventListener('click', openJulia);
document.querySelector('#iterSlider').addEventListener('input', e => { manualIterations = true; iterations = +e.target.value; (document.querySelector('#iterOut')).textContent = String(iterations); render(); });
document.querySelector('#driftSlider').addEventListener('input', e => { drift = +e.target.value; render(); });
document.querySelectorAll('.swatch').forEach(b => b.addEventListener('click', () => { palette = b.getAttribute('data-palette') || 'fire'; document.querySelectorAll('.swatch').forEach(x => x.classList.remove('active')); b.classList.add('active'); render(); }));
function getMarks() { try {
    return JSON.parse(localStorage.getItem('fractalMarks') || '[]');
}
catch {
    return [];
} }
function drawMarks() { const list = document.querySelector('#bookmarkList'), sel = document.querySelector('#bookmarkSelect'); list.innerHTML = ''; sel.innerHTML = '<option value="">Bookmarks…</option>'; getMarks().forEach((m, i) => { const row = document.createElement('div'); row.className = 'bookmark-row'; row.innerHTML = `<span>${m.name}</span><button data-i="${i}">OPEN</button>`; list.append(row); const o = document.createElement('option'); o.value = String(i); o.textContent = m.name; sel.append(o); }); list.querySelectorAll('button').forEach(b => b.addEventListener('click', () => loadMark(+(b.getAttribute('data-i') || 0)))); }
function loadMark(i) { const m = getMarks()[i]; if (!m)
    return; view = clone(m.view); palette = m.palette; drift = m.drift; iterations = m.iterations; document.querySelector('#iterSlider').value = String(iterations); drawMarks(); render(); notice('Bookmark restored'); }
(document.querySelector('#saveBtn')).addEventListener('click', () => { const a = getMarks(); a.push({ name: 'View ' + new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }), view: clone(view), palette, iterations, drift }); localStorage.setItem('fractalMarks', JSON.stringify(a)); drawMarks(); notice('View bookmarked'); });
(document.querySelector('#bookmarkSelect')).addEventListener('change', e => loadMark(+e.target.value));
drawMarks();
(document.querySelector('#closeBookmarks')).addEventListener('click', () => { document.querySelector('#bookmarks').style.display = 'none'; });
hud.addEventListener('dblclick', () => { document.querySelector('#bookmarks').style.display = 'block'; });
window.fractal = { iterationsAt: (re, im) => { const old = view; view = { ...view, type: 'mandelbrot' }; const r = escape(re, im); view = old; return r; }, setView: (v) => { view = { ...view, ...v }; render(); }, getView: () => clone(view), saveBookmark: () => localStorage.setItem('fractalTestView', JSON.stringify({ view, palette, iterations, drift })), restoreBookmark: () => { const x = JSON.parse(localStorage.getItem('fractalTestView') || 'null'); if (x) {
        view = x.view;
        palette = x.palette;
        iterations = x.iterations;
        drift = x.drift;
        render();
    } }, selectZoom: (x, y, w, h) => { const n = clone(view); n.re = view.re + (x + w / 2 - innerWidth / 2) * view.sx; n.im = view.im + (y + h / 2 - innerHeight / 2) * view.sy; n.sx = view.sx * w / innerWidth; n.sy = view.sy * h / innerHeight; navigate(n); return clone(view); } };
window.addEventListener('resize', resize);
resize();
};

// ── entry ──
__require("src/main.ts");
})();
</script>
</body>
</html>
<!-- agent-meta {"model":"openai/gpt-5.6-luna-pro","provider":"openrouter","persona":"typescript","sessionId":"4fe257a5-a9e7-4962-acdd-e5971dc55d06","tokensIn":778509,"tokensOut":28526,"tokensTotal":807035,"turns":18,"toolCalls":26,"failedToolCalls":1,"timestamp":"2026-07-31T02:41:20.537Z"} -->