Turtle graphics library in Blazor using the HTML canvas tag
Introduction
The Turtle graphics libraries, first introduced in the Logo programming language are useful tools to teach programming principals to children and novice programmers. With it, you can explore these four concepts:
- Loops
for
,foreach
,do/while
,while
- Conditions
if/else
- Functions/Methods
- Recursion
Getting Started - Creating a Blazor Turtle Graphics App
Create a new Blazor application.
Install the TurtleGraphics.BlazorCanvas
NuGet package .
In your index.html
file (WebAssembly Apps) or _Host.cshtml
(Server Apps) file, place a reference to the Blazor.Extensions.Canvas
library script file:
<script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script>
Then, in your _Imports.razor
file add the following using entry:
@using TurtleGraphics.BlazorCanvas
Lastly, we’ll register the TurtleJsInterop
as a service in Program.cs
.
public class Program
{
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddScoped(
sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
builder.Services.AddScoped<TurtleJsInterop>();
await builder.Build().RunAsync();
}
}
In the component/page where you want to place the canvas element, add a
<Turtle>
component. Make sure to set the @ref
to a field on your component.
For example, in your Index.razor
page,
@page "/"
<Turtle @ref="_turtle" Width="600" Height="400" />
@code {
private Turtle _turtle;
}
Here is a demo running as a Blazor WebAssembly application
Here is the code from these few examples:
Triangle
private async Task Triangle() { _turtle.PenSize = 1; await _turtle.Rotate(30); _turtle.PenColor = Color.Black; _turtle.Delay = 150; DrawTriangle(100); } private async Task DrawTriangle(int length) { for (int i = 0; i < 3; i++) { await _turtle.Forward(length); await _turtle.Rotate(120); } }
Green star
private async Task GreenStar() { _turtle.Delay = 200; _turtle.PenColor = Color.Green; for (int i = 0; i < 5; i++) { await _turtle.Forward(100); await _turtle.Rotate(144); } }
Spiral
private async Task Spiral() { _turtle.Delay = 100; _turtle.PenColor = Color.DarkGreen; for (int i = 0; i < 20; i++) { await _turtle.Forward(i * 5); await _turtle.Rotate(60); } }
Color wheel
private async Task ColorWheel() { _turtle.PenSize = 4; _turtle.Delay = 10; var rand = new Random(); for (int i = 0; i < 36; i++) { // System.Drawing.KnownColor: only use range from `28` to `167` _turtle.PenColor = Color.FromKnownColor((KnownColor)rand.Next(28, 167)); _turtle.PenUp(); await _turtle.Forward(65); _turtle.PenDown(); await _turtle.Forward(65); await _turtle.Backward(65); await _turtle.Rotate(170); } }
Sierpiński triangle (a Triforce)
private async Task DrawTriforce() { // ▲ // ▲ ▲ int length = 100; await _turtle.Rotate(30); _turtle.PenColor = Color.Gold; _turtle.Delay = 150; await DrawTriangle(length / 2); await _turtle.Forward(length / 2); await DrawTriangle(length / 2); await _turtle.Rotate(120); await _turtle.Forward(length / 2); await _turtle.Rotate(-120); await DrawTriangle(length / 2); await _turtle.Rotate(-120); await _turtle.Forward(length / 2); await _turtle.Rotate(120); }
Circle
private async Task DrawCircle() { _turtle.PenColor = Color.DarkViolet; _turtle.Delay = 10; for (int i = 0; i < 36; i++) { await _turtle.Forward(10); await _turtle.Rotate(10); } }
TurtleGraphics.BlazorCanvas - Developer’s Reference
Forward(distance)
- moves the turtle forward in the current direction by the specified distance. If the pen is down, the turtle draws a line from the current to the new position, otherwise it just moves without leaving a track.Backward(distance)
- moves the turtle in backward direction and draws a line if the pen is down.MoveTo(x, y)
- moves the turtle to the specified position and draws a line if the pen is down.Rotate(angle)
- rotates the turtle relatively to the current direction. The rotation angle is given in degrees (e.g. 45, -30, 315, …).RotateTo(angle)
- rotates the turtle to the specified angle in degrees (e.g. 0, 45, 180, 315, …).PenUp()
- moves the pen up (makes further moves invisible). Further calls toForward(distance)
/Backward(distance)
/MoveTo(x, y)
will move the turtle without drawing a line.PenDown()
- moves the pen down (makes further moves visible). Further calls toForward(distance)
/Backward(distance)
/MoveTo(x, y)
will draw a line from the current to the new position.X
- gets / sets the current turtle horizontal position. The initial turtle position is the screen center {0, 0}. Increasing X will move the turtle right.Y
- gets / sets the current turtle vertical position. The initial turtle position is the screen center {0, 0}. Increasing Y will move the turtle up.Angle
- gets / sets the current turtle direction (angle in degrees). The value of 0 means up, 90 means right, 180 means down and 270 means left. TheAngle
is always kept in the range (0…360). Initially the angle is 0.PenColor
- gets / sets the color of the pen. The default pen color is “blue”.PenSize
- gets / sets the size of the pen (in pixels). The default pen size is 7.PenVisible
- gets / sets the visibility of the pen. The default pen size is true. True means the pen is down (draws a line when the turtle moves). False means the pen is up (no line is drawn when the turtle moves).ShowTurtle
- gets / sets whether the turtle is visible. By default it is visible.Delay
- gets / sets the turtle delay in milliseconds after moving / rotating. By default the delay is 0 (no delay). Setting the delay to 100-300 will simulate a pleasant “animation effect”.Delay
is preserved afterReset()
.