Nozioni di base sul percorso in SkiaSharp
Esplorare l'oggetto SKPath SkiaSharp per combinare linee e curve connesse
Una delle caratteristiche più importanti del percorso grafico è la possibilità di definire quando devono essere connesse più linee e quando non devono essere connesse. La differenza può essere significativa, come illustrato dai primi di questi due triangoli:
Un percorso grafico viene incapsulato dall'oggetto SKPath
. Un percorso è una raccolta di uno o più contorni. Ogni contorno è una raccolta di linee e curve collegate. I contorni non sono collegati tra loro, ma potrebbero sovrapporsi visivamente. A volte un singolo contorno può sovrapporsi.
Un contorno inizia in genere con una chiamata al metodo seguente di SKPath
:
MoveTo
per iniziare un nuovo contorno
L'argomento di tale metodo è un singolo punto, che è possibile esprimere come SKPoint
valore o come coordinate X e Y separate. La MoveTo
chiamata stabilisce un punto all'inizio del contorno e un punto corrente iniziale. È possibile chiamare i metodi seguenti per continuare il contorno con una linea o una curva dal punto corrente a un punto specificato nel metodo, che diventa quindi il nuovo punto corrente:
LineTo
per aggiungere una linea retta al percorsoArcTo
per aggiungere un arco, che è una linea sulla circonferenza di un cerchio o di un'ellisseCubicTo
per aggiungere una spline di Bezier cubicaQuadTo
per aggiungere una spline di Bezier quadraticaConicTo
per aggiungere una spline di Bezier quadratica razionale, che può eseguire il rendering accurato di sezioni coniche (ellissi, parabole e iperbole)
Nessuno di questi cinque metodi contiene tutte le informazioni necessarie per descrivere la linea o la curva. Ognuno di questi cinque metodi funziona insieme al punto corrente stabilito dalla chiamata al metodo immediatamente precedente. Ad esempio, il LineTo
metodo aggiunge una linea retta al contorno in base al punto corrente, quindi il parametro a LineTo
è solo un singolo punto.
La SKPath
classe definisce anche metodi che hanno gli stessi nomi di questi sei metodi, ma con un all'inizio R
:
L'acronimo R
di relative. Questi metodi hanno la stessa sintassi dei metodi corrispondenti senza R
ma sono relativi al punto corrente. Questi sono utili per disegnare parti simili di un percorso in un metodo che chiami più volte.
Un contorno termina con un'altra chiamata a MoveTo
o RMoveTo
, che inizia una nuova contorno o una chiamata a Close
, che chiude il contorno. Il Close
metodo aggiunge automaticamente una linea retta dal punto corrente al primo punto del contorno e contrassegna il percorso come chiuso, il che significa che verrà eseguito il rendering senza estremità di tratto.
La differenza tra contorni aperti e chiusi è illustrata nella pagina Contorni a due triangoli, che usa un SKPath
oggetto con due contorni per eseguire il rendering di due triangoli. Il primo contorno è aperto e il secondo è chiuso. Di seguito è riportata la classe TwoTriangleContoursPage
:
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);
}
Il primo contorno è costituito da una chiamata a MoveTo
utilizzando coordinate X e Y anziché un SKPoint
valore, seguite da tre chiamate per disegnare LineTo
i tre lati del triangolo. Il secondo contorno ha solo due chiamate a LineTo
, ma termina il contorno con una chiamata a Close
, che chiude il contorno. La differenza è significativa:
Come si può notare, il primo contorno è ovviamente una serie di tre linee collegate, ma la fine non si connette con l'inizio. Le due righe si sovrappongono nella parte superiore. Il secondo contorno è ovviamente chiuso ed è stato eseguito con un minor numero LineTo
di chiamate perché il Close
metodo aggiunge automaticamente una riga finale per chiudere il contorno.
SKCanvas
definisce un DrawPath
solo metodo, che in questa dimostrazione viene chiamato due volte per riempire e tracciare il percorso. Tutti i contorni sono riempiti, anche quelli che non sono chiusi. Ai fini del riempimento di percorsi non aperti, si presuppone che esista una linea retta tra i punti iniziale e finale dei contorni. Se si rimuove l'ultimo LineTo
dal primo contorno o si rimuove la Close
chiamata dal secondo contorno, ogni contorno avrà solo due lati, ma verrà riempito come se fosse un triangolo.
SKPath
definisce molti altri metodi e proprietà. I metodi seguenti aggiungono intere contorni al percorso, che potrebbero essere chiusi o non chiusi a seconda del metodo :
AddRect
AddRoundedRect
AddCircle
AddOval
AddArc
per aggiungere una curva sulla circonferenza di un'ellisseAddPath
per aggiungere un altro percorso al percorso correnteAddPathReverse
per aggiungere un altro percorso inverso
Tenere presente che un SKPath
oggetto definisce solo una geometria, ovvero una serie di punti e connessioni. Solo quando un oggetto SKPath
viene combinato con un SKPaint
oggetto è il percorso di cui viene eseguito il rendering con un particolare colore, larghezza del tratto e così via. Tenere inoltre presente che l'oggetto SKPaint
passato al DrawPath
metodo definisce le caratteristiche dell'intero percorso. Se si desidera disegnare un elemento che richiede diversi colori, è necessario utilizzare un percorso separato per ogni colore.
Proprio come l'aspetto dell'inizio e della fine di una linea è definito da un limite di tratto, l'aspetto della connessione tra due linee è definito da un join di tratto. Per specificare questa impostazione, impostare la StrokeJoin
proprietà di SKPaint
su un membro dell'enumerazione SKStrokeJoin
:
Miter
per un join pointyRound
per un join arrotondatoBevel
per un join tritato
La pagina Join tratti mostra questi tre join di tratti con codice simile alla pagina Tratti maiuscole . Questo è il PaintSurface
gestore eventi nella StrokeJoinsPage
classe :
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;
}
}
Ecco il programma in esecuzione:
Il miter join è costituito da un punto appuntito in cui le linee si connettono. Quando due linee si uniscono ad un piccolo angolo, il miter join può diventare abbastanza lungo. Per evitare join di miter eccessivamente lunghi, la lunghezza del join del miter è limitata dal valore della StrokeMiter
proprietà di SKPaint
. Un miter join che supera questa lunghezza viene tagliato fuori per diventare un join di rilievo.