Pfadgrundlagen in SkiaSharp
Erkunden des SkiaSharp SKPath-Objekts zum Kombinieren verbundener Linien und Kurven
Eines der wichtigsten Features des Grafikpfads ist die Möglichkeit zu definieren, wann mehrere Zeilen verbunden werden sollen und wann sie nicht verbunden werden sollen. Der Unterschied kann signifikant sein, wie die Oberen dieser beiden Dreiecke zeigen:
Ein Grafikpfad wird vom SKPath
-Objekt gekapselt. Ein Pfad ist eine Auflistung einer oder mehrerer Konturen. Jede Kontur ist eine Sammlung verbundener gerader Linien und Kurven. Konturen sind nicht miteinander verbunden, aber sie können sich visuell überschneiden. Manchmal kann sich eine einzelne Kontur überlappen.
Eine Kontur beginnt im Allgemeinen mit einem Aufruf der folgenden Methode von SKPath
:
MoveTo
, um eine neue Kontur zu beginnen
Das Argument für diese Methode ist ein einzelner Punkt, den Sie entweder als SKPoint
Wert oder als separate X- und Y-Koordinaten ausdrücken können. Der MoveTo
Aufruf erstellt einen Punkt am Anfang der Kontur und einen anfänglichen Strompunkt. Sie können die folgenden Methoden aufrufen, um die Kontur mit einer Linie oder Kurve vom aktuellen Punkt zu einem in der -Methode angegebenen Punkt fortzusetzen, der dann zum neuen aktuellen Punkt wird:
LineTo
, um dem Pfad eine gerade Linie hinzuzufügenArcTo
, um einen Bogen hinzuzufügen, bei dem es sich um eine Linie im Umfang eines Kreises oder einer Ellipse handeltCubicTo
so fügen Sie eine kubische Bézier-Spline hinzuQuadTo
so fügen Sie eine quadratische Bézier-Spline hinzuConicTo
, um eine rationale quadratische Bézier-Spline hinzuzufügen, die konische Abschnitte (Ellipsen, Parabeln und Hyperbeln) genau rendern kann
Keine dieser fünf Methoden enthält alle Informationen, die zum Beschreiben der Linie oder Kurve erforderlich sind. Jede dieser fünf Methoden funktioniert in Verbindung mit dem aktuellen Punkt, der durch den Methodenaufruf unmittelbar vor dem Aufruf festgelegt wurde. Beispielsweise fügt die LineTo
-Methode der Kontur basierend auf dem aktuellen Punkt eine gerade Linie hinzu, sodass der Parameter von LineTo
nur ein einzelner Punkt ist.
Die SKPath
-Klasse definiert auch Methoden, die die gleichen Namen wie diese sechs Methoden haben, aber mit einem R
am Anfang:
Steht R
für relativ. Diese Methoden weisen die gleiche Syntax wie die entsprechenden Methoden ohne auf, R
sind aber relativ zum aktuellen Punkt. Diese sind praktisch, um ähnliche Teile eines Pfads in einer Methode zu zeichnen, die Sie mehrmals aufrufen.
Eine Kontur endet mit einem weiteren Aufruf von MoveTo
oder RMoveTo
, der eine neue Kontur beginnt, oder mit einem Aufruf von Close
, der die Kontur schließt. Die Close
-Methode fügt automatisch eine gerade Linie vom aktuellen Punkt an den ersten Punkt der Kontur an und markiert den Pfad als geschlossen, was bedeutet, dass er ohne Strichkappen gerendert wird.
Der Unterschied zwischen offenen und geschlossenen Konturen wird auf der Seite Zwei Dreieckskonturen veranschaulicht, die ein SKPath
Objekt mit zwei Konturen verwendet, um zwei Dreiecke zu rendern. Die erste Kontur ist offen und die zweite ist geschlossen. Dies ist die TwoTriangleContoursPage
-Klasse:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Create the path
SKPath path = new SKPath();
// Define the first contour
path.MoveTo(0.5f * info.Width, 0.1f * info.Height);
path.LineTo(0.2f * info.Width, 0.4f * info.Height);
path.LineTo(0.8f * info.Width, 0.4f * info.Height);
path.LineTo(0.5f * info.Width, 0.1f * info.Height);
// Define the second contour
path.MoveTo(0.5f * info.Width, 0.6f * info.Height);
path.LineTo(0.2f * info.Width, 0.9f * info.Height);
path.LineTo(0.8f * info.Width, 0.9f * info.Height);
path.Close();
// Create two SKPaint objects
SKPaint strokePaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Magenta,
StrokeWidth = 50
};
SKPaint fillPaint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Cyan
};
// Fill and stroke the path
canvas.DrawPath(path, fillPaint);
canvas.DrawPath(path, strokePaint);
}
Die erste Kontur besteht aus einem Aufruf MoveTo
der X- und Y-Koordinaten anstelle eines SKPoint
Werts, gefolgt von drei Aufrufen von, LineTo
um die drei Seiten des Dreiecks zu zeichnen. Die zweite Kontur hat nur zwei Aufrufe von LineTo
, aber sie beendet die Kontur mit einem Aufruf von Close
, der die Kontur schließt. Der Unterschied ist signifikant:
Wie Sie sehen können, besteht die erste Kontur offensichtlich aus einer Reihe von drei verbundenen Linien, aber das Ende verbindet sich nicht mit dem Anfang. Die beiden Zeilen überlappen sich oben. Die zweite Kontur ist offensichtlich geschlossen und wurde mit einem Aufruf weniger LineTo
erreicht, da die Close
Methode automatisch eine letzte Linie hinzufügt, um die Kontur zu schließen.
SKCanvas
definiert nur eine DrawPath
Methode, die in dieser Demonstration zweimal aufgerufen wird, um den Pfad zu füllen und zu strichen. Alle Konturen sind gefüllt, auch solche, die nicht geschlossen sind. Zum Füllen von nicht abgeschlossenen Pfaden wird angenommen, dass zwischen den Anfangs- und Endpunkten der Konturen eine gerade Linie vorhanden ist. Wenn Sie die letzte LineTo
von der ersten Kontur oder den Close
Aufruf von der zweiten Kontur entfernen, hat jede Kontur nur zwei Seiten, wird aber wie ein Dreieck ausgefüllt.
SKPath
definiert viele andere Methoden und Eigenschaften. Die folgenden Methoden fügen dem Pfad ganze Konturen hinzu, die je nach Methode geschlossen oder nicht geschlossen sein können:
AddRect
AddRoundedRect
AddCircle
AddOval
AddArc
, um eine Kurve über den Umfang einer Ellipse hinzuzufügenAddPath
, um dem aktuellen Pfad einen weiteren Pfad hinzuzufügenAddPathReverse
, um einen anderen Pfad in umgekehrter Richtung hinzuzufügen
Beachten Sie, dass ein SKPath
Objekt nur eine Geometrie definiert – eine Reihe von Punkten und Verbindungen. Nur wenn ein SKPath
mit einem SKPaint
-Objekt kombiniert wird, wird der Pfad mit einer bestimmten Farbe, Strichbreite usw. gerendert. Beachten Sie auch, dass das an die SKPaint
DrawPath
-Methode übergebene Objekt Merkmale des gesamten Pfads definiert. Wenn Sie etwas zeichnen möchten, das mehrere Farben erfordert, müssen Sie für jede Farbe einen separaten Pfad verwenden.
Genau wie die Darstellung von Anfang und Ende einer Linie durch eine Strichkappe definiert wird, wird die Darstellung der Verbindung zwischen zwei Linien durch einen Strichjoin definiert. Geben Sie dies an, indem Sie die StrokeJoin
-Eigenschaft von SKPaint
auf einen Member der SKStrokeJoin
-Enumeration festlegen:
Miter
für einen pointy joinRound
für einen abgerundeten JoinBevel
für einen abgehackten Join
Auf der Seite Strichverknappungen werden diese drei Strichjoins angezeigt, deren Code der Seite Strichkappen ähnelt. Dies ist der PaintSurface
Ereignishandler in der StrokeJoinsPage
-Klasse:
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.Right
};
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 - 100;
float xLine1 = 100;
float xLine2 = info.Width - xLine1;
float y = 2 * textPaint.FontSpacing;
string[] strStrokeJoins = { "Miter", "Round", "Bevel" };
foreach (string strStrokeJoin in strStrokeJoins)
{
// Display text
canvas.DrawText(strStrokeJoin, xText, y, textPaint);
// Get stroke-join value
SKStrokeJoin strokeJoin;
Enum.TryParse(strStrokeJoin, out strokeJoin);
// Create path
SKPath path = new SKPath();
path.MoveTo(xLine1, y - 80);
path.LineTo(xLine1, y + 80);
path.LineTo(xLine2, y + 80);
// Display thick line
thickLinePaint.StrokeJoin = strokeJoin;
canvas.DrawPath(path, thickLinePaint);
// Display thin line
canvas.DrawPath(path, thinLinePaint);
y += 3 * textPaint.FontSpacing;
}
}
Dies ist das Programm, das ausgeführt wird:
Der Gehrungsjoin besteht aus einem scharfen Punkt, an dem sich die Linien verbinden. Wenn zwei Linien in einem kleinen Winkel miteinander verknüpft sind, kann die Gehrungsjoin ziemlich lang werden. Um zu lange Miterjoins zu verhindern, wird die Länge des Gehrungsjoins durch den Wert der StrokeMiter
-Eigenschaft von SKPaint
begrenzt. Ein Gehrungsjoin, der diese Länge überschreitet, wird abgehackt, um zu einem Abgeschrägten zu werden.