{"id":15092980,"url":"https://github.com/blazorextensions/canvas","last_synced_at":"2025-05-15T02:08:26.726Z","repository":{"id":41063255,"uuid":"132538599","full_name":"BlazorExtensions/Canvas","owner":"BlazorExtensions","description":"HTML5 Canvas API implementation for Microsoft Blazor","archived":false,"fork":false,"pushed_at":"2024-03-11T22:59:13.000Z","size":327,"stargazers_count":630,"open_issues_count":58,"forks_count":145,"subscribers_count":28,"default_branch":"master","last_synced_at":"2025-05-10T20:49:13.701Z","etag":null,"topics":["blazor","canvas","canvas-element","html5-canvas","web-assembly","webassembly"],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlazorExtensions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-05-08T01:51:06.000Z","updated_at":"2025-05-02T09:44:38.000Z","dependencies_parsed_at":"2024-06-20T16:17:11.239Z","dependency_job_id":"6e2eb4bb-7281-488c-8831-243b687483dd","html_url":"https://github.com/BlazorExtensions/Canvas","commit_stats":{"total_commits":56,"total_committers":15,"mean_commits":"3.7333333333333334","dds":0.6607142857142857,"last_synced_commit":"ebc3eefc7f6c7544975b3d434cc98c01e4d99106"},"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlazorExtensions%2FCanvas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlazorExtensions%2FCanvas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlazorExtensions%2FCanvas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlazorExtensions%2FCanvas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlazorExtensions","download_url":"https://codeload.github.com/BlazorExtensions/Canvas/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254259384,"owners_count":22040820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blazor","canvas","canvas-element","html5-canvas","web-assembly","webassembly"],"created_at":"2024-09-25T11:02:27.068Z","updated_at":"2025-05-15T02:08:21.706Z","avatar_url":"https://github.com/BlazorExtensions.png","language":"C#","readme":"# Canvas\r\nHTML5 Canvas API implementation for Microsoft Blazor\r\n\r\n[![Build](https://github.com/BlazorExtensions/Canvas/workflows/CI/badge.svg)](https://github.com/BlazorExtensions/Canvas/actions)\r\n[![Package Version](https://img.shields.io/nuget/v/Blazor.Extensions.Canvas.svg)](https://www.nuget.org/packages/Blazor.Extensions.Canvas)\r\n[![NuGet Downloads](https://img.shields.io/nuget/dt/Blazor.Extensions.Canvas.svg)](https://www.nuget.org/packages/Blazor.Extensions.Canvas)\r\n[![License](https://img.shields.io/github/license/BlazorExtensions/Canvas.svg)](https://github.com/BlazorExtensions/Canvas/blob/master/LICENSE)\r\n\r\n# Blazor Extensions\r\n\r\nBlazor Extensions are a set of packages with the goal of adding useful things to [Blazor](https://blazor.net).\r\n\r\n# Blazor Extensions Canvas\r\n\r\nThis package wraps [HTML5 Canvas](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas) APIs. \r\n\r\nBoth Canvas 2D and WebGL are supported.\r\n\r\nBoth Blazor Server Apps and Blazor WebAssembly Apps are supported.\r\n\r\n**NOTE** Currently targets the v3.1.5 of Blazor with 3.2.0 of WebAssembly\r\n\r\n# Installation\r\n\r\n```\r\nInstall-Package Blazor.Extensions.Canvas\r\n```\r\n\r\n# Sample\r\n\r\n## Usage\r\n\r\nIn your `index.html` file (WebAssembly Apps) or `_Host.cshtml` (Server Apps) file, place a reference to the library's script file:\r\n\r\n```html\r\n\u003cscript src=\"_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js\"\u003e\u003c/script\u003e\r\n```\r\n\r\nIn your `_Imports.razor` add the following `using` entry:\r\n\r\n```c#\r\n@using Blazor.Extensions.Canvas\r\n```\r\n\r\nIn 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:\r\n\r\n```c#\r\n\u003cBECanvas Width=\"300\" Height=\"400\" @ref=\"_canvasReference\" \u003e\u003c/BECanvas\u003e\r\n```\r\n\r\n### 2D\r\n\r\nIn 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`.\r\n\r\nCreate a `Canvas2DContext`, and then use the context methods to draw on the canvas:\r\n\r\n```c#\r\nprivate Canvas2DContext _context;\r\n\r\nprotected BECanvasComponent _canvasReference;\r\n\r\nprotected override async Task OnAfterRenderAsync(bool firstRender)\r\n{\r\n    this._context = await this._canvasReference.CreateCanvas2DAsync();\r\n    await this._context.SetFillStyleAsync(\"green\");\r\n\r\n    await this._context.FillRectAsync(10, 100, 100, 100);\r\n\r\n    await this._context.SetFontAsync(\"48px serif\");\r\n    await this._context.StrokeTextAsync(\"Hello Blazor!!!\", 10, 100);\r\n}\r\n```\r\n\r\n**NOTE** You cannot call `CreateCanvas2DAsync` in `OnInitAsync`, because the underlying `\u003ccanvas\u003e` element is not yet present in the generated markup.\r\n\r\n### WebGL\r\n\r\nIn 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`.\r\n\r\nCreate a `WebGLContext`, and then use the context methods to draw on the canvas:\r\n\r\n```c#\r\nprivate WebGLContext _context;\r\n\r\nprotected BECanvasComponent _canvasReference;\r\n\r\nprotected override async Task OnAfterRenderAsync(bool firstRender)\r\n{\r\n    this._context = await this._canvasReference.CreateWebGLAsync();\r\n    \r\n    await this._context.ClearColorAsync(0, 0, 0, 1);\r\n    await this._context.ClearAsync(BufferBits.COLOR_BUFFER_BIT);\r\n}\r\n```\r\n\r\n**NOTE** You cannot call `CreateWebGLAsync` in `OnInitAsync`, because the underlying `\u003ccanvas\u003e` element is not yet present in the generated markup.\r\n\r\n### Call Batching\r\n\r\nAll 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.\r\n\r\nWhen 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.\r\n\r\nTo avoid this issue, all WebGL **drawing** operations should be explicitly preceded and followed by `BeginBatchAsync` and `EndBatchAsync` calls.\r\n\r\nFor example:\r\n\r\n```c#\r\nawait 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\r\n\r\nawait this._context.BeginBatchAsync(); // begin the explicit batch\r\n\r\nawait this._context.ClearAsync(BufferBits.COLOR_BUFFER_BIT);\r\nawait this._context.DrawArraysAsync(Primitive.TRIANGLES, 0, 3);\r\n\r\nawait this._context.EndBatchAsync(); // execute all currently batched calls\r\n```\r\n\r\nIt 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.\r\n\r\nMethods 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.\r\n\r\n***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`.\r\n\r\n# Contributions and feedback\r\n\r\nPlease feel free to use the component, open issues, fix bugs or provide feedback.\r\n\r\n# Contributors\r\n\r\nThe following people are the maintainers of the Blazor Extensions projects:\r\n\r\n- [Attila Hajdrik](https://github.com/attilah)\r\n- [Gutemberg Ribiero](https://github.com/galvesribeiro)\r\n\r\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblazorextensions%2Fcanvas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblazorextensions%2Fcanvas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblazorextensions%2Fcanvas/lists"}