ascii-globe
v0.4.2
Published
Isomorphic ASCII globe renderer
Maintainers
Readme
Zero dependencies isomorphic ASCII-Art globe renderer in JavaScript.
See Live Demo
Installation
npm
npm install ascii-globeCDN
<!-- IIFE (global variable) -->
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<!-- ES Module -->
<script type="module">
import Globe from 'https://esm.run/ascii-globe';
</script>Usage
ES Module (Node.js / Vite / bundlers)
import Globe from 'ascii-globe';
const globe = new Globe({ size: 1.4 });
console.log(globe.render(90));CommonJS (Node.js)
const Globe = require('ascii-globe');
const globe = new Globe({ size: 1.4 });
console.log(globe.render(90));Browser (script tag)
<pre id="output"></pre>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script>
var globe = new Globe({ size: 1 });
document.getElementById('output').textContent = globe.render(0);
</script>Browser (ES Module)
<pre id="output"></pre>
<script type="module">
import Globe from 'https://esm.run/ascii-globe';
const globe = new Globe({ size: 1 });
document.getElementById('output').textContent = globe.render(0);
</script>API
new Globe(options?)
Creates a new globe instance.
| Option | Type | Default | Description |
|----------------|----------|---------|-----------------------------------------------------|
| size | number | 1.4 | Scale factor. 1 produces a 120x60 character grid. |
| map | string | — | Base64-encoded map data. Defaults to the built-in Earth map. |
| land | string | '#' | Character used to render land masses. |
| water | string | '-' | Character used to render water/ocean. |
| background | string | ' ' | Character used for the area outside the globe disk. |
| margin | number | 0 | Number of characters around the globe disk. |
| marginBlock | number | 0 | Vertical margin (overrides margin). |
| marginInline | number | 0 | Horizontal margin (overrides margin). |
| pin | string | '@' | Default character for location pins. Can include ANSI escape codes. |
| pinSize | number | 1 | Default size multiplier for pin markers. |
| pins | Pin[] | [] | Array of pin locations. |
| tilt | number | 0 | Axial tilt in degrees (Earth's tilt is 23.5°). |
| speed | number | 0.7 | Rotation speed in degrees per frame. |
| format | function | — | Callback (type, length) => string for custom output (see below). |
Pin object
| Property | Type | Required | Description |
|----------|----------|----------|--------------------------------------------------------------------|
| lat | number | yes | Latitude in degrees (-90 to 90). |
| long | number | yes | Longitude in degrees (-180 to 180). |
| char | string | no | Override character for this pin. Can include ANSI escape codes. |
| size | number | no | Size multiplier for this pin (overrides pinSize). |
format(type, length)
When provided, render() calls this function for each run of consecutive cells of the same type instead of using the land/water/background/pin characters. This lets you wrap output in HTML tags, ANSI codes, or any other markup.
| Type value | Meaning |
|------------|------------|
| 0 | Background |
| 1 | Water |
| 2 | Land |
| 3+ | Pin (index type - 3 in the pins array) |
Example — HTML colored output:
const globe = new Globe({
size: 1,
pins: [{ lat: 52.23, long: 21.01 }],
format(type, length) {
const chars = [' ', ' ', '#', '@'];
const colors = ['', '', 'green', 'red'];
const text = chars[type].repeat(length);
if (!colors[type]) return text;
return `<span style="color:${colors[type]}">${text}</span>`;
}
});
pre.innerHTML = globe.render(250);Custom maps
The library ships with an Earth map by default, but you can use a different map by passing
the map option. The package includes a built-in Death Star map:
import Globe from 'ascii-globe';
import deathStar from 'ascii-globe/maps/death-star';
const globe = new Globe({ map: deathStar, land: '#', water: ' ' });
console.log(globe.render(0));With a script tag (no modules), load the map as a separate script. The load order doesn't matter:
<pre id="output"></pre>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe/dist/maps/death-star.global.js"></script>
<script>
var globe = new Globe({ map: Globe.maps['death-star'], land: '#', water: ' ' });
document.getElementById('output').textContent = globe.render(0);
</script>You can also generate your own map data from any equirectangular projection image (see Generating custom map data below).
globe.render(rotation)
Returns a string with the ASCII globe rendered at the given rotation.
rotation— a single number (horizontal angle in degrees) or a[horizontal, vertical]pair. Values wrap around automatically.
globe.render(90); // horizontal rotation only
globe.render([90, 30]); // horizontal + vertical tiltCLI
npx ascii-globe --rotation 200
npx ascii-globe --animateOr install globally:
npm install -g ascii-globe
globe --rotation 200
globe --animateASCII Globe v0.4.2 - Isomorphic ASCII globe renderer
Usage: globe <--rotation <degrees> | --animate> [options]
Options:
--rotation <degrees> Rotation angle (single number or h,v pair)
--animate Animate the globe in the terminal
--size <number> Globe size multiplier (default: 1.4)
--map <file> Path to a map data file (generated by extract-texture)
--land <char> Character for land (default: #)
--water <char> Character for water (default: -)
--background <char> Character for background (default: " ")
--margin <number> Characters around the globe (default: 0)
--margin-block <n> Vertical margin (overrides --margin)
--margin-inline <n> Horizontal margin (overrides --margin)
--pin <char> Character for location pins (default: @)
--pin-size <number> Size of pin markers (default: 1)
--pins <coords> Pin locations as lat,long pairs separated by ;
--tilt <degrees> Axial tilt in degrees (default: 0)
--speed <number> Rotation speed in degrees per frame (default: 0.7)
--help Show this help message
-v, --version Show version number
Either --rotation or --animate is required.Example with pins (Warsaw and New York):
globe --rotation 250 --pins '52.23,21.01;40.71,-74.01'
globe --rotation 250 --pin '\x1b[31m@\x1b[m' --pins '52.23,21.01'Example with a custom map:
globe --rotation 40,20 --map ./my-map.js --land '#' --water ' 'Examples
Node.js terminal animation
import Globe from 'ascii-globe';
const globe = new Globe({ size: 1, land: '#', water: ' ', tilt: 23.5 });
let rotation = 0;
process.stdout.write('\x1B[?25l'); // hide cursor
setInterval(() => {
process.stdout.write('\x1B[2J\x1B[H'); // clear + home
process.stdout.write(globe.render(rotation));
rotation = (rotation + globe.speed) % 360;
}, 1000 / 30);Run the included example:
npm run example:nodeBrowser animation
<pre id="globe"></pre>
<button id="toggle">Pause</button>
<input id="rotation" type="number" min="0" max="360" step="0.1" value="0" disabled>
<script src="https://cdn.jsdelivr.net/npm/ascii-globe"></script>
<script>
var globe = new Globe({ size: 1, land: '#', water: ' ' });
var pre = document.getElementById('globe');
var playing = true;
var rotation = 0;
function loop() {
pre.textContent = globe.render(rotation);
if (playing) {
rotation = (rotation + 0.7) % 360;
requestAnimationFrame(loop);
}
}
document.getElementById('toggle').addEventListener('click', function() {
playing = !playing;
if (playing) loop();
});
loop();
</script>Open examples/browser/index.html via a local server to run the included browser demo.
Generating custom map data
You can generate map data from any equirectangular projection image (2:1 aspect ratio PNG). The extract script is included in the repository:
npx tsx scripts/extract-texture.ts <image.png> --output <output.ts>Options:
| Flag | Description |
|----------------|----------------------------------------------------------|
| --output <path> | Output file path (default: src/maps/<name>.ts) |
| --grayscale | Use brightness instead of Earth-specific color detection |
| --alpha | Use the alpha channel as the mask (opaque = land) |
| --invert | Invert the mask (swap land and water) |
The default mode classifies pixels using Earth-specific color heuristics (blue → water,
dark → land). Use --grayscale or --alpha for non-Earth images.
The output file can be imported and passed to the map option:
import Globe from 'ascii-globe';
import myMap from './my-map.ts';
const globe = new Globe({ map: myMap });Or used with the CLI:
globe --rotation 90 --map ./my-map.tsBuilding from source
npm install
npm run extract # generate src/maps/ from globe.png and death-star.png
npm run build # compile TypeScript to dist/Acknowledgments
World map texture by Ebrahim; CC BY-SA 4.0; source Wikimedia Commons.
License
Copyright (c) 2025 Jakub T. Jankiewicz
Released under the MIT License. See LICENSE for details.
