A rectangular selection frame with dashes marching clockwise around an empty middle.
┏╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌━■━━╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌━━━━╌╌┓ ┃ ╎ ╎ ┃ ╎ ┃ ■ ■ ╎ ┃ ┃ ╎ ┃ ╎ ┗━╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌■━━━╌╌╌╌━━━━╌╌╌╌━━━━╌╌╌╌━━━━╌┛
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="marching-ants-frame"></ascii-art>// copy marching-ants-frame.js and kit.js into your project, then:
import { useEffect, useRef } from "react";
import create from "./marching-ants-frame.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 marching-ants-frame<!-- Download GIF below, commit it, then: -->
<p align="center">
<img src="assets/marching-ants-frame.gif" alt="Marching Ants Frame, 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.
/* marching-ants-frame: a rectangular selection frame with dashes marching around it. */
import { Grid, palette } from "../lib/kit.js";
export const meta = {
slug: "marching-ants-frame",
name: "Marching Ants Frame",
category: "frames",
note: "A rectangular selection frame with dashes marching clockwise around an empty middle.",
tags: ["border", "frame", "selection", "readme", "box"],
cols: 60, rows: 9, fps: 20,
palette: palette(["#e6edf3", "#484f58", "#79c0ff", "#8b949e"]),
};
function perimeter(w, h) {
const p = [];
for (let x = 0; x < w; x++) p.push([x, 0, "h"]);
for (let y = 1; y < h; y++) p.push([w - 1, y, "v"]);
for (let x = w - 2; x >= 0; x--) p.push([x, h - 1, "h"]);
for (let y = h - 2; y >= 1; y--) p.push([0, y, "v"]);
return p;
}
export default function create() {
const { cols, rows } = meta;
const g = new Grid(cols, rows);
const P = perimeter(cols, rows);
const corners = { "0,0": "┏", [`${cols - 1},0`]: "┓", [`0,${rows - 1}`]: "┗", [`${cols - 1},${rows - 1}`]: "┛" };
return (t) => {
g.clear();
const step = Math.floor(t * 10);
P.forEach(([x, y, d], i) => {
const on = (((i - step) % 8) + 8) % 8 < 4;
const c = corners[`${x},${y}`];
if (c) { g.set(x, y, c, "0"); return; }
if (d === "h") g.set(x, y, on ? "━" : "╌", on ? "0" : "1");
else g.set(x, y, on ? "┃" : "╎", on ? "0" : "1");
});
// small resize handles at edge midpoints
const mx = Math.floor(cols / 2), my = Math.floor(rows / 2);
g.set(mx, 0, "■", "2"); g.set(mx, rows - 1, "■", "2");
g.set(0, my, "■", "2"); g.set(cols - 1, my, "■", "2");
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.