CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-terminal-kit

Comprehensive Node.js terminal library with 256 colors, interactive components, and advanced graphics capabilities

Pending
Overview
Eval results
Files

buffers-graphics.mddocs/

Buffers and Graphics

Terminal Kit provides advanced display management through screen buffers, text buffers, and image rendering capabilities. These components enable complex graphics, animations, and efficient screen updates.

Screen Buffers

ScreenBuffer

new termkit.ScreenBuffer(options: ScreenBufferOptions): ScreenBuffer;

Standard screen buffer for double-buffered display management.

interface ScreenBufferOptions {
  dst: Terminal;
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  blending?: boolean;
  wrap?: boolean;
  tabWidth?: number;
  forceSize?: boolean;
}
const term = require('terminal-kit').terminal;
const termkit = require('terminal-kit');

// Create screen buffer
const screenBuffer = new termkit.ScreenBuffer({
  dst: term,
  width: 80,
  height: 25
});

// Draw to buffer
screenBuffer.put({ x: 10, y: 5, attr: { color: 'red' } }, 'Hello World!');

// Update terminal
screenBuffer.draw();

ScreenBufferHD

new termkit.ScreenBufferHD(options: ScreenBufferHDOptions): ScreenBufferHD;

High-definition screen buffer with sub-cell resolution and 32-bit RGBA support.

interface ScreenBufferHDOptions extends ScreenBufferOptions {
  cellWidth?: number;
  cellHeight?: number;
}
// Create HD buffer for detailed graphics
const hdBuffer = new termkit.ScreenBufferHD({
  dst: term,
  width: 160,
  height: 50,
  cellWidth: 2,
  cellHeight: 1
});

// Draw with sub-pixel precision
hdBuffer.setPixel(25, 10, { r: 255, g: 100, b: 50, a: 255 });
hdBuffer.draw();

Screen Buffer Methods

Drawing Operations

// Text operations
screenBuffer.put(options: PutOptions, text: string): void;
screenBuffer.get(options: GetOptions): string;

// Cell operations  
screenBuffer.setAttrAt(x: number, y: number, attr: CellAttributes): void;
screenBuffer.getAttrAt(x: number, y: number): CellAttributes;

// Bulk operations
screenBuffer.fill(options: FillOptions): void;
screenBuffer.clear(): void;

interface PutOptions {
  x?: number;
  y?: number;
  attr?: CellAttributes;
  wrap?: boolean;
  direction?: 'right' | 'down' | 'left' | 'up';
}

interface CellAttributes {
  color?: string | number;
  bgColor?: string | number;
  bold?: boolean;
  italic?: boolean;
  underline?: boolean;
  // ... other style attributes
}
// Fill area with character and attributes
screenBuffer.fill({
  char: '█',
  attr: { color: 'blue', bgColor: 'white' },
  region: { x: 5, y: 5, width: 20, height: 10 }
});

// Put text with custom attributes
screenBuffer.put({
  x: 10,
  y: 3,
  attr: { color: 'brightGreen', bold: true }
}, 'Status: OK');

Region Operations

// Copy regions
screenBuffer.copyRegion(options: CopyRegionOptions): void;
screenBuffer.moveRegion(src: Region, dst: Point): void;

// Region scrolling
screenBuffer.vScroll(options: ScrollOptions): void;
screenBuffer.hScroll(options: ScrollOptions): void;

interface Region {
  x: number;
  y: number;
  width: number;
  height: number;
}

interface ScrollOptions {
  top?: number;
  bottom?: number;
  left?: number;
  right?: number;
  rows?: number;
  columns?: number;
}

Display Management

// Update display
screenBuffer.draw(options?: DrawOptions): void;
screenBuffer.drawCursor(): void;

// Buffer state
screenBuffer.resize(options: ResizeOptions): void;
screenBuffer.dump(): string;
screenBuffer.load(data: string): void;

interface DrawOptions {
  delta?: boolean;
  cursor?: boolean;
  inline?: boolean;
}

Text Buffers

TextBuffer

new termkit.TextBuffer(options: TextBufferOptions): TextBuffer;

Specialized buffer for text processing with advanced formatting and markup support.

interface TextBufferOptions {
  dst?: Terminal | ScreenBuffer;
  width?: number;
  height?: number;
  x?: number;
  y?: number;
  wrap?: boolean;
  hyphenate?: boolean;
  wordWrap?: boolean;
  tabWidth?: number;
  forceSize?: boolean;
}
const textBuffer = new termkit.TextBuffer({
  dst: term,
  width: 60,
  height: 20,
  wordWrap: true
});

// Add formatted text
textBuffer.append('This is ^Rred^ text and ^Bblue^ text.\n');
textBuffer.append('Line with **bold** markup.\n');

// Render to terminal
term.clear();
textBuffer.draw();

Text Buffer Operations

// Content management
textBuffer.setText(text: string): void;
textBuffer.append(text: string, attr?: CellAttributes): void;
textBuffer.prepend(text: string, attr?: CellAttributes): void;
textBuffer.insert(text: string, index?: number): void;

// Navigation and selection
textBuffer.moveTo(x: number, y: number): void;
textBuffer.moveToEndOfBuffer(): void;
textBuffer.moveToBeginningOfBuffer(): void;

// Scrolling
textBuffer.scrollTo(y: number): void;
textBuffer.scroll(dy: number): void;

Image Rendering

Image Loading and Display

// Load and display image
terminal.drawImage(url: string, options: ImageOptions, callback: ImageCallback): void;

// Image utilities
termkit.image.load(url: string, options: LoadOptions, callback: LoadCallback): void;

interface ImageOptions {
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  shrink?: {
    width: number;
    height: number;
  };
}

interface LoadOptions {
  terminal?: Terminal;
  shrink?: object;
}

type ImageCallback = (error: Error | null) => void;
type LoadCallback = (error: Error | null, image: ImageData) => void;
// Display image file
term.drawImage('./logo.png', {
  x: 10,
  y: 5,
  shrink: { width: 40, height: 20 }
}, (error) => {
  if (error) {
    term.red('Failed to load image: %s\n', error.message);
  } else {
    term.green('Image loaded successfully!\n');
  }
});

// Load image data for processing
termkit.image.load('./photo.jpg', {
  shrink: { width: 80, height: 40 }
}, (error, image) => {
  if (!error && image) {
    // Process image data
    term.moveTo(1, 20)('Image size: %dx%d\n', image.width, image.height);
  }
});

High-Definition Graphics

Pixel-Level Operations

// HD buffer pixel operations
hdBuffer.setPixel(x: number, y: number, rgba: RGBA): void;
hdBuffer.getPixel(x: number, y: number): RGBA;
hdBuffer.blendPixel(x: number, y: number, rgba: RGBA): void;

// Line and shape drawing  
hdBuffer.drawLine(x1: number, y1: number, x2: number, y2: number, rgba: RGBA): void;
hdBuffer.drawRect(x: number, y: number, width: number, height: number, rgba: RGBA): void;
hdBuffer.fillRect(x: number, y: number, width: number, height: number, rgba: RGBA): void;

interface RGBA {
  r: number; // 0-255
  g: number; // 0-255  
  b: number; // 0-255
  a: number; // 0-255
}
const hdBuffer = new termkit.ScreenBufferHD({
  dst: term,
  width: 120,
  height: 40
});

// Draw gradient
for (let x = 0; x < 120; x++) {
  for (let y = 0; y < 40; y++) {
    const red = Math.floor(255 * x / 120);
    const green = Math.floor(255 * y / 40);
    hdBuffer.setPixel(x, y, { r: red, g: green, b: 100, a: 255 });
  }
}

hdBuffer.draw();

Image Composition

// Image blending modes
hdBuffer.drawImage(image: ImageData, options: DrawImageOptions): void;

interface DrawImageOptions {
  x?: number;
  y?: number;
  srcX?: number;
  srcY?: number;
  srcWidth?: number;
  srcHeight?: number;
  blending?: BlendMode;
  opacity?: number;
}

type BlendMode = 'normal' | 'multiply' | 'screen' | 'overlay' | 'add';

Animation and Effects

Buffer Animation

// Animation helpers
screenBuffer.vScroll(rows: number, options?: ScrollOptions): void;
screenBuffer.hScroll(columns: number, options?: ScrollOptions): void;

// Custom animation loop
function animateBuffer() {
  // Clear buffer
  screenBuffer.clear();
  
  // Draw current frame
  drawFrame(frameNumber++);
  
  // Update display
  screenBuffer.draw({ delta: true });
  
  // Schedule next frame
  setTimeout(animateBuffer, 50);
}

Sprite Management

class Sprite {
  constructor(x, y, width, height, data) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.data = data;
  }
  
  draw(buffer) {
    for (let dy = 0; dy < this.height; dy++) {
      for (let dx = 0; dx < this.width; dx++) {
        const char = this.data[dy * this.width + dx];
        if (char !== ' ') {
          buffer.put({
            x: this.x + dx,
            y: this.y + dy
          }, char);
        }
      }
    }
  }
  
  move(dx, dy) {
    this.x += dx;
    this.y += dy;
  }
}

// Usage
const player = new Sprite(10, 5, 3, 2, [
  '@@@',
  '|||'
]);

function gameLoop() {
  screenBuffer.clear();
  player.draw(screenBuffer);
  screenBuffer.draw();
  
  setTimeout(gameLoop, 100);
}

Usage Examples

Double-Buffered Animation

const term = require('terminal-kit').terminal;
const termkit = require('terminal-kit');

const screenBuffer = new termkit.ScreenBuffer({
  dst: term,
  width: term.width,
  height: term.height
});

let ballX = 10, ballY = 10;
let velocityX = 1, velocityY = 1;

function animate() {
  // Clear buffer
  screenBuffer.clear();
  
  // Update ball position
  ballX += velocityX;
  ballY += velocityY;
  
  // Bounce off walls
  if (ballX <= 0 || ballX >= term.width - 1) velocityX = -velocityX;
  if (ballY <= 0 || ballY >= term.height - 1) velocityY = -velocityY;
  
  // Draw ball
  screenBuffer.put({
    x: Math.floor(ballX),
    y: Math.floor(ballY),
    attr: { color: 'red' }
  }, '●');
  
  // Update display
  screenBuffer.draw({ delta: true });
  
  setTimeout(animate, 50);
}

term.clear();
animate();

Text Processing with TextBuffer

const term = require('terminal-kit').terminal;
const termkit = require('terminal-kit');

const textBuffer = new termkit.TextBuffer({
  dst: term,
  width: 60,
  height: 20,
  wordWrap: true
});

// Add formatted content
textBuffer.append('^R^+ERROR:^ Failed to connect to server.\n');
textBuffer.append('^Y^+WARNING:^ Connection timeout.\n');
textBuffer.append('^G^+SUCCESS:^ Connected successfully.\n');
textBuffer.append('\n');
textBuffer.append('This is a ^Bblue^ word and this is ^Rred^.\n');
textBuffer.append('**Bold text** and *italic text* are supported.\n');

// Create a scrollable log viewer
let scrollY = 0;

term.grabInput();
term.on('key', (name) => {
  switch (name) {
    case 'UP':
      if (scrollY > 0) scrollY--;
      break;
    case 'DOWN':
      scrollY++;
      break;
    case 'CTRL_C':
      term.releaseInput();
      process.exit();
      break;
  }
  
  term.clear();
  textBuffer.scrollTo(scrollY);
  textBuffer.draw();
});

// Initial render
term.clear();
textBuffer.draw();

HD Graphics Example

const term = require('terminal-kit').terminal;
const termkit = require('terminal-kit');

const hdBuffer = new termkit.ScreenBufferHD({
  dst: term,
  width: 160,
  height: 80
});

// Draw a rainbow gradient
function drawRainbow() {
  for (let x = 0; x < 160; x++) {
    for (let y = 0; y < 80; y++) {
      const hue = (x / 160) * 360;
      const saturation = 1;
      const lightness = 0.5 + 0.3 * Math.sin(y / 80 * Math.PI);
      
      // Convert HSL to RGB
      const chroma = termkit.chroma.hsl(hue, saturation, lightness);
      const [r, g, b] = chroma.rgb();
      
      hdBuffer.setPixel(x, y, { r, g, b, a: 255 });
    }
  }
  
  hdBuffer.draw();
}

// Draw geometric patterns
function drawPattern() {
  hdBuffer.clear();
  
  const centerX = 80;
  const centerY = 40;
  
  for (let angle = 0; angle < 360; angle += 10) {
    const rad = angle * Math.PI / 180;
    const x1 = centerX + Math.cos(rad) * 30;
    const y1 = centerY + Math.sin(rad) * 20;
    const x2 = centerX + Math.cos(rad) * 60;
    const y2 = centerY + Math.sin(rad) * 40;
    
    const color = termkit.chroma.hsl(angle, 1, 0.5).rgb();
    hdBuffer.drawLine(x1, y1, x2, y2, {
      r: color[0], g: color[1], b: color[2], a: 255
    });
  }
  
  hdBuffer.draw();
}

term.clear();
drawPattern();

Install with Tessl CLI

npx tessl i tessl/npm-terminal-kit

docs

buffers-graphics.md

colors-styling.md

document-model.md

index.md

interactive-input.md

terminal-control.md

tile.json