0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ひとりで完走_C# is GODAdvent Calendar 2024

Day 4

Win2Dについて その5 線描画

Last updated at Posted at 2024-12-03

線描画について

今回はいよいよペイントソフトらしくドラッグで線を書いてみます。
前回作成したレイヤー機能の上に構築します。

線を保持するクラス

前回と同様に線を保持するクラスを作成します。

public class LineShape : IShape
{
    public ShapeMode Mode { get; set; } = ShapeMode.Line;
    public List<Vector2> LinePoints { get; set; }
    public Color Color { get; set; }
    public float Stroke {  get; set; }

    public LineShape(Vector2 linePoint, Color color, float stroke) 
    {
        LinePoints = new List<Vector2>() {linePoint};
        Color = color;
        Stroke = stroke;
    }
}

Win2Dで線を引くとき、始点と終点の2つの点が必要になります。
今回はリストの中にそれぞれの点の情報を追加していく形となるのでVector2のリストを保持しています。

描画処理

線データを詰める処理は以下のようになります。

// 線情報を初期化する。
public void AddLine(Vector2 point, Color color, float stroke)
{
    lines =new LineShape(point, color, stroke);
    // ここでshapesにlinesを追加すれば、線を引いている最中でもどのような線を引いているか確認できる。
    shapes.Add(lines);
}
// 点を追加していく。
public void AddPoint(Vector2 point)
{
    lines.LinePoints.Add(point);
}

最初のクリックで線情報を初期化し、shapesに詰めています。
初期化の際、色と太さを指定しておけば、クリックして離すまではそれが適応されるような形となります。

LayerDraw関数に以下の分岐を追加します。

 public void Draw(CanvasDrawingSession ds, float alpha = 1)
 {
     foreach(var shape in shapes)
     {
         if(shape.Mode == ShapeMode.Rectangle)
         {
             var rectangle = (RectangleShape) shape;
             ds.DrawRectangle(rectangle.Rect, rectangle.Color, rectangle.Storoke);
         }
         // Line描画
+        if(shape.Mode == ShapeMode.Line)
+        {
+            var lines = (LineShape) shape;
+            for(int i = 0; i < lines.LinePoints.Count -1; i++)
+            {
+                ds.DrawLine(lines.LinePoints[i], lines.LinePoints[i+1], lines.Color, lines.Stroke);
+            }
+        }
     }
 }

前回同様にshapesに詰められた描画アイテムからLineShapeの点の情報を引き出して始点と終点を作り線を作成しています。
線は連続した点の集まりとなるので上記のように処理するわけです。

クリック処理

MainWindow.xaml.csでは以下のように作成し、各レイヤーの描画処理を呼び出します。

// クリック開始
private void Canvas_PointerPressed(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{    
    pointerDrag = new PointerDrag(e.GetCurrentPoint(canvas).Position);
    mouseDown = true;
    // 初期化処理を呼び出す。
    layers[CurrentIndex].AddLine(new Vector2((float) pointerDrag.CurrentLocation.X, (float) pointerDrag.CurrentLocation.Y), PickUpColor, 5);
    canvas.Invalidate();
}

// マウスを動かすとき
private void Canvas_PointerMoved(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    if (mouseDown == false)
        return;
    pointerDrag.CurrentLocation = e.GetCurrentPoint(canvas).Position;

    // 現在のポイントを線の点リストに追加(Vector2で与えている)
    layers[CurrentIndex].AddPoint(new Vector2((float) pointerDrag.CurrentLocation.X, (float) pointerDrag.CurrentLocation.Y));

    canvas.Invalidate();
}

// マウスを離したとき
private void Canvas_PointerReleased(object sender, Microsoft.UI.Xaml.Input.PointerRoutedEventArgs e)
{
    if (mouseDown == false)
        return; 
    // 離したときは何もしなくてよい。(MouseDownをfalseにすること)
    mouseDown = false;
    canvas.Invalidate();
}

マウスを動かしている間常に現在の点が線リストに追加していき、その追加した点を元に2点を求め、線を引く形となっている。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?