Documentation
¶
Overview ¶
Package gif provides utilities for creating animated GIF images with a clean, builder-style API. It includes comprehensive support for:
- Frame-by-frame GIF creation with drawing primitives
- Terminal emulation and ANSI escape sequence processing
- Converting terminal recordings (.cast files) to animated GIFs
- TTF and bitmap fonts for text rendering
The package is designed to work seamlessly with the termsession package for converting terminal recordings into animated GIFs, making it ideal for creating documentation and tutorials.
Basic GIF Creation ¶
Create an animated GIF by building frames with drawing operations:
g := gif.New(100, 100)
for i := 0; i < 10; i++ {
g.AddFrame(func(f *gif.Frame) {
f.Fill(gif.White)
f.FillCircle(50, 50+i*3, 10, gif.Red)
})
}
g.Save("animation.gif")
Custom Palettes ¶
GIFs support up to 256 colors per frame. Create custom palettes:
palette := gif.Palette{gif.White, gif.Black, gif.RGB(255, 0, 0)}
g := gif.NewWithPalette(100, 100, palette)
Terminal Recording to GIF ¶
Convert asciinema recordings to animated GIFs:
opts := gif.DefaultCastOptions()
opts.FontSize = 14
opts.FPS = 10
g, err := gif.RenderCast("recording.cast", opts)
if err != nil {
log.Fatal(err)
}
g.Save("demo.gif")
Terminal Emulation ¶
Process raw terminal output with ANSI escape sequences:
emulator := gif.NewEmulator(80, 24)
emulator.ProcessOutput("\x1b[31mHello\x1b[0m World")
renderer := gif.NewTerminalRenderer(emulator.Screen(), 8)
renderer.RenderFrame(10)
renderer.Save("terminal.gif")
Drawing Primitives ¶
The Frame type provides various drawing operations:
- Fill, FillRect, FillCircle: Fill areas with color
- DrawLine, DrawRect, DrawCircle: Draw outlines
- SetPixel, SetPixelIndex: Set individual pixels
All drawing operations handle bounds checking automatically.
Example ¶
Example demonstrates creating a simple animated GIF.
// Create a 100x100 pixel GIF
g := New(100, 100)
// Add 10 frames showing a moving circle
for i := 0; i < 10; i++ {
g.AddFrame(func(f *Frame) {
f.Fill(White)
f.FillCircle(20+i*8, 50, 10, Red)
})
}
// Save to file
if err := g.Save("animation.gif"); err != nil {
fmt.Printf("Error: %v\n", err)
}
Index ¶
- Constants
- Variables
- func DrawBitmapChar(f *Frame, px, py int, char rune, fg color.Color, font BitmapFont)
- func RGB(r, g, b uint8) color.RGBA
- func RGBA(r, g, b, a uint8) color.RGBA
- type BitmapFont
- type CastInfo
- type CastOptions
- type Emulator
- type FontFace
- func (ff *FontFace) Ascent() int
- func (ff *FontFace) CellHeight() int
- func (ff *FontFace) CellWidth() int
- func (ff *FontFace) Close() error
- func (ff *FontFace) DrawChar(img draw.Image, px, py int, char rune, fg color.Color)
- func (ff *FontFace) DrawString(img draw.Image, px, py int, s string, fg color.Color)
- type Frame
- func (f *Frame) DrawCircle(cx, cy, r int, c color.Color)
- func (f *Frame) DrawLine(x0, y0, x1, y1 int, c color.Color)
- func (f *Frame) DrawRect(x, y, w, h int, c color.Color)
- func (f *Frame) Fill(c color.Color)
- func (f *Frame) FillCircle(cx, cy, r int, c color.Color)
- func (f *Frame) FillRect(x, y, w, h int, c color.Color)
- func (f *Frame) Height() int
- func (f *Frame) Image() *image.Paletted
- func (f *Frame) SetPixel(x, y int, c color.Color)
- func (f *Frame) SetPixelIndex(x, y int, index uint8)
- func (f *Frame) Width() int
- type GIF
- func (g *GIF) AddFrame(draw func(*Frame)) *GIF
- func (g *GIF) AddFrameWithDelay(draw func(*Frame), delay int) *GIF
- func (g *GIF) AddImage(img *image.Paletted, delay int) *GIF
- func (g *GIF) Bytes() ([]byte, error)
- func (g *GIF) Encode(w io.Writer) error
- func (g *GIF) FrameCount() int
- func (g *GIF) Height() int
- func (g *GIF) Save(filename string) error
- func (g *GIF) SetLoopCount(count int) *GIF
- func (g *GIF) Width() int
- type Palette
- type RendererOptions
- type TerminalCell
- type TerminalRenderer
- type TerminalScreen
Examples ¶
Constants ¶
const ( FontWidth = 8 // Default font width FontHeight = 8 // Default font height )
Bitmap font dimension constants for backward compatibility.
Variables ¶
var ( // BitmapFont8x8 is the classic 8x8 pixel bitmap font, suitable for // compact displays and retro aesthetics. BitmapFont8x8 = BitmapFont{Width: 8, Height: 8} // BitmapFont8x16 is a taller 8x16 pixel font that provides better // readability for terminal rendering. This is the recommended default // for bitmap font usage. BitmapFont8x16 = BitmapFont{Width: 8, Height: 16} )
Predefined bitmap fonts with different sizes.
var ( Black = color.RGBA{0, 0, 0, 255} White = color.RGBA{255, 255, 255, 255} Red = color.RGBA{255, 0, 0, 255} Green = color.RGBA{0, 255, 0, 255} Blue = color.RGBA{0, 0, 255, 255} Yellow = color.RGBA{255, 255, 0, 255} Cyan = color.RGBA{0, 255, 255, 255} Magenta = color.RGBA{255, 0, 255, 255} Transparent = color.RGBA{0, 0, 0, 0} )
Common colors for convenience.
DefaultPalette provides a basic palette with common colors.
Functions ¶
func DrawBitmapChar ¶
DrawBitmapChar draws a single character using a bitmap font at the specified pixel position (px, py) on a GIF frame. The character is drawn in the foreground color, with the frame's existing background showing through empty pixels.
Supported fonts:
- BitmapFont8x8: Classic 8x8 pixel font
- BitmapFont8x16: Taller 8x16 font with better readability
Characters outside the ASCII printable range (32-126) are rendered as block characters.
Example:
g := gif.New(100, 20)
g.AddFrame(func(f *gif.Frame) {
f.Fill(gif.Black)
x := 5
for _, ch := range "Hello" {
gif.DrawBitmapChar(f, x, 5, ch, gif.White, gif.BitmapFont8x8)
x += 8
}
})
Types ¶
type BitmapFont ¶
type BitmapFont struct {
Width int // Character cell width in pixels
Height int // Character cell height in pixels
}
BitmapFont represents a fixed-width bitmap font with specific dimensions. Bitmap fonts are faster to render than TTF fonts and require no external dependencies, but offer lower visual quality.
type CastInfo ¶
type CastInfo struct {
Width int // Terminal width in columns
Height int // Terminal height in rows
Duration float64 // Total recording duration in seconds
EventCount int // Number of events in the recording
Title string // Recording title from metadata
Timestamp int64 // Unix timestamp when recorded
}
CastInfo contains metadata about a terminal recording without rendering it. This is useful for inspecting recording properties before conversion.
func GetCastInfo ¶
GetCastInfo extracts metadata from a .cast file without rendering it to a GIF. This is useful for displaying recording information or making decisions about rendering options.
Example:
info, err := gif.GetCastInfo("demo.cast")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Recording: %dx%d, %.1fs duration, %d events\n",
info.Width, info.Height, info.Duration, info.EventCount)
type CastOptions ¶
type CastOptions struct {
Cols int // Override terminal columns (0 = use recording dimensions)
Rows int // Override terminal rows (0 = use recording dimensions)
Speed float64 // Playback speed multiplier (1.0 = normal, 2.0 = double speed)
MaxIdle float64 // Maximum idle time between events in seconds (default: 2.0, prevents long pauses)
FPS int // Target frames per second for output GIF (default: 10)
Padding int // Padding around terminal content in pixels (default: 8)
Font *FontFace // Custom TTF/OTF font (nil = use default Inconsolata)
FontSize float64 // Font size in points when using default font (default: 14)
UseBitmap bool // Force bitmap font instead of TTF (faster but lower quality)
}
CastOptions configures the conversion of terminal recordings (.cast files) to animated GIFs. It provides control over dimensions, timing, rendering quality, and font selection.
Use DefaultCastOptions to get sensible defaults, then customize as needed:
opts := gif.DefaultCastOptions() opts.FontSize = 16 opts.FPS = 15 opts.Speed = 2.0 // Double speed playback
func DefaultCastOptions ¶
func DefaultCastOptions() CastOptions
DefaultCastOptions returns sensible defaults for cast conversion.
type Emulator ¶
type Emulator struct {
// contains filtered or unexported fields
}
Emulator interprets ANSI escape sequences and maintains terminal screen state. It processes raw terminal output (including control characters and escape sequences) and updates a TerminalScreen buffer that can be rendered to GIF frames.
The emulator supports:
- Standard ANSI color codes (30-37, 40-47, 90-97, 100-107)
- 256-color mode (ESC[38;5;Nm and ESC[48;5;Nm)
- True color / 24-bit RGB (ESC[38;2;R;G;Bm and ESC[48;2;R;G;Bm)
- Cursor movement (CSI sequences: H, A, B, C, D, E, F, G, d)
- Screen clearing (CSI J and K sequences)
- Common control characters (newline, carriage return, backspace, tab)
Example:
emulator := gif.NewEmulator(80, 24)
emulator.ProcessOutput("Hello \x1b[31mRed\x1b[0m World\n")
emulator.ProcessOutput("Line 2")
renderer := gif.NewTerminalRenderer(emulator.Screen(), 8)
renderer.RenderFrame(10)
renderer.Save("output.gif")
func NewEmulator ¶
NewEmulator creates a new terminal emulator with the specified dimensions. The cols and rows parameters define the terminal size in character cells. Standard terminal sizes include 80x24 (classic), 80x25 (DOS), and 132x24.
func (*Emulator) ProcessOutput ¶
ProcessOutput processes raw terminal output containing printable characters, control characters, and ANSI escape sequences. It updates the screen state, cursor position, and text attributes accordingly.
Supported sequences include:
- CSI sequences (ESC[...): cursor movement, colors, clearing
- OSC sequences (ESC]...): ignored (window title, etc.)
- Control characters: \n, \r, \b, \t, and printable ASCII
func (*Emulator) Reset ¶
func (e *Emulator) Reset()
Reset clears the screen and resets all state to initial values. This includes clearing all text, resetting colors to defaults (white on black), and moving the cursor to the home position (0, 0).
func (*Emulator) Resize ¶
Resize changes the terminal dimensions, preserving as much existing content as possible. If the new size is smaller, content outside the bounds is lost. If larger, new areas are filled with spaces using default colors.
func (*Emulator) Screen ¶
func (e *Emulator) Screen() *TerminalScreen
Screen returns the current terminal screen state, which contains the character cells, colors, and cursor position. The returned screen can be rendered to GIF frames using a TerminalRenderer.
func (*Emulator) Write ¶
Write implements io.Writer, allowing the emulator to be used as a writer for terminal output. It processes the data through ProcessOutput and always returns the full length written with no error.
This makes Emulator compatible with any code that writes to an io.Writer, such as terminal applications or command execution output.
type FontFace ¶
type FontFace struct {
// contains filtered or unexported fields
}
FontFace wraps a TrueType or OpenType font for high-quality text rendering to images. It maintains metrics for monospace character cells, making it suitable for terminal and grid-based text rendering.
FontFace calculates cell dimensions automatically based on the font metrics, ensuring consistent spacing for terminal emulation and text layouts.
func LoadDefaultFont ¶
LoadDefaultFont loads the embedded Inconsolata monospace font at the specified size in points. Inconsolata is a clean, highly readable monospace font ideal for terminal rendering and code display.
This is the recommended font for terminal GIF rendering, as it provides excellent readability and proper monospace character metrics.
Example:
font, err := gif.LoadDefaultFont(14)
if err != nil {
log.Fatal(err)
}
defer font.Close()
// Use with terminal renderer
opts := gif.DefaultRendererOptions()
opts.Font = font
renderer := gif.NewTerminalRendererWithOptions(screen, opts)
func LoadFontFromBytes ¶
LoadFontFromBytes loads a TrueType (TTF) or OpenType (OTF) font from raw bytes at the specified size in points. The font is configured with standard 72 DPI and full hinting for best rendering quality.
This function is useful for embedding custom fonts or loading fonts from non-standard locations.
Example:
fontData, err := os.ReadFile("custom-font.ttf")
if err != nil {
log.Fatal(err)
}
font, err := gif.LoadFontFromBytes(fontData, 14)
if err != nil {
log.Fatal(err)
}
defer font.Close()
func (*FontFace) Ascent ¶
Ascent returns the font ascent (distance from baseline to top of tallest glyph) in pixels. This is used internally for positioning characters correctly on the baseline.
func (*FontFace) CellHeight ¶
CellHeight returns the height of a single character cell in pixels. This includes the space needed for ascenders, descenders, and line spacing. This value is used to calculate total image height for terminal rendering.
func (*FontFace) CellWidth ¶
CellWidth returns the width of a single character cell in pixels. For monospace fonts, all characters have the same width. This value is used to calculate total image width for terminal rendering.
func (*FontFace) Close ¶
Close releases resources associated with the font face. While most font faces don't require explicit cleanup, this method is provided for completeness and should be called when the font is no longer needed, typically using defer.
Example:
font, err := gif.LoadDefaultFont(14)
if err != nil {
log.Fatal(err)
}
defer font.Close()
func (*FontFace) DrawChar ¶
DrawChar draws a single character at the specified pixel position on the image. The position (px, py) is the top-left corner of the character cell. The character is drawn in the foreground color with proper baseline alignment.
Space characters and null runes are not drawn (optimization).
func (*FontFace) DrawString ¶
DrawString draws a complete string at the specified pixel position. The position (px, py) is the top-left corner of the first character cell. Characters advance horizontally according to the font's advance width.
This method is primarily used internally by TerminalRenderer but can be used directly for custom text rendering needs.
type Frame ¶
type Frame struct {
// contains filtered or unexported fields
}
Frame represents a single frame being drawn.
func (*Frame) DrawCircle ¶
DrawCircle draws a circle outline using the midpoint algorithm.
Example ¶
ExampleFrame_DrawCircle demonstrates drawing circles.
g := New(200, 200)
g.AddFrame(func(f *Frame) {
f.Fill(White)
// Draw concentric circles
for r := 20; r <= 100; r += 20 {
f.DrawCircle(100, 100, r, Black)
}
})
g.Save("circles.gif")
func (*Frame) DrawLine ¶
DrawLine draws a line from (x0, y0) to (x1, y1) using Bresenham's algorithm.
Example ¶
ExampleFrame_DrawLine demonstrates drawing lines on a frame.
g := New(200, 200)
g.AddFrame(func(f *Frame) {
f.Fill(White)
// Draw a grid
for i := 0; i <= 200; i += 20 {
f.DrawLine(i, 0, i, 200, RGB(200, 200, 200))
f.DrawLine(0, i, 200, i, RGB(200, 200, 200))
}
// Draw diagonal lines
f.DrawLine(0, 0, 200, 200, Red)
f.DrawLine(200, 0, 0, 200, Blue)
})
g.Save("lines.gif")
func (*Frame) FillCircle ¶
FillCircle fills a circle.
func (*Frame) SetPixel ¶
SetPixel sets a pixel to the given color. The color must be in the palette or it will be matched to the nearest color.
func (*Frame) SetPixelIndex ¶
SetPixelIndex sets a pixel using a palette index directly. This is faster than SetPixel when you know the index.
type GIF ¶
type GIF struct {
// contains filtered or unexported fields
}
GIF represents an animated GIF being constructed.
func New ¶
New creates a new GIF with the specified dimensions and the default palette. Dimensions must be positive; values less than 1 are clamped to 1.
Example ¶
ExampleNew demonstrates creating a basic GIF with the default palette.
g := New(200, 100)
g.AddFrame(func(f *Frame) {
f.Fill(White)
f.FillRect(50, 25, 100, 50, Blue)
f.DrawRect(49, 24, 102, 52, Black)
})
g.Save("simple.gif")
func NewWithPalette ¶
NewWithPalette creates a new GIF with a custom palette. Dimensions must be positive; values less than 1 are clamped to 1. Palette must have 1-256 colors; empty palettes use DefaultPalette, and palettes exceeding 256 colors are truncated.
Example ¶
ExampleNewWithPalette demonstrates creating a GIF with a custom palette.
// Create a custom palette with grayscale colors
palette := Grayscale(16)
g := NewWithPalette(100, 100, palette)
// Create frames with different shades
for i := 0; i < 16; i++ {
g.AddFrame(func(f *Frame) {
f.Fill(palette[i])
})
}
g.Save("grayscale.gif")
func RenderCast ¶
func RenderCast(castFile string, opts CastOptions) (*GIF, error)
RenderCast converts an asciinema .cast file (terminal recording) to an animated GIF. It processes the terminal output events, applies ANSI escape sequences, and renders each frame with proper timing.
The function handles:
- ANSI color codes (16-color, 256-color, and true color)
- Cursor movement and text positioning
- Screen clearing and line editing
- Playback speed adjustment and idle time limiting
Example:
opts := gif.DefaultCastOptions()
opts.FontSize = 16
opts.Speed = 1.5 // Play at 1.5x speed
g, err := gif.RenderCast("demo.cast", opts)
if err != nil {
log.Fatal(err)
}
g.Save("demo.gif")
The returned GIF can be saved with Save() or encoded with Encode().
func RenderCastEvents ¶
func RenderCastEvents(header *termsession.RecordingHeader, events []termsession.RecordingEvent, opts CastOptions) (*GIF, error)
RenderCastEvents converts pre-loaded terminal recording events to an animated GIF. This function is useful when you already have the header and events in memory, or when you want to filter or modify events before rendering.
See RenderCast for higher-level usage that loads from a file directly.
func (*GIF) AddFrame ¶
AddFrame adds a new frame with the default delay (100ms). The draw function is called to render the frame content.
Example ¶
ExampleGIF_AddFrame demonstrates adding frames with drawing operations.
g := New(150, 150)
// Add frames showing geometric shapes
g.AddFrame(func(f *Frame) {
f.Fill(White)
f.FillCircle(75, 75, 50, Red)
})
g.AddFrame(func(f *Frame) {
f.Fill(White)
f.FillRect(25, 25, 100, 100, Blue)
})
g.AddFrame(func(f *Frame) {
f.Fill(White)
f.DrawLine(0, 0, 150, 150, Green)
f.DrawLine(150, 0, 0, 150, Green)
})
g.Save("shapes.gif")
func (*GIF) AddFrameWithDelay ¶
AddFrameWithDelay adds a new frame with a custom delay. Delay is in 100ths of a second (e.g., 10 = 100ms). Negative delays are clamped to 0.
func (*GIF) AddImage ¶
AddImage adds an existing paletted image as a frame. The image is added directly without palette conversion; ensure the image uses a compatible palette or colors may not display correctly. Nil images are ignored. Negative delays are clamped to 0.
func (*GIF) FrameCount ¶
FrameCount returns the number of frames added so far.
func (*GIF) SetLoopCount ¶
SetLoopCount sets the number of times the animation should loop. 0 means loop forever, -1 means no loop (play once).
Example ¶
ExampleGIF_SetLoopCount demonstrates controlling animation looping.
g := New(100, 50)
// Set to loop 3 times (not infinite)
g.SetLoopCount(3)
for i := 0; i < 5; i++ {
g.AddFrameWithDelay(func(f *Frame) {
f.Fill(White)
f.FillCircle(10+i*20, 25, 10, Red)
}, 20) // 200ms delay
}
g.Save("limited-loop.gif")
type Palette ¶
Palette is a slice of colors used for GIF frames. GIFs support up to 256 colors per frame.
func Grayscale ¶
Grayscale creates a grayscale palette with n shades from black to white.
Example ¶
ExampleGrayscale demonstrates creating a grayscale palette.
// Create a 32-shade grayscale palette
palette := Grayscale(32)
g := NewWithPalette(320, 100, palette)
g.AddFrame(func(f *Frame) {
// Draw a gradient bar showing all shades
for i := 0; i < 32; i++ {
f.FillRect(i*10, 0, 10, 100, palette[i])
}
})
g.Save("gradient.gif")
func Terminal256 ¶ added in v0.0.7
func Terminal256() Palette
Terminal256 creates the standard xterm 256-color palette used by modern terminal emulators. This palette provides excellent coverage for terminal rendering with anti-aliased text, as it includes:
- Colors 0-15: Standard 16 ANSI colors (8 normal + 8 bright)
- Colors 16-231: 6×6×6 RGB color cube (216 colors)
- Colors 232-255: 24-shade grayscale ramp
This is the recommended palette for terminal GIF rendering, as the color cube provides smooth intermediate shades for anti-aliased font edges.
Example:
palette := gif.Terminal256() g := gif.NewWithPalette(800, 600, palette)
Example ¶
ExampleTerminal256 demonstrates creating a terminal-style palette.
// Use the standard xterm 256-color palette for terminal rendering
palette := Terminal256()
g := NewWithPalette(400, 300, palette)
g.AddFrame(func(f *Frame) {
// Dark background like a terminal
f.Fill(palette[0]) // Black
// The palette includes all colors needed for anti-aliased text
})
g.Save("terminal.gif")
type RendererOptions ¶
type RendererOptions struct {
Font *FontFace // Custom TTF/OTF font (nil = use default Inconsolata or bitmap)
FontSize float64 // Font size in points for default TTF (default: 14)
UseBitmap bool // Force bitmap font instead of TTF (faster, lower quality)
BitmapFont BitmapFont // Which bitmap font to use when UseBitmap=true (default: 8x16)
Padding int // Padding in pixels around terminal content (default: 8)
}
RendererOptions configures how a TerminalRenderer converts terminal screens to GIF frames. It provides control over font selection, sizing, and layout.
Use DefaultRendererOptions() to get sensible defaults, then customize:
opts := gif.DefaultRendererOptions() opts.FontSize = 16 opts.Padding = 10 renderer := gif.NewTerminalRendererWithOptions(screen, opts)
func DefaultRendererOptions ¶
func DefaultRendererOptions() RendererOptions
DefaultRendererOptions returns sensible defaults for terminal rendering.
type TerminalCell ¶
type TerminalCell struct {
Char rune // The Unicode character displayed in this cell
FG color.Color // Foreground (text) color
BG color.Color // Background color
}
TerminalCell represents a single character cell in a terminal screen, including the character itself and its foreground and background colors.
type TerminalRenderer ¶
type TerminalRenderer struct {
// contains filtered or unexported fields
}
TerminalRenderer converts a TerminalScreen buffer into animated GIF frames. It handles text rendering using either TTF fonts (for high quality) or bitmap fonts (for speed and simplicity), and manages the GIF creation process.
The renderer calculates pixel dimensions based on the terminal size and selected font, then renders each frame by drawing character cells with their foreground and background colors.
Example:
screen := gif.NewTerminalScreen(80, 24)
screen.WriteString("Hello World", gif.White, gif.Black)
renderer := gif.NewTerminalRenderer(screen, 8)
renderer.RenderFrame(10) // Add frame with 100ms delay
renderer.Save("output.gif")
func NewTerminalRenderer ¶
func NewTerminalRenderer(screen *TerminalScreen, padding int) *TerminalRenderer
NewTerminalRenderer creates a renderer for the given terminal screen using the default TTF font (Inconsolata) for best rendering quality. The padding parameter specifies extra pixels around the terminal content.
This is a convenience constructor that uses DefaultRendererOptions with the specified padding. For more control over font selection and rendering options, use NewTerminalRendererWithOptions.
func NewTerminalRendererWithOptions ¶
func NewTerminalRendererWithOptions(screen *TerminalScreen, opts RendererOptions) *TerminalRenderer
NewTerminalRendererWithOptions creates a renderer with full control over rendering options. This allows customizing font selection (TTF vs bitmap), font size, and padding.
The renderer automatically calculates pixel dimensions based on the terminal size and selected font metrics.
func (*TerminalRenderer) Bytes ¶
func (tr *TerminalRenderer) Bytes() ([]byte, error)
Bytes returns the GIF animation as a byte slice, suitable for writing to HTTP responses or other byte-oriented outputs. This is a convenience method that calls Bytes on the underlying GIF object.
func (*TerminalRenderer) GIF ¶
func (tr *TerminalRenderer) GIF() *GIF
GIF returns the underlying GIF object being constructed. This allows access to the GIF for additional manipulation or encoding options.
func (*TerminalRenderer) RenderFrame ¶
func (tr *TerminalRenderer) RenderFrame(delay int)
RenderFrame captures the current terminal screen state and adds it as a frame to the GIF animation. The delay parameter specifies how long to display this frame, measured in hundredths of a second (e.g., 10 = 100ms, 50 = 500ms).
Call this method multiple times as the terminal screen changes to create an animation showing the terminal session progression.
func (*TerminalRenderer) Save ¶
func (tr *TerminalRenderer) Save(filename string) error
Save writes the rendered GIF animation to a file. This is a convenience method that calls Save on the underlying GIF object.
func (*TerminalRenderer) SetLoopCount ¶
func (tr *TerminalRenderer) SetLoopCount(count int) *TerminalRenderer
SetLoopCount sets how many times the GIF animation should loop. Use 0 for infinite looping (default), -1 to play once, or a positive number for a specific repeat count. Returns the renderer for method chaining.
type TerminalScreen ¶
type TerminalScreen struct {
Width int // Screen width in columns (character cells)
Height int // Screen height in rows (character cells)
Cells [][]TerminalCell // 2D array of cells [row][column]
CursorX int // Current cursor column (0-indexed)
CursorY int // Current cursor row (0-indexed)
DefaultFG color.Color // Default foreground color (typically white)
DefaultBG color.Color // Default background color (typically black)
}
TerminalScreen represents a virtual terminal screen buffer with character cells arranged in rows and columns. It maintains the complete state needed to render terminal output, including all characters, their colors, and the cursor position.
The screen uses (0,0) as the top-left position, with X increasing to the right and Y increasing downward.
func NewTerminalScreen ¶
func NewTerminalScreen(cols, rows int) *TerminalScreen
NewTerminalScreen creates a new terminal screen buffer with the specified dimensions. All cells are initialized with space characters and default colors.
func (*TerminalScreen) Clear ¶
func (ts *TerminalScreen) Clear()
Clear clears the entire screen, filling all cells with spaces using the default foreground and background colors. The cursor is reset to position (0,0).
func (*TerminalScreen) MoveCursor ¶
func (ts *TerminalScreen) MoveCursor(x, y int)
MoveCursor moves the cursor to the specified position, clamping coordinates to valid screen bounds. Negative values are clamped to 0, and values beyond the screen dimensions are clamped to the maximum valid position.
func (*TerminalScreen) SetCell ¶
func (ts *TerminalScreen) SetCell(x, y int, char rune, fg, bg color.Color)
SetCell sets the character and colors for a cell at the specified position. If the position is out of bounds, the call is silently ignored. Nil colors are replaced with the default foreground or background colors.
func (*TerminalScreen) WriteString ¶
func (ts *TerminalScreen) WriteString(s string, fg, bg color.Color)
WriteString writes a string to the screen starting at the current cursor position. The cursor advances as characters are written. Newlines (\n) move the cursor to the start of the next line. Carriage returns (\r) move to the start of the current line. The screen scrolls up if text extends beyond the bottom row.