npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eink-simulator

v1.0.0

Published

Web-based e-ink display simulator with pixel-perfect Adafruit GFX font rendering

Readme

E-Ink Display Simulator

A web-based simulator for e-ink displays with pixel-perfect Adafruit GFX font rendering. Designed for rapid UI prototyping without flashing hardware.

Features

  • Pixel-perfect rendering - Uses actual bitmap font data extracted from Adafruit GFX headers
  • Full drawing primitives - Lines, rectangles, circles, triangles, rounded rectangles, XBitmap images
  • GFX-compatible API - Mirrors Adafruit GFX library function signatures
  • TypeScript support - Full type definitions for IDE autocomplete and type safety
  • Export options - Download PNG or copy to clipboard
  • Scalable display - 1x to 4x zoom with pixel-perfect scaling
  • Zero runtime dependencies - Pure vanilla JavaScript

Installation

npm install eink-simulator

Quick Start

Browser (Script Tag)

<canvas id="display" width="296" height="128"></canvas>
<script src="node_modules/eink-simulator/dist/eink-simulator.bundle.js"></script>
<script>
  const { EinkSimulator } = window.EinkSimulator;

  const canvas = document.getElementById('display');
  const sim = new EinkSimulator(canvas, { width: 296, height: 128 });

  sim.clear();
  sim.fillRect(10, 10, 50, 30);
  sim.drawCircle(100, 50, 20);
  sim.drawText('Hello World', 150, 50);  // Uses built-in 5x7 font
</script>

ES Modules

import { EinkSimulator } from 'eink-simulator';

const canvas = document.getElementById('display') as HTMLCanvasElement;
const sim = new EinkSimulator(canvas, { width: 296, height: 128 });

sim.clear();
sim.fillRect(10, 10, 50, 30);
sim.drawText('Hello', 10, 50);

Using Custom Fonts

The simulator includes a built-in 5x7 monospace font. For custom Adafruit GFX fonts, you need to extract font data from C header files.

# Extract fonts from Adafruit GFX headers
npx extract-fonts \
  --fonts-dir ./path/to/Adafruit_GFX_Library/Fonts \
  --fonts "FreeSans9pt7b,FreeMono12pt7b" \
  --output ./src/generated/font-data.ts

Then import and use the fonts:

import { EinkSimulator } from 'eink-simulator';
import { FreeSans9pt7b } from './generated/font-data.js';

const sim = new EinkSimulator(canvas, { width: 296, height: 128 });
sim.drawText('Custom Font', 10, 50, FreeSans9pt7b);

Font Extraction

Using a Config File

Create fonts.config.json:

{
  "fontsDir": "./path/to/Adafruit_GFX_Library/Fonts",
  "customFontsDir": "./src/fonts",
  "fonts": [
    "FreeSans9pt7b",
    "FreeSansBold12pt7b",
    "FreeMono9pt7b"
  ],
  "output": "./src/generated/font-data.ts"
}

Run the extractor:

npx extract-fonts --config fonts.config.json

CLI Options

npx extract-fonts [options]

Options:
  --config       Path to JSON config file
  --fonts-dir    Directory containing Adafruit GFX font headers
  --custom-dir   Directory containing custom font headers (optional)
  --fonts        Comma-separated list of font names (without .h extension)
  --output       Output file path (default: stdout)
  --help, -h     Show help message

Converting TTF/OTF to Adafruit GFX Format

Use the Adafruit GFX fontconvert tool to convert TrueType fonts:

# Build fontconvert (requires FreeType)
cd Adafruit_GFX_Library/fontconvert
make

# Convert a font
./fontconvert MyFont.ttf 12 > MyFont12pt7b.h

API Reference

EinkSimulator Class

const sim = new EinkSimulator(canvas, {
  width: 296,      // Display width in pixels
  height: 128,     // Display height in pixels
  foreground: '#000000',  // Black (default)
  background: '#FFFFFF',  // White (default)
});

Drawing Methods

| Method | Description | |--------|-------------| | clear() | Clear display with background color | | drawPixel(x, y, color?) | Draw a single pixel | | drawLine(x0, y0, x1, y1, color?) | Draw a line | | drawHLine(x, y, length, color?) | Draw horizontal line | | drawVLine(x, y, length, color?) | Draw vertical line | | drawRect(x, y, w, h, color?) | Draw rectangle outline | | fillRect(x, y, w, h, color?) | Fill rectangle | | drawCircle(x, y, r, color?) | Draw circle outline | | fillCircle(x, y, r, color?) | Fill circle | | drawTriangle(x0, y0, x1, y1, x2, y2, color?) | Draw triangle outline | | fillTriangle(x0, y0, x1, y1, x2, y2, color?) | Fill triangle | | drawRoundRect(x, y, w, h, r, color?) | Draw rounded rectangle outline | | fillRoundRect(x, y, w, h, r, color?) | Fill rounded rectangle | | drawXBitmap(x, y, bitmap, w, h, color?) | Draw XBitmap image | | drawXBitmapScaled(x, y, bitmap, w, h, sw, sh, color?) | Draw scaled XBitmap |

Text Methods

| Method | Description | |--------|-------------| | setFont(font) | Set current font (null for built-in 5x7) | | setTextColor(color) | Set text color | | drawText(text, x, y, font?, color?) | Draw text at position | | drawTextCentered(text, x, y, width, font?, color?) | Draw centered text | | drawTextRightAligned(text, rightX, y, font?, color?) | Draw right-aligned text | | getTextWidth(text, font?) | Get text width in pixels | | getTextBounds(text, font?) | Get text bounds { w, h, yMin, yMax } |

Export Methods

| Method | Description | |--------|-------------| | toDataURL() | Get PNG as data URL | | toBlob() | Get PNG as Blob (async) | | download(filename?) | Download as PNG | | copyToClipboard() | Copy to clipboard (async) | | setScale(scale) | Set CSS scale (1-4x) | | getContext() | Get the drawing context |

Built-in 5x7 Font

The GFX library includes a built-in 5x7 monospace font that's always available:

sim.setFont(null);  // Use built-in font
sim.drawText('Hello', 10, 10);

// Or pass null/undefined as the font parameter
sim.drawText('World', 10, 20, null);

Important differences from GFXfont:

  • Uses top-left positioning (not baseline like custom fonts)
  • Character width: 6px (5px glyph + 1px spacing)
  • Character height: 7px

Types

interface GFXFont {
  name: string;
  bitmap: number[];
  glyphs: Record<number, GFXGlyph>;
  first: number;
  last: number;
  yAdvance: number;
}

interface GFXGlyph {
  offset: number;
  width: number;
  height: number;
  xAdvance: number;
  xOffset: number;
  yOffset: number;
}

interface DisplayConfig {
  width: number;
  height: number;
  foreground?: string;
  background?: string;
}

interface TextBounds {
  w: number;
  h: number;
  yMin: number;
  yMax: number;
}

Project Structure

eink-simulator/
├── src/
│   ├── types.ts          # Type definitions
│   ├── primitives.ts     # Drawing primitives
│   ├── fonts.ts          # Font rendering
│   ├── simulator.ts      # Main simulator class
│   ├── index.ts          # Entry point
│   └── generated/
│       └── font-data.ts  # Your extracted fonts go here
├── scripts/
│   ├── extract-fonts.js  # Font extraction CLI tool
│   └── bundle.js         # Browser bundler
├── dist/                 # Compiled output
│   ├── index.js          # ES module
│   ├── index.d.ts        # Type definitions
│   └── eink-simulator.bundle.js  # Browser bundle
├── examples/
│   └── basic-shapes.html # Demo page
├── fonts.config.example.json
├── package.json
└── tsconfig.json

Building from Source

# Clone the repository
git clone https://github.com/slavik0329/eink-simulator.git
cd eink-simulator

# Install dependencies
npm install

# Build TypeScript and create bundle
npm run build

# Watch for changes during development
npm run watch

License

MIT