Blazor.Extensions.Canvas 1.1.1

Prefix Reserved
dotnet add package Blazor.Extensions.Canvas --version 1.1.1                
NuGet\Install-Package Blazor.Extensions.Canvas -Version 1.1.1                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Blazor.Extensions.Canvas" Version="1.1.1" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Blazor.Extensions.Canvas --version 1.1.1                
#r "nuget: Blazor.Extensions.Canvas, 1.1.1"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install Blazor.Extensions.Canvas as a Cake Addin
#addin nuget:?package=Blazor.Extensions.Canvas&version=1.1.1

// Install Blazor.Extensions.Canvas as a Cake Tool
#tool nuget:?package=Blazor.Extensions.Canvas&version=1.1.1                

Canvas

HTML5 Canvas API implementation for Microsoft Blazor

Build Package Version NuGet Downloads License

Blazor Extensions

Blazor Extensions are a set of packages with the goal of adding useful things to Blazor.

Blazor Extensions Canvas

This package wraps HTML5 Canvas APIs.

Both Canvas 2D and WebGL are supported.

Both Blazor Server Apps and Blazor WebAssembly Apps are supported.

NOTE Currently targets the v3.1.5 of Blazor with 3.2.0 of WebAssembly

Installation

Install-Package Blazor.Extensions.Canvas

Sample

Usage

In your index.html file (WebAssembly Apps) or _Host.cshtml (Server Apps) file, place a reference to the library's script file:

<script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script>

In your _Imports.razor add the following using entry:

@using Blazor.Extensions.Canvas

In the component where you want to place a canvas element, add a BECanvas. Make sure to set the ref to a field on your component:

<BECanvas Width="300" Height="400" @ref="_canvasReference" ></BECanvas>

2D

In your component C# code (regardless if inline on .razor or in a .cs file), add a BECanvasComponent reference which matches the ref you set on your BECanvas.

Create a Canvas2DContext, and then use the context methods to draw on the canvas:

private Canvas2DContext _context;

protected BECanvasComponent _canvasReference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    this._context = await this._canvasReference.CreateCanvas2DAsync();
    await this._context.SetFillStyleAsync("green");

    await this._context.FillRectAsync(10, 100, 100, 100);

    await this._context.SetFontAsync("48px serif");
    await this._context.StrokeTextAsync("Hello Blazor!!!", 10, 100);
}

NOTE You cannot call CreateCanvas2DAsync in OnInitAsync, because the underlying <canvas> element is not yet present in the generated markup.

WebGL

In your component C# code (regardless if inline on .razor or in a .cs file), add a BECanvasComponent reference which matches the ref you set on your BECanvas.

Create a WebGLContext, and then use the context methods to draw on the canvas:

private WebGLContext _context;

protected BECanvasComponent _canvasReference;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    this._context = await this._canvasReference.CreateWebGLAsync();
    
    await this._context.ClearColorAsync(0, 0, 0, 1);
    await this._context.ClearAsync(BufferBits.COLOR_BUFFER_BIT);
}

NOTE You cannot call CreateWebGLAsync in OnInitAsync, because the underlying <canvas> element is not yet present in the generated markup.

Call Batching

All javascript interop are batched as needed to improve performance. In high-performance scenarios this behavior will not have any effect: each call will execute immediately. In low-performance scenarios, consective calls to canvas APIs will be queued. JavaScript interop calls will be made with each batch of queued commands sequentially, to avoid the performance impact of multiple concurrent interop calls.

When using server-side Razor Components, because of the server-side rendering mechanism, only the last drawing operation executed will appear to render on the client, overwriting all previous operations. In the example code above, for example, drawing the triangles would appear to "erase" the black background drawn immediately before, leaving the canvas transparent.

To avoid this issue, all WebGL drawing operations should be explicitly preceded and followed by BeginBatchAsync and EndBatchAsync calls.

For example:

await this._context.ClearColorAsync(0, 0, 0, 1); // this call does not draw anything, so it does not need to be included in the explicit batch

await this._context.BeginBatchAsync(); // begin the explicit batch

await this._context.ClearAsync(BufferBits.COLOR_BUFFER_BIT);
await this._context.DrawArraysAsync(Primitive.TRIANGLES, 0, 3);

await this._context.EndBatchAsync(); // execute all currently batched calls

It is best to structure your code so that BeginBatchAsync and EndBatchAsync surround as few calls as possible. That will allow the automatic batching behavior to send calls in the most efficient manner possible, and avoid unnecessary performance impacts.

Methods which return values are never batched. Such methods may be called at any time, even after calling BeginBatchAsync, without interrupting the batching of other calls.

NOTE The "overwriting" behavior of server-side code is unpredictable, and shouldn't be relied on as a feature. In low-performance situations calls can be batched automatically, even when you don't explicitly use BeginBatchAsync and EndBatchAsync.

Contributions and feedback

Please feel free to use the component, open issues, fix bugs or provide feedback.

Contributors

The following people are the maintainers of the Blazor Extensions projects:

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (10)

Showing the top 5 NuGet packages that depend on Blazor.Extensions.Canvas:

Package Downloads
FenixAlliance.ACL.Dependencies

Application Component for the Alliance Business Suite.

MComponents

Another blazor component library

Asmodat.Standard

Multipurpose .NET Standard Extensions

ApprenticeFoundryBlazor

2D and 3D graphics for blazor applications

FoundryBlazor

Package Description

GitHub repositories (6)

Showing the top 5 popular GitHub repositories that depend on Blazor.Extensions.Canvas:

Repository Stars
ArduPilot/MissionPlanner
Mission Planner Ground Control Station for ArduPilot (c# .net)
swharden/Csharp-Data-Visualization
Resources for visualizing data using C# and the .NET platform
SteveDunn/PacManBlazor
PACMAN in Blazor WebAssembly
admin-shell-io/aasx-package-explorer
C# based viewer / editor for the Asset Administration Shell
BlazorGuy/BlazorGalaga
Version Downloads Last updated
1.1.1 842,376 2/17/2021
1.1.0-preview2 811 2/17/2021 1.1.0-preview2 is deprecated because it is no longer maintained and has critical bugs.
1.1.0-preview1 26,677 10/31/2019
1.0.0 36,224 10/31/2019
0.4.0 3,680 9/8/2019
0.3.0 448 8/16/2019
0.2.0 432 7/28/2019
0.1.9 1,460 5/1/2019
0.1.8 3,698 11/26/2018
0.1.7 3,338 10/14/2018
0.1.6 3,384 7/29/2018
0.1.5 1,433 7/27/2018
0.1.4 1,576 6/9/2018
0.1.2 1,510 5/23/2018
0.1.1 1,477 5/23/2018
0.1.0 1,589 5/23/2018