Skip to content

Drawing

Ryan A edited this page Jan 19, 2022 · 2 revisions

Drawing using SimulationFramework is an easy and straightforward process. The first thing needed to begin is an ICanvas object. The OnRender() method on Simulation provides a canvas, or you can create one using ISurface.OpenCanvas() (the surface can be obtained using Graphics.CreateSurface()).

// create a 128x128 surface
var surface = Graphics.CreateSurface(128, 128);
using (var canvas = surface.OpenCanvas())
{
    // clear out surface to red
    surface.Clear(Color.Red);
}
// the surface can be drawn elsewhere now!

To start drawing shapes, just call methods on the canvas. Each method which performs drawing takes a few parameters and has many overloads for usability.

public override void OnRender(ICanvas canvas)
{
    // draws a 50x50 orange square at (100, 100)
    canvas.DrawRect((100,100), (50,50), Color.Orange);
}

Note: Vector2 integrates with tuples; You can define vectors using tuples: Vector2 vector = (1, 2);.

Using Color

The Color struct represents an 32-bit RGBA color. Colors can be cast from byte tuples with 3 or 4 elements (RGB or RGBA) or just a 32-bit uint.

Using Alignment

Most draw methods on ICanvas have a parameter named Alignment. This parameter specifies where on the shape the point passed to the function lies. For example, Alignment.Center means that the point passed to the function is where the center of the shape lies, and Alignment.TopRight means the provided point is at the top-right corner of the shape. Usually, alignment is optional and defaults to either Alignment.TopLeft or Alignment.Center.

Using DrawMode

Shapes can be filled, filled with a gradient, or just outlined. This can be configured using ICanvas.SetDrawMode and the DrawMode enum. The DrawMode has the following values, each of which correspond to a style of shape rendering:

  • Fill - Fill in the shape with the color provided to the function.
  • Border - Draw the outline of the shape with the color provided to the function and the width set by ICanvas.SetStrokeWidth.
  • Gradient - Fill in the shape with the current gradient (set using ICanvas.SetGradientLinear and ICanvas.SetGradientRadial), unless the current GradientTileMode is GradientTileMode.Stop. In that case, any area inside the shape and the gradient are filled with the gradient, and anywhere in the shape outside the gradient is filled with the color provided to the draw function.
public override void OnRender(ICanvas canvas)
{
    canvas.SetDrawMode(DrawMode.Fill);
    canvas.DrawRect(10, 10, 50, 50, Color.Green);

    canvas.SetDrawMode(DrawMode.Border);
    canvas.DrawRect(70, 10, 50, 50, Color.Red);
}

Gradients

SimulationFramework supports linear and radial gradients. Both are defined by some positioning values, and a collection of GradientStop values. A GradientStop is a position and a Color, and the collection of them defines the colors along the gradient and where they lie along it. A GradientStop's position ranges from 0 to 1, and places a color between the two points of the gradient. For a linear gradient, the two points are its start and end points. For a radial gradient, the two points are the its center and its radius.

To draw a gradient, first set the canvas's DrawMode to DrawMode.Gradient. Next, use ICanvas.SetGradientLinear and ICanvas.SetGradientRadial to set the current gradient of the canvas. Finally, draw a shape and it will be filled using the gradient.

public override void OnRender(ICanvas canvas)
{
    canvas.SetDrawMode(DrawMode.Gradient);
    canvas.SetGradientRadial((100, 100), 50, Color.Red, Color.Green); // Color can be cast to GradientStop.
    canvas.DrawRect(100, 100, 100, 100, Color.Black, Alignment.Center);
}

Relative gradients

Relative gradients make use of the Alignment enum and an offset to dynamically update the gradient's position based upon the shapes they are being used to draw. To set a relative gradient, use the overloads of ICanvas.SetGradientLinear and ICanvas.SetGradientRadial which accept Alignment values instead of absolute positions.

public override void OnRender(ICanvas canvas)
{
    // draw using a gradient
    canvas.SetDrawMode(DrawMode.Gradient);

    // set a relative gradient.
    canvas.SetGradientRadial(Alignment.TopCenter, 50, Color.Red, Color.Green);

    // no matter what shape we draw the gradient will be located at the top-center point of that shape's bounding box.
    canvas.DrawRect(100, 100, 100, 100, Color.Black, Alignment.Center);
    canvas.DrawRect(200, 200, 100, 100, Color.Black, Alignment.Center);
    canvas.DrawRect(300, 400, 100, 100, Color.Black, Alignment.Center);
}

Graphics Backends

Currently, only the SkiaSharp backend is implemented, but there are plans for direct2d and possible some 3D APIs in the future.