ブラウザ上でクリックした位置に図形を描画したい
WinFormsでできていたことをブラウザでどれだけ実現できるのかを試してみた。
BlazorもWebAssemblyもASP.NETもこれが初挑戦。
そっちを調べるほうが時間かかった。
できた。
環境
- VS2022
- .NET6
構成
準備
Blazor.Extensions.Canvas(1.1.1)のnugetパッケージをインストール
書いてみる
Canvasの準備
WinFormsのPictureBoxみたいなもの?
<div tabindex="0" @onmousedown="OnMouseDown" @onmousemove="OnMouseMove"> <BECanvas Width="800" Height="600" @ref="_canvasReference"></BECanvas> </div>
MouseDown
とMouseMove
を拾えるようにしておく
@code { private Canvas2DContext _context; protected BECanvasComponent _canvasReference; protected override async Task OnAfterRenderAsync(bool firstRender) { _context = await _canvasReference.CreateCanvas2DAsync(); // 背景を黒で塗りつぶし await _context.SetFillStyleAsync("black"); await _context.FillRectAsync(0, 0, _canvasReference.Width, _canvasReference.Height); } }
描画用のインスタンス
Canvas2DContext
:Graphics
みたいなもの
BECanvasComponent
:Canvas
Point構造体ってないの?
仕方がないので作る。
internal record Point(double X, double Y);
四角形を描画する
protected Point Pos { get; } protected string Color { get; } public async Task DrawAsync(Canvas2DContext context) { await context.SetFillStyleAsync(Color); await context.FillRectAsync(Pos.X - 16, Pos.Y - 16, 32, 32); }
丸を描画する
public async Task DrawAsync(Canvas2DContext context) { await context.SetFillStyleAsync(Color); await context.BeginPathAsync(); await context.ArcAsync(Pos.X, Pos.Y, 16, 0, Math.PI * 2); await context.ClosePathAsync(); await context.FillAsync(); }
Graphics.FillEllipse
に相当するものはないみたい。なのでPathを使って書く。
この後やること考えたらPathでよいのだけど。
丸の枠線を描画する
public async Task DrawStrokeAsync(Canvas2DContext context) { await context.SetStrokeStyleAsync("white"); await context.BeginPathAsync(); await context.ArcAsync(Pos.X, Pos.Y, 16, 0, Math.PI * 2); await context.ClosePathAsync(); await context.StrokeAsync(); }
WinFormsでDrawXXX
だったものはStrokeXXX
で表現するらしい
丸の当たり判定を行う
public async Task<bool> HitTestAsync(Canvas2DContext context, Point pt) { await context.BeginPathAsync(); await context.ArcAsync(Pos.X, Pos.Y, 16, 0, Math.PI * 2); await context.ClosePathAsync(); return await context.IsPointInPathAsync(pt.X, pt.Y); }
この辺りは同じ感じ
図形を管理するクラスを作って出来上がり
おしまい
async/await
もほぼ初めてなのでいろいろ勉強になった。