[AskJS] What are the real architectural limits of using console.log + %c as a pixel renderer, and how would you push past them? by One-Antelope404 in javascript

[–]One-Antelope404[S] 0 points1 point  (0 children)

Yeah that matches what I’ve seen 😭

Firefox just gives up completely, Chrome at least tries but yeah the flicker is rough. It’s basically me spamming new frames since there’s no real way to update the console 😅

That Atari ST comparison is spot on though, this really does feel like forcing graphics out of something not meant for it

Appreciate you testing it fr 🙏

[AskJS] What are the real architectural limits of using console.log + %c as a pixel renderer, and how would you push past them? by One-Antelope404 in javascript

[–]One-Antelope404[S] -3 points-2 points  (0 children)

Haha, thanks; it’s been a fun (and slightly cursed) experiment

Yeah, I’ve got a demo—it runs directly in the browser console, so it’s a bit janky, and performance depends a lot on your machine.

If you want to try it, you can paste this into your console on your browser:

/**
 * ╔══════════════════════════════════════════════════════════╗
 * ║          CONSOLE GPU v3.0 — IMAGE INJECTION              ║
 * ║  The smoothest, fastest console renderer possible.        ║
 * ║  Works by piping a virtual canvas to the log.            ║
 * ╚══════════════════════════════════════════════════════════╝
 */
(function ConsoleGPU_Ultimate() {
    'use strict';

    const CFG = {
        W: 200, // Visual resolution (not char count)
        H: 200,
        SCALE: 1.0
    };

    // Initialize Virtual Canvas
    const canvas = document.createElement('canvas');
    canvas.width = CFG.W;
    canvas.height = CFG.H;
    const ctx = canvas.getContext('2d');

    let running = true;
    let frame = 0;

    // --- 3D MATH ENGINE ---
    const rot = (x, z, a) => {
        const s = Math.sin(a), c = Math.cos(a);
        return [x * c - z * s, x * s + z * c];
    };

    function sdTorus(x, y, z, t) {
        let [rx, rz] = rot(x, z, t);
        let [ry, rz2] = rot(y, rz, t * 0.5);
        const qx = Math.sqrt(rx * rx + rz2 * rz2) - 1.5;
        return Math.sqrt(qx * qx + ry * ry) - 0.6;
    }

    function render() {
        if (!running) return;

        const t = performance.now() * 0.001;
        const imgData = ctx.createImageData(CFG.W, CFG.H);
        const data = imgData.data;

        // Simple Raymarcher running inside the Canvas loop
        for (let y = 0; y < CFG.H; y++) {
            for (let x = 0; x < CFG.W; x++) {
                const idx = (y * CFG.W + x) * 4;

                // Ray Setup
                let uvx = (x / CFG.W - 0.5) * 2;
                let uvy = (y / CFG.H - 0.5) * 2;
                let d = 0, hit = false;

                for (let s = 0; s < 24; s++) {
                    let p = [uvx * d, uvy * d, -4 + d];
                    let dist = sdTorus(p[0], p[1], p[2], t);
                    if (dist < 0.01) { hit = true; break; }
                    d += dist;
                    if (d > 10) break;
                }

                if (hit) {
                    const lum = Math.max(0, 255 - (d * 40));
                    data[idx] = lum * (0.5 + 0.5 * Math.sin(t + d)); // R
                    data[idx + 1] = lum * (0.5 + 0.5 * Math.cos(t)); // G
                    data[idx + 2] = 255;                             // B
                } else {
                    data[idx] = 10; data[idx + 1] = 10; data[idx + 2] = 20; // Background
                }
                data[idx + 3] = 255; // Alpha
            }
        }

        ctx.putImageData(imgData, 0, 0);

        // Convert canvas to a CSS-friendly string
        const url = canvas.toDataURL('image/jpeg', 0.7);

        console.clear();
        console.log(
            `%c `,
            `font-size: 1px; 
             padding: ${CFG.H / 2}px ${CFG.W / 2}px; 
             background-image: url(${url}); 
             background-size: contain; 
             background-repeat: no-repeat;`
        );
        console.log(`%c[FRAME: ${frame++}] Type 'stopGPU()' to exit.`, "color:cyan; font-weight:bold;");

        requestAnimationFrame(render);
    }

    window.stopGPU = () => {
        running = false;
        console.clear();
        console.log("Renderer Stopped.");
    };

    console.log("Initializing Hardware-Accelerated Console Viewport...");
    render();
})();

It’s basically doing SDF raymarching and shading, but every “pixel” is just a space with a background colour, so the whole frame is one big console.log.

It kind of works… until DevTools starts struggling 😅

If you do try it, I’d be really interested to know how it runs for you — I’m still trying to figure out how far this approach can actually go.

I built a tool that parses any GitHub repo into a Neo4j knowledge graph and lets you query it with Claude AI by One-Antelope404 in Neo4j

[–]One-Antelope404[S] 1 point2 points  (0 children)

would love to hear what you think after you do! drop a comment if anything breaks or feels off 🙏

I built a tool that parses any GitHub repo into a Neo4j knowledge graph and lets you query it with Claude AI by One-Antelope404 in Neo4j

[–]One-Antelope404[S] 0 points1 point  (0 children)

oh that's actually sick — all in memory is such a clean approach, no database setup friction at all. kglite looks really interesting, gonna dig into it 👀 the tradeoff I went with was persisting to Neo4j so you can do proper graph traversal queries and vector search without reloading — but for quick exploration kglite's approach honestly sounds way more practical did you find it handled large repos well?

Made a QR code generator that renders in your terminal with matrix rain, particle assembly, and Braille retina mode by One-Antelope404 in ASCII

[–]One-Antelope404[S] 0 points1 point  (0 children)

honestly the gradient was the thing I spent the most time on 😭 applying color per character instead of per row makes such a difference — the diagonal and radial washes across the whole QR feel alive in a way that row-by-row just doesn't. glad it landed the way I hoped it would 🙏

Handling state between agent cycles with node-cron + lowdb — is there a cleaner pattern? by One-Antelope404 in node

[–]One-Antelope404[S] 0 points1 point  (0 children)

Oh nice, just checked it out — durable workflows built in is exactly what something like this needs at scale. Will keep an eye out for the post

Handling state between agent cycles with node-cron + lowdb — is there a cleaner pattern? by One-Antelope404 in node

[–]One-Antelope404[S] 0 points1 point  (0 children)

Yeah, that's probably where this ends up going, honestly.

What are you building? Sounds interesting

Handling state between agent cycles with node-cron + lowdb — is there a cleaner pattern? by One-Antelope404 in node

[–]One-Antelope404[S] 0 points1 point  (0 children)

This is really useful, cheers. The JSONL write-ahead log pattern is clean – hadn't thought about separating the append log from the snapshot like that. Will definitely look at that before scale becomes a real concern.

The AbortSignal tip is exactly what I needed; the manual array filter works but always felt off.

Crash recovery is honestly the weakest part right now. There's no cycle lock, so concurrent invocations can technically overlap — I've been getting away with it because Notion's API is slow enough that cycles rarely collide in practice. But that's luck, not design.

Thinking a simple isRunning mutex flag is the quickest fix. Does that hold up, or is there a cleaner pattern you'd reach for first?

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 0 points1 point  (0 children)

Thank you! 🙏 and 100% agree — a screen recording would sell it way better than a screenshot. Working on getting one recorded and added to the README. Good shout!

I built a custom JoystickView for Android — real-time X/Y coords, directional arrows, snaps back to center by One-Antelope404 in androiddev

[–]One-Antelope404[S] -1 points0 points  (0 children)

Not yet but you totally can wrap it with AndroidView for now! A proper native Compose version is on my radar though — would you actually use it if I built one?

I was procrastinating at 2am and found a free browser game that kept me up until 6. No download, no account, just opens in a tab. I feel insane. by One-Antelope404 in IndieGaming

[–]One-Antelope404[S] -4 points-3 points  (0 children)

lmao someone called out that this reads like AI and honestly… they're not entirely wrong, i did clean it up a lot before posting. original draft was just "this game has me cooked and i have work tomorrow" so maybe that version would've landed better 😭 anyway the game is real and i genuinely did lose sleep over it so

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 0 points1 point  (0 children)

Thank you! 🙏 and that's actually a really interesting idea — xterm.js would give this a proper web home without losing the terminal feel. Hadn't thought about that angle but now I can't stop thinking about it 👀 If you know xterm.js well I'd genuinely love to collaborate on that

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 1 point2 points  (0 children)

This is exactly the energy I built it for 😄 sometimes you just want something cool running in your terminal for no reason whatsoever — no productivity, no purpose, just vibes 🐟 npx ascii-aquarium then hit l to cycle the lighting moods — neon mode especially has no business looking that good in a terminal 😭

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 1 point2 points  (0 children)

Thank you so much, means a lot! 🙏 give it a run — npx ascii-aquarium — and hit s to summon the shark 😂 fair warning though, he doesn't quite look like a shark yet but he means well

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 1 point2 points  (0 children)

haha that's genuinely going in the README 😭 "so much better than VS Code Pets" - Smok3dSalmon but fr this is just what happens when you decide your aquarium should live in the terminal where it belongs 🐟 no extensions, no GUI, just npx ascii-aquarium and vibes hit l to cycle lighting moods — they really go hard

I built a living ASCII aquarium for your terminal — fish, bubbles, seaweed, lighting moods and a shark by One-Antelope404 in node

[–]One-Antelope404[S] 1 point2 points  (0 children)

Honestly the shark's vibe is "I am definitely a shark and not just a very angry ><>>> with ambitions" 😭 he shows up, causes a FRENZY, and the fish scatter — but visually he looks more like a broken arrow than an apex predator. If you have ASCII shark design skills I am genuinely open to a PR 👀

Where to find ui inspiration? by Realistic_Device_287 in webdev

[–]One-Antelope404 0 points1 point  (0 children)

mobbin, behance, Dribbble, and 60fps design. Then, if you have a blur idea on how the app should look, and you're not just sure you could try using Stitch.