Canvas Widget

Draw pixel-level graphics and patterns in the console

The Canvas widget enables pixel-level drawing in the console, where you can set individual pixels with specific colors to create graphics, patterns, and visualizations.

Screenshot

When to Use

Use Canvas when you need to create custom graphics or visualizations at the pixel level. Common scenarios:

  • Custom data visualizations: Build charts, graphs, or diagrams with precise pixel control
  • Patterns and effects: Generate gradients, textures, or geometric patterns
  • Simple graphics: Draw shapes, lines, or pixel art
  • Algorithm visualization: Show the output of image processing or generation algorithms

For displaying existing images, use CanvasImage instead, which handles image file loading and conversion automatically.

Basic Usage

Create a canvas with specified dimensions and set individual pixels using SetPixel(x, y, color). Pixels use zero-based coordinates starting from the top-left corner.

public static void BasicCanvasExample()
{
    var canvas = new Canvas(16, 8);
  
    // Draw some colored pixels
    for (var x = 0; x < 16; x++)
    {
        canvas.SetPixel(x, 0, Color.Blue);
        canvas.SetPixel(x, 7, Color.Blue);
    }
  
    for (var y = 1; y < 7; y++)
    {
        canvas.SetPixel(0, y, Color.Blue);
        canvas.SetPixel(15, y, Color.Blue);
    }
  
    // Fill the center
    for (var x = 1; x < 15; x++)
    {
        for (var y = 1; y < 7; y++)
        {
            canvas.SetPixel(x, y, Color.Green);
        }
    }
  
    AnsiConsole.Write(canvas);
}

Creating Patterns

Simple Patterns

Use loops to create repeating patterns across the canvas.

public static void CanvasPatternExample()
{
    var canvas = new Canvas(20, 10);
  
    // Create a checkerboard pattern
    for (var y = 0; y < 10; y++)
    {
        for (var x = 0; x < 20; x++)
        {
            var color = (x + y) % 2 == 0 ? Color.Red : Color.Yellow;
            canvas.SetPixel(x, y, color);
        }
    }
  
    AnsiConsole.Write(canvas);
}

Gradients

Create smooth color transitions by calculating pixel colors based on position.

public static void CanvasGradientExample()
{
    var canvas = new Canvas(30, 10);
  
    // Create a horizontal color gradient
    for (var y = 0; y < 10; y++)
    {
        for (var x = 0; x < 30; x++)
        {
            var intensity = (byte)(x * 255 / 29);
            var color = new Color(intensity, 0, (byte)(255 - intensity));
            canvas.SetPixel(x, y, color);
        }
    }
  
    AnsiConsole.Write(canvas);
}

Controlling Size and Scaling

Maximum Width

Use MaxWidth to constrain the rendered canvas width. The canvas automatically scales while maintaining the aspect ratio.

public static void CanvasScalingExample()
{
    var canvas = new Canvas(40, 10);
  
    // Fill with a simple pattern
    for (var y = 0; y < 10; y++)
    {
        for (var x = 0; x < 40; x++)
        {
            canvas.SetPixel(x, y, x < 20 ? Color.Blue : Color.Green);
        }
    }
  
    AnsiConsole.MarkupLine("[yellow]Original size:[/]");
    AnsiConsole.Write(canvas);
  
    AnsiConsole.WriteLine();
    AnsiConsole.MarkupLine("[yellow]With MaxWidth = 20:[/]");
    canvas.MaxWidth = 20;
    AnsiConsole.Write(canvas);
}

Pixel Width

Use PixelWidth to control how many console characters each pixel occupies. Larger values create wider, more visible pixels.

public static void CanvasPixelWidthExample()
{
    var canvas = new Canvas(10, 5);
  
    // Fill with alternating colors
    for (var y = 0; y < 5; y++)
    {
        for (var x = 0; x < 10; x++)
        {
            canvas.SetPixel(x, y, y % 2 == 0 ? Color.Purple : Color.Orange1);
        }
    }
  
    AnsiConsole.MarkupLine("[yellow]PixelWidth = 1:[/]");
    canvas.PixelWidth = 1;
    AnsiConsole.Write(canvas);
  
    AnsiConsole.WriteLine();
    AnsiConsole.MarkupLine("[yellow]PixelWidth = 2 (default):[/]");
    canvas.PixelWidth = 2;
    AnsiConsole.Write(canvas);
  
    AnsiConsole.WriteLine();
    AnsiConsole.MarkupLine("[yellow]PixelWidth = 4:[/]");
    canvas.PixelWidth = 4;
    AnsiConsole.Write(canvas);
}

Disabling Scaling

Set Scale = false to prevent automatic resizing when the canvas exceeds available space. This ensures pixel-perfect rendering but may cause clipping.

public static void CanvasNoScalingExample()
{
    var canvas = new Canvas(30, 8);
  
    // Create a pattern
    for (var y = 0; y < 8; y++)
    {
        for (var x = 0; x < 30; x++)
        {
            if (x % 3 == 0)
            {
                canvas.SetPixel(x, y, Color.Cyan1);
            }
        }
    }
  
    AnsiConsole.MarkupLine("[yellow]With scaling (default):[/]");
    canvas.Scale = true;
    canvas.MaxWidth = 15;
    AnsiConsole.Write(canvas);
  
    AnsiConsole.WriteLine();
    AnsiConsole.MarkupLine("[yellow]Without scaling:[/]");
    canvas.Scale = false;
    AnsiConsole.Write(canvas);
}

Advanced Usage

Custom Visualizations

Combine pixel operations to create custom data visualizations like bar charts or graphs.

public static void CanvasBarVisualizationExample()
{
    var canvas = new Canvas(25, 15);
  
    // Draw bars with different heights
    int[] heights = { 5, 10, 7, 13, 9 };
    var colors = new[] { Color.Red, Color.Green, Color.Blue, Color.Yellow, Color.Purple };
  
    for (var i = 0; i < heights.Length; i++)
    {
        var barX = i * 5;
        var barHeight = heights[i];
  
        // Draw the bar from bottom up
        for (var y = 15 - barHeight; y < 15; y++)
        {
            for (var x = barX; x < barX + 4 && x < 25; x++)
            {
                canvas.SetPixel(x, y, colors[i]);
            }
        }
    }
  
    AnsiConsole.Write(canvas);
}

Drawing Lines

Create line patterns by calculating pixel positions along a path.

public static void CanvasDiagonalLineExample()
{
    var canvas = new Canvas(20, 20);
  
    // Draw diagonal lines
    for (var i = 0; i < 20; i++)
    {
        // Main diagonal
        canvas.SetPixel(i, i, Color.Red);
  
        // Anti-diagonal
        canvas.SetPixel(i, 19 - i, Color.Blue);
    }
  
    // Draw a horizontal line through the middle
    for (var x = 0; x < 20; x++)
    {
        canvas.SetPixel(x, 10, Color.Green);
    }
  
    AnsiConsole.Write(canvas);
}

Complex Compositions

Build sophisticated graphics by combining multiple drawing operations with helper methods.

public static void CanvasComplexPatternExample()
{
    var canvas = new Canvas(40, 20);
  
    // Fill background
    for (var y = 0; y < 20; y++)
    {
        for (var x = 0; x < 40; x++)
        {
            canvas.SetPixel(x, y, Color.Grey11);
        }
    }
  
    // Draw concentric rectangles
    DrawRectangle(canvas, 5, 5, 30, 10, Color.Red);
    DrawRectangle(canvas, 10, 7, 20, 6, Color.Yellow);
    DrawRectangle(canvas, 15, 9, 10, 2, Color.Green);
  
    AnsiConsole.Write(canvas);
}

API Reference

Represents a renderable canvas.

Constructors

Canvas(int width, int height)

Initializes a new instance of the class.

Parameters:

width (int)
The canvas width.
height (int)
The canvas height.

Properties

Height : int

Gets the height of the canvas.

MaxWidth : Nullable<int>

Gets or sets the render width of the canvas.

PixelWidth : int

Gets or sets the pixel width.

Scale : bool

Gets or sets a value indicating whether or not to scale the canvas when rendering.

Width : int

Gets the width of the canvas.

Methods

Canvas SetPixel(int x, int y, Color color)

Sets a pixel with the specified color in the canvas at the specified location.

Parameters:

x (int)
The X coordinate for the pixel.
y (int)
The Y coordinate for the pixel.
color (Color)
The pixel color.

Returns:

The same instance so that multiple calls can be chained.

Extension Methods

IEnumerable<Segment> GetSegments(IAnsiConsole console)

Gets the segments for a renderable using the specified console.

Parameters:

console (IAnsiConsole)
The console.

Returns:

An enumerable containing segments representing the specified .