Linien und Strichenden
Erfahren Sie, wie Sie Mit SkiaSharp Linien mit unterschiedlichen Strichkappen zeichnen.
In SkiaSharp unterscheidet sich das Rendern einer einzelnen Zeile von der Darstellung einer Reihe verbundener gerader Linien. Auch beim Zeichnen einzelner Linien ist es häufig erforderlich, den Linien eine bestimmte Strichbreite zu verleihen. Da diese Linien breiter werden, wird auch das Aussehen der Enden der Linien wichtig. Die Darstellung des Endes der Linie wird als Strichkappe bezeichnet:
Zum Zeichnen einzelner Linien definiert eine einfache DrawLine
Methode, SKCanvas
deren Argumente die Anfangs- und Endkoordinaten der Linie mit einem SKPaint
Objekt angeben:
canvas.DrawLine (x0, y0, x1, y1, paint);
Standardmäßig ist die StrokeWidth
Eigenschaft eines neu instanziierten SKPaint
Objekts 0, das denselben Effekt hat wie ein Wert von 1 beim Rendern einer Zeile mit einer Pixelstärke. Dies erscheint auf geräten mit hoher Auflösung wie Smartphones sehr dünn, sodass Sie wahrscheinlich den StrokeWidth
Wert auf einen größeren Wert festlegen möchten. Aber sobald Sie mit dem Zeichnen von Linien einer izierbaren Stärke beginnen, löst dies ein weiteres Problem aus: Wie sollten die Anfangs- und Enden dieser dicken Linien gerendert werden?
Das Aussehen der Anfangs- und Enden von Linien wird als Linienkappe bezeichnet oder in Skia eine Strichkappe. Das Wort "cap" in diesem Kontext bezieht sich auf eine Art Hut – etwas, das sich am Ende der Zeile befindet. Sie legen die StrokeCap
Eigenschaft des SKPaint
Objekts auf eines der folgenden Elemente der SKStrokeCap
Enumeration fest:
Butt
(Standard)Square
Round
Diese werden am besten mit einem Beispielprogramm veranschaulicht. Der Abschnitt "SkiaSharp Lines and Paths " des Beispielprogramms beginnt mit einer Seite mit dem Titel "Stroke Caps " basierend auf der StrokeCapsPage
Klasse. Diese Seite definiert einen PaintSurface
Ereignishandler, der die drei Member der SKStrokeCap
Enumeration durchläuft, wobei sowohl der Name des Enumerationsmembers als auch das Zeichnen einer Linie mit dieser Strichkappe angezeigt wird:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint textPaint = new SKPaint
{
Color = SKColors.Black,
TextSize = 75,
TextAlign = SKTextAlign.Center
};
SKPaint thickLinePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Orange,
StrokeWidth = 50
};
SKPaint thinLinePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Black,
StrokeWidth = 2
};
float xText = info.Width / 2;
float xLine1 = 100;
float xLine2 = info.Width - xLine1;
float y = textPaint.FontSpacing;
foreach (SKStrokeCap strokeCap in Enum.GetValues(typeof(SKStrokeCap)))
{
// Display text
canvas.DrawText(strokeCap.ToString(), xText, y, textPaint);
y += textPaint.FontSpacing;
// Display thick line
thickLinePaint.StrokeCap = strokeCap;
canvas.DrawLine(xLine1, y, xLine2, y, thickLinePaint);
// Display thin line
canvas.DrawLine(xLine1, y, xLine2, y, thinLinePaint);
y += 2 * textPaint.FontSpacing;
}
}
Für jedes Element der SKStrokeCap
Aufzählung zeichnet der Handler zwei Linien, eine mit einer Strichstärke von 50 Pixeln und eine andere Linie, die oben mit einer Strichstärke von zwei Pixeln positioniert ist. Diese zweite Zeile soll den geometrischen Anfang und das Ende der Linie unabhängig von der Linienstärke und einer Strichkappe veranschaulichen:
Wie Sie sehen können, erweitern die Groß- und Round
Strichkappen die Square
Länge der Linie um die Hälfte der Strichbreite am Anfang der Linie und wieder am Ende. Diese Erweiterung wird wichtig, wenn es erforderlich ist, die Dimensionen eines gerenderten Grafikobjekts zu bestimmen.
Die SKCanvas
Klasse enthält auch eine weitere Methode zum Zeichnen mehrerer Linien, die etwas eigenartig ist:
DrawPoints (SKPointMode mode, points, paint)
Der points
Parameter ist ein Array von SKPoint
Werten und mode
ein Element der SKPointMode
Enumeration, das drei Elemente enthält:
Points
so rendern Sie die einzelnen PunkteLines
zum Verbinden der einzelnen PunktepaarePolygon
so verbinden Sie alle aufeinander folgenden Punkte
Auf der Seite "Mehrere Zeilen " wird diese Methode veranschaulicht. Die Datei MultipleLinesPage.xaml instanziiert zwei Picker
Ansichten, mit denen Sie ein Element der SKPointMode
Enumeration und ein Element der SKStrokeCap
Enumeration auswählen können:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
xmlns:skiaforms="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="SkiaSharpFormsDemos.Paths.MultipleLinesPage"
Title="Multiple Lines">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Picker x:Name="pointModePicker"
Title="Point Mode"
Grid.Row="0"
Grid.Column="0"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKPointMode}">
<x:Static Member="skia:SKPointMode.Points" />
<x:Static Member="skia:SKPointMode.Lines" />
<x:Static Member="skia:SKPointMode.Polygon" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
<Picker x:Name="strokeCapPicker"
Title="Stroke Cap"
Grid.Row="0"
Grid.Column="1"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKStrokeCap}">
<x:Static Member="skia:SKStrokeCap.Butt" />
<x:Static Member="skia:SKStrokeCap.Round" />
<x:Static Member="skia:SKStrokeCap.Square" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
<skiaforms:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2" />
</Grid>
</ContentPage>
Beachten Sie, dass die SkiaSharp-Namespacedeklarationen etwas anders sind, da der SkiaSharp
Namespace benötigt wird, um auf die Member der SKPointMode
Und SKStrokeCap
Enumerationen zu verweisen. Der SelectedIndexChanged
Handler für beide Picker
Ansichten macht das SKCanvasView
Objekt einfach ungültig:
void OnPickerSelectedIndexChanged(object sender, EventArgs args)
{
if (canvasView != null)
{
canvasView.InvalidateSurface();
}
}
Dieser Handler muss überprüfen, ob das SKCanvasView
Objekt vorhanden ist, da der Ereignishandler zuerst aufgerufen wird, wenn die SelectedIndex
Eigenschaft des Picker
Objekts in der XAML-Datei auf 0 festgelegt ist und vor der SKCanvasView
Instanziierung auftritt.
Der PaintSurface
Handler ruft die beiden Enumerationswerte aus den Picker
Ansichten ab:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Create an array of points scattered through the page
SKPoint[] points = new SKPoint[10];
for (int i = 0; i < 2; i++)
{
float x = (0.1f + 0.8f * i) * info.Width;
for (int j = 0; j < 5; j++)
{
float y = (0.1f + 0.2f * j) * info.Height;
points[2 * j + i] = new SKPoint(x, y);
}
}
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.DarkOrchid,
StrokeWidth = 50,
StrokeCap = (SKStrokeCap)strokeCapPicker.SelectedItem
};
// Render the points by calling DrawPoints
SKPointMode pointMode = (SKPointMode)pointModePicker.SelectedItem;
canvas.DrawPoints(pointMode, points, paint);
}
Die Screenshots zeigen eine Vielzahl von Picker
Auswahlmöglichkeiten:
Die i Telefon links zeigt, wie das Enumerationselement bewirktDrawPoints
, dass jeder der Punkte im SKPoint
Array als Quadrat gerendert wird, wenn die Linienkappe oder -klammer ist Butt
Square
.SKPointMode.Points
Kreise werden gerendert, wenn die Linienlinie groß ist Round
.
Der Android-Screenshot zeigt das Ergebnis des SKPointMode.Lines
. Die DrawPoints
Methode zeichnet in diesem Fall Round
eine Linie zwischen den einzelnen WertenpaarenSKPoint
, wobei die angegebene Linienkappe verwendet wird.
Wenn Sie stattdessen verwenden SKPointMode.Polygon
, wird eine Linie zwischen den aufeinander folgenden Punkten im Array gezeichnet, aber wenn Sie sehr genau aussehen, sehen Sie, dass diese Linien nicht verbunden sind. Jede dieser separaten Zeilen beginnt und endet mit der angegebenen Linienkappe. Wenn Sie die Round
Feststelltaste auswählen, werden die Linien möglicherweise verbunden, aber sie sind wirklich nicht verbunden.
Ob Linien verbunden sind oder nicht verbunden sind, ist ein wichtiger Aspekt der Arbeit mit Grafikpfaden.