ascii README

The project's README from github.com/bas3line/ascii. As one markdown file: README.md.

ascii.rest

A lit donut turning, drawn in ascii

Thanks to the sponsors who make running ascii.rest possible

Command Code        Cloudflare


Animated ascii art for web pages.
216 pieces for React, Next.js, Astro or plain HTML.

ascii.rest · install · pieces · contributing

by @bas3line CI npm MIT TypeScript


Written in TypeScript by @bas3line. 216 pieces, from full-colour scenes to loaders, charts, language logos, Linux distros, spinning shapes and physics. The donut above turns on a page with one tag: <ascii-art piece="donut"></ascii-art>. See them all at ascii.rest.

night coast aurora fjord earthrise kyoto dusk torus knot taj dawn

Why

I've always been a fan of Markdown files and terminal-style websites: plain text, one monospace face, nothing that moves without a reason. The kind of quiet web that planetscale.com does well. So I made this, a way to put a little motion on pages like that without giving up the style. If you like minimalism, this library is for you.

Install

npm install ascii.rest

Or skip installing: the HTML tag loads everything from ascii.rest.

React and Next.js

import { Ascii } from "ascii.rest/react";
import { donut } from "ascii.rest/pieces";

<Ascii piece={donut} />
<Ascii piece="night-coast" />                          // fetched by name when it mounts
<Ascii piece={donut} options={{ fps: 12 }} className="art" />
<Ascii piece="rust" mono />                            // a logo in one ink

Ascii is a client component ("use client"), so it goes straight into the Next.js app router. Text pieces draw into a <pre> in its colour and font size; the coloured ones, scenes, logos, companies and distros, draw onto a <canvas> as wide as its container, or into a <pre> in one ink with mono.

Astro

---
import Ascii from "ascii.rest/astro";
---

<Ascii piece="donut" />
<Ascii piece="big-text" options={{ text: "hello" }} class="banner" />

The first frame is rendered on the server, so the page is whole before any script runs; the piece starts playing once the page loads.

HTML, no build step

<script type="module" src="https://ascii.rest/ascii.js"></script>

<ascii-art piece="donut"></ascii-art>

Style it like text: ascii-art { font-size: 10px; color: teal; }. The logos, companies and distros come in their own colours; add mono, <ascii-art piece="rust" mono>, to draw one in the text's colour instead. In a bundled app, import "ascii.rest/element" defines the same tag.

In a GitHub README

A README runs no script, so every logo, company and distro also comes as an animated SVG, one loop of its glint or scan, at https://ascii.rest/svg/<name>.svg for light pages and <name>.dark.svg for dark ones:

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://ascii.rest/svg/rust.dark.svg">
  <img alt="rust" src="https://ascii.rest/svg/rust.svg" width="320">
</picture>

GitHub shows the dark one in its dark theme. Each piece's page on ascii.rest has its snippet under readme.

In a terminal

npx ascii.rest rust                        # plays until you press a key
npx ascii.rest night-coast --seconds 10
npx ascii.rest list                        # every piece's name, by category

The logos, companies, distros and scenes play in their own colours, in 24-bit colour. A scene is shrunk to fit the terminal, whatever its size, and drawn in tones, two of its rows in each of the terminal's as half blocks, so the dots it is made of blend as they do on a page. --mono draws a coloured piece in the terminal's own colour, for a terminal without 24-bit colour, and --light takes the colours meant for a light background. --fps and --seconds set the speed and the length. The piece plays centred; any other piece wider or taller than the terminal shows only its middle, and it says so when it stops. Piped or redirected, it prints its first frame as text.

As a splash screen

import { play } from "ascii.rest/terminal";

const { interrupted } = await play("command-code", { seconds: 2 });
if (interrupted) process.exit(130);

play(piece, options?) takes a piece module or a name and resolves when the piece stops: after seconds, on any key, or on Ctrl+C, which sets interrupted. It plays on the alternate screen with the cursor hidden, and puts the terminal back however it stops, on an error too. When the output is not a terminal it draws nothing and resolves at once, so a pipe or a CI log never gets a splash. It uses only Node's own modules.

option
seconds how long it plays; until a key is pressed by default
mono draws a coloured piece in the terminal's own colour
light for a light terminal: the light colours, and shaded pieces flipped
fps frames a second, instead of the piece's own
options the piece's option overrides: { text: "hello" }
out where it draws: process.stdout by default

It resolves with { interrupted, cropped, piece, terminal }: cropped is true when the terminal was smaller than the piece, whose size and the terminal's are in piece and terminal.

TypeScript, anywhere

import { mount } from "ascii.rest";
import { donut } from "ascii.rest/pieces";

const stop = mount(document.querySelector("pre")!, donut, { fps: 12 });

API

mount(element, piece, options?)

Plays piece in element and returns a function that stops it.

load, names, canvas, isPiece

From ascii.rest. load["night-coast"]() imports any piece by name, names lists every name, canvas is the set of pieces drawn on a canvas, and isPiece(name) narrows a string to a piece name.

<Ascii> (React)

prop type
piece piece module or name a module is bundled, a name is fetched when it mounts
options object option overrides, and fps
label string what it shows, for screen readers; the piece's name by default
mono boolean draws a coloured piece in one ink, in a <pre>
className, style passed to the <pre> or <canvas>

<Ascii> (Astro)

piece (a name), options, fps, label, mono and class.

<ascii-art>

attribute
piece a piece's name: donut, night-coast
src or the URL of any module that follows the piece contract
fps overrides the frame rate
options JSON overriding the option defaults: '{"text":"hello"}'
label what it shows, for screen readers
mono draws a coloured piece in one ink, the text's colour

Browser support

Any current browser: it needs ES modules, custom elements and IntersectionObserver, plus ResizeObserver for the coloured pieces. Importing any module on a server, for server rendering, is safe: nothing touches the DOM until a piece is mounted.

Many pieces draw with box drawing and block glyphs (─ │ ╭ █ ▄ ░). Where the system monospace face has none, as on Android, the tag and the Astro component take them from "ascii.rest mono", a 3 KB cut of JetBrains Mono (OFL) served by ascii.rest, so every row keeps its width. Only a browser that lacks the glyphs fetches it. With React, put it in your own <pre>'s font stack:

@font-face {
  font-family: "ascii.rest mono";
  src: url("https://ascii.rest/fonts/ascii-rest-mono.woff2") format("woff2");
  unicode-range: U+00B0, U+00B7, U+2022, U+2500-259F, U+25CF;
}
pre.art { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", "ascii.rest mono", monospace; }

Pieces

category pieces
scenes alpine dawn, aurora fjord, deep reef, desert night, earthrise, kyoto dusk, lantern lake, marine drive, misty forest, night coast, ocean sunset, storm plains, taj dawn, tokyo rain, varanasi ghats
ui boot log, box frames, calendar, digital clock, dividers, file tree, form controls, not found, progress bar, skeleton, spinners, terminal
data bar chart, candlesticks, cpu meters, equalizer, gauge, heartbeat, heatmap, radar, sparkline, uptime bar
type big text, dissolve, glitch, marquee, morse, scramble, split-flap, typewriter, wave text
logos c, c#, c++, clojure, css, dart, elixir, elm, erlang, go, haskell, html, java, javascript, julia, kotlin, lua, ocaml, perl, php, python, r, ruby, rust, scala, svelte, swift, typescript, zig
companies a0, agentmail, apple, autumn, cloudflare, coderabbit, collabute, command code, databuddy, greptile, helium, keiki, mintlify, orchid, planetscale, playstation, polar, supabase, supermemory, vercel
distros almalinux, alpine linux, arch linux, centos, debian, deepin, elementary os, endeavouros, fedora, gentoo, kali linux, linux mint, manjaro, nixos, omarchy, opensuse, pop!_os, red hat, rocky linux, tux, ubuntu, void linux, zorin os
shapes cube, dna helix, donut, glxgears, gyroscope, heart, icosahedron, mobius strip, spring, tesseract, torus knot, twisted ring
space black hole, earth, eclipse, galaxy, moon phases, planet, rocket, saptarishi, solar system, starfield, three-body
physics bouncing balls, chladni plate, double pendulum, falling sand, flag, fountain, harmonograph, lorenz attractor, newton's cradle, pendulum wave, plucked string, pond ripples, smoke, wave interference
nature aurora, bonsai, campfire, cherry blossom, contour map, fern, fireflies, fractal tree, landscape, lightning, rain, ruled mountains, sea swell, snowfall, sunrise, wind
creatures aquarium, butterfly, cat, fox, jellyfish, owl, snake, spider, starlings, whale
objects analog clock, candle, coffee, ferris wheel, hawa mahal, hourglass, kite, lava lamp, lighthouse, skyline, sundial, train, vinyl, windmill
generative epicycles, flow field, glider gun, hilbert curve, julia set, langton's ant, mandelbrot, maze, plasma, reaction diffusion, rule 30, sierpinski, voronoi
effects doom fire, fireworks, matrix rain, rotozoomer, sparks, synthwave, tunnel, tv static

The logos and distros are drawn from devicon (MIT) and Simple Icons (CC0); omarchy's mark there is its own, MIT licensed, from omarchy.org. The companies are drawn from Simple Icons too, and a0, agentmail, autumn, coderabbit, collabute, command code, databuddy, greptile, keiki, orchid, polar and supermemory from their own marks on a0.dev, agentmail.to, useautumn.com, coderabbit.ai, collabute.ai, commandcode.ai, databuddy.cc, greptile.com, onkeiki.com, orchid.ai, polar.sh and supermemory.ai. Each is a trademark of its owner, shown here to name the language, the distribution or the company.

Contributing

New pieces, fixes and ideas are welcome. CONTRIBUTING.md covers the piece contract, the checks and how to open a pull request, and the code of conduct applies everywhere. Found a security problem? See SECURITY.md.

Author

Made by @bas3line. If you use it, a link back is appreciated, and so is a star.

To support it: GitHub Sponsors, Buy Me a Coffee or PayPal.

License

MIT, © @bas3line

ascii (bas3line/ascii)

Searching Database…

893 ·GitHub
这是什么?ascii 是一个 TypeScript 库,收录 216 件网页用的动态 ASCII 艺术作品,可用于 React、Next.js、Astro、纯 HTML、终端和 GitHub README。
怎么把一件作品加到我的页面?放入纯 HTML 自定义元素即可,它从 ascii.rest 加载一切、零安装;或者安装该包,使用 mount() API、React 组件或 Astro 组件。
需要打包器或构建步骤吗?不需要。HTML 自定义元素无需构建步骤即可工作,在运行时按名称获取作品;打包应用如果愿意也可以导入该元素或框架封装。
动画总是立即播放吗?不是。为了照顾偏好减少动态效果的读者,作品默认停留在第一帧,只有当读者显式选择某个控件、设置 motion:true 后才会动起来。
这些作品能在终端里运行,而不只是浏览器吗?可以。一个 CLI 能以 24 位终端色彩直接播放标志、场景和形状,带有 --mono、--light、--fps 和 --seconds 标志,还有一个 play() 函数可以把任何作品显示为启动画面。
它支持哪些浏览器?任何支持 ES 模块、自定义元素和 IntersectionObserver 的现代浏览器;彩色作品还需要 ResizeObserver;在服务器端为 SSR 导入也是安全的,因为在 mount 之前不会触碰 DOM。
库里的所有东西都能自由使用吗?代码采用 MIT 许可证,但其中捆绑的公司和标志图案是各自所有者的商标,收录它们只是为了代表其所属的语言、发行版或公司。
包含哪些类别的作品?216 件作品涵盖场景、UI 元素、数据图表、文字特效、语言和发行版标志、公司标志、3D 形状、太空场景、物理模拟、自然、生物、物品、生成艺术和屏幕特效。
作者为什么构建这个而不是通用的动画库?作者喜欢以纯等宽文字呈现的极简终端风格网站(比如 planetscale.com),想在不放弃这种美学的前提下为其添加细微的动感。
可以在 GitHub README 里嵌入动态作品吗?可以。标志、公司和发行版还提供动态 SVG 版本,带有明、暗两套版本,GitHub 在深色主题下会自动选用深色版。
如果终端缺少对应的字体字形会怎样?很多作品使用制表符和方块字形;在 Android 这类缺少这些字形的系统上,库会自动提供一个 3KB 的 JetBrains Mono 精简版,让每行保持一致的宽度。
Creator
bas3line
Size
3.3 MB
Stars
893
Updated
CommitOct 15
Age
10d
Commits · 90 Days