線描画について
今回はいよいよペイントソフトらしくドラッグで線を書いてみます。
前回作成したレイヤー機能の上に構築します。
線を保持するクラス
前回と同様に線を保持するクラスを作成します。
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
に詰めています。
初期化の際、色と太さを指定しておけば、クリックして離すまではそれが適応されるような形となります。
Layer
のDraw
関数に以下の分岐を追加します。
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点を求め、線を引く形となっている。