Blazor.Extensions.Canvas 0.1.9

Blazor Extensions Canvas

HTML5 Canvas API implementation for ASP.NET Core Blazor.

Install-Package Blazor.Extensions.Canvas -Version 0.1.9
dotnet add package Blazor.Extensions.Canvas --version 0.1.9
<PackageReference Include="Blazor.Extensions.Canvas" Version="0.1.9" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Blazor.Extensions.Canvas --version 0.1.9
The NuGet Team does not provide support for this client. Please contact its maintainers for support.

Usage

On your _ViewImports.cshtml add the using and TagHelper entries:

@using Blazor.Extensions.Canvas
@addTagHelper *, Blazor.Extensions.Canvas

On your .cshtml add a BECanvas and make sure you set the ref to a field on your component:

<BECanvas ref="@_canvasReference"></BECanvas>

2D

On your component C# code (regardless if inline on .razor or in a .cs file), from a BECanvasComponent reference, 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()
{
    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 &lt;canvas&gt; element is not yet present in the generated markup.

WebGL

On your component C# code (regardless if inline on .razor or in a .cs file), from a BECanvasComponent reference, 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()
{
    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 &lt;canvas&gt; 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:

Usage

On your _ViewImports.cshtml add the using and TagHelper entries:

@using Blazor.Extensions.Canvas
@addTagHelper *, Blazor.Extensions.Canvas

On your .cshtml add a BECanvas and make sure you set the ref to a field on your component:

<BECanvas ref="@_canvasReference"></BECanvas>

2D

On your component C# code (regardless if inline on .razor or in a .cs file), from a BECanvasComponent reference, 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()
{
    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 &lt;canvas&gt; element is not yet present in the generated markup.

WebGL

On your component C# code (regardless if inline on .razor or in a .cs file), from a BECanvasComponent reference, 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()
{
    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 &lt;canvas&gt; 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:

Version History

Version Downloads Last updated
0.1.9 262 5/1/2019
0.1.8 1,684 11/26/2018
0.1.7 1,620 10/14/2018
0.1.6 2,089 7/29/2018
0.1.5 197 7/27/2018
0.1.4 269 6/9/2018
0.1.2 215 5/23/2018
0.1.1 185 5/23/2018
0.1.0 198 5/23/2018