gta vi
[docs] [github1.1k]the vi of grand theft auto vi, in a sunset, glinting now and then
companies 76×32 30 fps in colour or one ink 11.7 kB [report a bug]
88888888888888 88888888888888 88888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 888888888888 888888888888 888888888888888888 888888888888888888888888 888888888888888888 8888888888888888888888 888888888888888888 88888888888888888888 888888888888888888 888888888888888888 888888888888888888 8888888888888888 888888888888888888 88888888888888 888888888888888888 88888888888888 888888888888888888 888888888888 888888888888888888 8888888888 888888888888888888 88888888 888888888888888888 888888 888888888888888888 8888 8888888888888888 88 88888888888888 88888888888888 88888888888888 88888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 888888888888 888888888888 888888888888888888 888888888888888888888888 888888888888888888 8888888888888888888888 888888888888888888 88888888888888888888 888888888888888888 888888888888888888 888888888888888888 8888888888888888 888888888888888888 88888888888888 888888888888888888 88888888888888 888888888888888888 888888888888 888888888888888888 8888888888 888888888888888888 88888888 888888888888888888 888888 888888888888888888 8888 8888888888888888 88 88888888888888
download
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://ascii.rest/svg/gta-vi.dark.svg"> <img alt="gta vi" src="https://ascii.rest/svg/gta-vi.svg" width="380"> </picture>
Yours? The readme snippet puts it in your README, moving, in GitHub's light and dark themes. A post with the video or GIF from the downloads moves too; a link alone shows its card, which holds still.
use it
[docs][copy it in]html
<script type="module" src="https://ascii.rest/ascii.js"></script> <ascii-art piece="gta-vi" options='{"shine":5}'></ascii-art>
No install and no build step. ascii.js defines the <ascii-art> tag, loads the piece from ascii.rest, plays it while it is on screen, and holds the first frame for anyone who prefers reduced motion. Add mono, <ascii-art piece="gta-vi" mono>, for one ink.
react
// npm install ascii.rest import { Ascii } from "ascii.rest/react"; import { gtaVi } from "ascii.rest/pieces"; <Ascii piece={gtaVi} options={{"shine":5}} />
A client component, so it works in the Next.js app router as it is. Pass the name instead, piece="gta-vi", to fetch the piece only when it mounts. Add mono for one ink.
astro
--- // npm install ascii.rest import Ascii from "ascii.rest/astro"; --- <Ascii piece="gta-vi" options={{"shine":5}} />
Renders the first frame on the server, so the page is whole before any script runs, then plays the piece once it loads. Add mono for one ink.
typescript
// npm install ascii.rest import { mount } from "ascii.rest"; import { gtaVi } from "ascii.rest/pieces"; const el = document.querySelector<HTMLCanvasElement>("canvas")!; const stop = mount(el, gtaVi, {"shine":5});
mount plays a piece in a <pre>, or on a <canvas> for the coloured ones, and returns a function that stops it. Every piece, option and frame is typed. Mount it in a <pre> for one ink.
terminal
npx ascii.rest gta-vi Plays it in your terminal, in colour, until you press a key. Add --mono for the terminal's own colour. Add --light for a light terminal. Add --seconds 5 to stop it on its own; npx ascii.rest list shows every piece. In a CLI of your own, play("gta-vi", { seconds: 2 }) from ascii.rest/terminal shows it as a splash screen.
agent
npx skills add bas3line/ascii # then ask your agent: # add the gta-vi piece to my home page
Gives Claude Code, Cursor, Codex or another coding agent the ascii.rest skill: every piece, the snippet for your framework, and these docs to read offline. Then ask in your own words, and it adds gta-vi the way your project needs. The skill is on skills.sh.
readme
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://ascii.rest/svg/gta-vi.dark.svg"> <img alt="gta vi" src="https://ascii.rest/svg/gta-vi.svg" width="380"> </picture>
An animated SVG that needs no script, so it plays in a GitHub README, which runs none. GitHub shows the dark one in its dark theme. It holds still for anyone who prefers reduced motion.
/* * gta-vi: the "VI" of Grand Theft Auto VI, in the mark's sunset, with a glint * crossing it every few seconds. * * Drawn from Rockstar Games' Grand Theft Auto VI mark: two thick strokes * meeting in a point below the bar between them, each letter edged in violet * and filled with the Vice City sunset, blue at the top of the letters through * purple, pink and coral to gold at the bottom, palm crowns spread over the * fill. On a canvas the outline takes its violet, the palms a shade sunk into * the sunset, and the fill the gradient, lifted a little on a dark page; in a * <pre> it is one ink, from the same drawing. Grand Theft Auto is a trademark * of its owner, shown here to name the game. */ import type { Frame, Meta } from "../types.ts"; export interface GtaViOptions { [key: string]: unknown; /** Seconds between glints; 0 keeps the mark still. */ shine: number; } export const meta = { name: "gta vi", category: "companies", note: "the vi of grand theft auto vi, in a sunset, glinting now and then", cols: 76, rows: 32, fps: 30, options: { shine: 5 }, // Per page: the sunset's 7 stops, the palms over them, then twice lighter for the glint; the outline last. palette: [ "#4a5ce6", "#7a4bd6", "#b043bc", "#e8418f", "#f87270", "#fb9c52", "#ffc95e", "#3b3294", "#502b8c", "#692781", "#82266c", "#893c5e", "#8a4f51", "#8c6356", "#929df0", "#af93e6", "#d08ed7", "#f18dbc", "#fbaaa9", "#fdc497", "#ffdf9e", "#c9cef8", "#d7c9f3", "#e7c7eb", "#f8c6dd", "#fdd5d4", "#fee1cb", "#ffefcf", "#5c1898", "#5566e8", "#8256d8", "#b54ec0", "#e94c96", "#f87a79", "#fba25c", "#ffcc68", "#403794", "#54308d", "#6b2c82", "#822b70", "#894062", "#8a5255", "#8c655b", "#99a3f1", "#b49ae8", "#d395d9", "#f294c0", "#fbafaf", "#fdc79d", "#ffe0a4", "#ccd1f8", "#daccf3", "#e9caec", "#f8c9e0", "#fdd7d7", "#fee3ce", "#fff0d2", "#8d3ad1", ], } satisfies Meta<GtaViOptions>; // In a <pre>, in the page's own colour. const MONO = String.raw` 88888888888888 88888888888888 88888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 888888888888 888888888888 888888888888888888 888888888888888888888888 888888888888888888 8888888888888888888888 888888888888888888 88888888888888888888 888888888888888888 888888888888888888 888888888888888888 8888888888888888 888888888888888888 88888888888888 888888888888888888 88888888888888 888888888888888888 888888888888 888888888888888888 8888888888 888888888888888888 88888888 888888888888888888 888888 888888888888888888 8888 8888888888888888 88 88888888888888 `; // On a canvas, and the colour of each cell: an index into the mark's colours. const ART = String.raw` 88888888888888 88888888888888 88888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 8888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 888888888888888 888888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 88888888888888 88888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 8888888888888 8888888888888 888888888888888888 888888888888 888888888888 888888888888888888 888888888888888888888888 888888888888888888 8888888888888888888888 888888888888888888 88888888888888888888 888888888888888888 888888888888888888 888888888888888888 8888888888888888 888888888888888888 88888888888888 888888888888888888 88888888888888 888888888888888888 888888888888 888888888888888888 8888888888 888888888888888888 88888888 888888888888888888 888888 888888888888888888 8888 8888888888888888 88 88888888888888 `; const INK = String.raw` 0000000000000000 0000000000000000 0000000000000000 0000000000000000 0000000000000000 000000000000000000 000000000000000 000000000000000 000000000000000000 000000000000000 000000000000000 000000000000000000 11111111111111 11111111111111 111111111111111111 11111111111111 11111111111111 111111111111111111 11111111111111 11111111111111 111111111111111111 11111111111111 11111111111111 111111111111111111 22222222222222 22222222222222 222222222222222222 22222222222222 22222222222222 222222222222222222 2222222222222 2222222222222 222222222222222222 2222222222222 2222222222222 222222222222222222 333333333333 333333333333 333333333333333333 333333333333333333333333 333333333333333333 3333333333333333333333 333333333333333333 44444444444444444444 444444444444444444 444444444444444444 444444444444444444 4444444444444444 444444444444444444 44444444444444 444444444444444444 55555555555555 555555555555555555 555555555555 555555555555555555 5555555555 555555555555555555 55555555 555555555555555555 666666 666666666666666666 6666 6666666666666666 66 66666666666666 `; // f fill, p palm, o outline. const LAYER = String.raw` oooooooooooooo oooooooooooooo oooooooooooooo offffffffffffffo offffffffffffffo offfffpffpffpppo offffffffffffffo oppffffffffffffo offffffppppfppfffo offfffffffffffo offfffffffffffo opppppppppppfffffo offfffffffppppo offfffffffffffo offffffppppppppffo offffffffpfffo oppffffffffffo offffffffppfffpppo offfffffffffpo offppppffffffo offffffffffppffffo offfffffppppfo offffffpppfffo offfffffffffppfffo offfffpppffffo oppffffffpfffo offffffffffffppffo offfppfffffffo offpppfffffffo offfffffffffffppfo ofppfffffffffo oppfffppfffffo offffffffffffffppo offfffffffffo ofppffffppffo offffffffpffffffpo offffffffppfo offfppffffppo offffffffpfffffffo offfffffppfo offffppffffo offffffffpfffffffo offffffppffooffffffpfffo offffffffpfffffffo offfffppffffffffffppfo offffffffpfffffffo offffppfffffffffffpo offffffffpfffffffo offppffffffffffffo offffffffpfffffffo ofppfffffffffffo offffffffpfffffffo oppffffffffffo offffffffpfffffffo oppffffffffffo offffffffpfffffffo opfffffffffo offffffffpfffffffo offffffffo offffffffpfffffffo offffffo offffffffffffffffo offffo offffffffffffffffo offo offffffffffffffo oo oooooooooooooo `; const START = 0.5; // seconds before the first glint const PASS = 2; // seconds a glint takes to cross const HALF = 5; // half its width, in cells const LEAN = 0.9; // cells it shifts left a row down, so it leans like a slash const SOLID = "8dbqpPYOo0"; // what the glint turns to slashes; thin edges keep their shape const lines = (art: string) => art.slice(1, -1).split("\n").map((line) => line.padEnd(meta.cols)); export default function gtaVi({ shine = meta.options.shine }: Partial<GtaViOptions> = {}): Frame { const { cols, rows } = meta; const mono = lines(MONO), art = lines(ART), ink = lines(INK), lay = lines(LAYER); const n = (meta.palette.length - 2) / 8; // colours a gradient stop group holds const every = shine > 0 ? Math.max(shine, PASS + 0.5) : 0; // The glint crosses the mark's ink, edge to edge, rather than the whole frame. let lo = Infinity, hi = -Infinity; for (const pic of [mono, art]) pic.forEach((line, y) => { for (let x = 0; x < cols; x++) if (line[x] !== " ") (lo = Math.min(lo, x + LEAN * y)), (hi = Math.max(hi, x + LEAN * y)); }); const span = hi - lo + 2 * HALF; return (t, { paper = false, color } = {}) => { const pic = color ? art : mono; const since = t - START; const at = every && since >= 0 ? lo - HALF + (span * (since % every)) / PASS : -Infinity; const out: string[] = []; for (let y = 0; y < rows; y++) { let line = ""; for (let x = 0; x < cols; x++) { let ch = pic[y][x]; if (ch !== " ") { const d = Math.abs(x + LEAN * y - at); let k = d < HALF ? 1 - d / HALF : 0; k = k * k * (3 - 2 * k); if (k > 0.55 && SOLID.includes(ch)) ch = "/"; if (color) { const l = lay[y][x]; color[y * cols + x] = l === "o" ? (paper ? 4 * n : 8 * n + 1) : (paper ? 0 : 4 * n + 1) + ((l === "p" ? 1 : 0) + (k > 0.6 ? 2 : k > 0.25 ? 1 : 0)) * n + parseInt(ink[y][x], 36); } } line += ch; } out.push(line); } return out.join("\n"); }; }