Four terminal progress bars filling at their own pace, with percent and a spinner.
⠦ fetch █████░░░░░░░░░░░░░░░░░░░░░░░░░ 16% ⠧ resolve ███░░░░░░░░░░░░░░░░░░░░░░░░░░░ 12% ⠇ build ███░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9% ⠏ deploy ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 7%
Paste two lines into any page, play it in a terminal, or put a GIF in a README. The code follows the look you pick above.
<script type="module" src="https://www.ascii-magic.com/ascii/ascii.js"></script>
<ascii-art piece="progress-loader"></ascii-art>// copy progress-loader.js and kit.js into your project, then:
import { useEffect, useRef } from "react";
import create from "./progress-loader.js";
export function Piece() {
const ref = useRef(null);
useEffect(() => {
const draw = create(), t0 = performance.now();
let raf;
const tick = () => {
const f = draw((performance.now() - t0) / 1000);
ref.current.textContent = f.text ?? f;
raf = requestAnimationFrame(tick);
};
tick();
return () => cancelAnimationFrame(raf);
}, []);
return <pre ref={ref} style={{ lineHeight: 1, fontFamily: "Menlo, Consolas, monospace" }} />;
}npx --yes https://www.ascii-magic.com/ascii/cli.tgz progress-loader<!-- Download GIF below, commit it, then: -->
<p align="center">
<img src="assets/progress-loader.gif" alt="Progress Loader, animated ASCII art" width="720">
</p>Pause on the frame you like, pick a look, then download it at an exact size.
MIT licensed. It imports one small helper file, kit.js.
/* progress-loader: a stack of terminal progress bars, each filling at its own pace. */
import { Grid, palette } from "../lib/kit.js";
export const meta = {
slug: "progress-loader",
name: "Progress Loader",
category: "screens",
note: "Four terminal progress bars filling at their own pace, with percent and a spinner.",
tags: ["loader", "terminal", "cli", "install"],
cols: 56, rows: 9, fps: 15,
palette: palette(["#7ee787", "#79c0ff", "#8b949e", "#e6edf3"]),
};
const TASKS = [["fetch", 3.1], ["resolve", 4.3], ["build", 5.7], ["deploy", 7.2]];
const SPIN = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏";
export default function create() {
const g = new Grid(meta.cols, meta.rows);
return (t) => {
g.clear();
const loop = t % 9;
TASKS.forEach(([name, dur], i) => {
const y = 1 + i * 2;
const p = Math.min(1, loop / dur);
const w = 30, n = Math.round(p * w);
g.text(2, y, (p < 1 ? SPIN[Math.floor(t * 12 + i) % SPIN.length] : "✓"), p < 1 ? "1" : "0");
g.text(4, y, name.padEnd(8), "3");
g.text(13, y, "█".repeat(n), p < 1 ? "1" : "0");
g.text(13 + n, y, "░".repeat(w - n), "2");
g.text(45, y, String(Math.round(p * 100)).padStart(3) + "%", "3");
});
return g.frame();
};
}
/YOUR OWN
The pieces here are hand-built animations. To turn your own photo, logo or video into animated ASCII, use the ASCII Magic editor.