Linie i zakończenia pociągnięć
Dowiedz się, jak używać skiaSharp do rysowania linii z różnymi czapkami pociągnięcia
W usłudze SkiaSharp renderowanie pojedynczej linii różni się bardzo od renderowania serii połączonych linii prostych. Nawet w przypadku rysowania pojedynczych linii często konieczne jest nadanie wierszom określonej szerokości pociągnięcia. W miarę jak te linie stają się szersze, wygląd końców linii również staje się ważny. Wygląd końca linii jest nazywany czapką pociągnięć:
W przypadku rysowania pojedynczych wierszy definiuje prostą metodę, SKCanvas
której argumenty wskazują współrzędne początkowe i końcowe linii z obiektemSKPaint
:DrawLine
canvas.DrawLine (x0, y0, x1, y1, paint);
Domyślnie StrokeWidth
właściwość nowo utworzonego SKPaint
obiektu ma wartość 0, która ma taki sam efekt jak wartość 1 w renderowaniu linii o grubości jednego piksela. Wydaje się to bardzo cienkie na urządzeniach o wysokiej rozdzielczości, takich jak telefony, więc prawdopodobnie chcesz ustawić StrokeWidth
wartość na większą. Ale po rozpoczęciu rysowania linii o dużej grubości, co budzi kolejny problem: Jak powinny być renderowane początkowe i końce tych grubych linii?
Wygląd startów i końców linii jest nazywany czapką liniową lub, w Skia, czapką pociągniętą. Słowo "cap" w tym kontekście odnosi się do rodzaju kapelusza — coś, co znajduje się na końcu linii. Właściwość obiektu należy ustawić StrokeCap
SKPaint
na jeden z następujących elementów członkowskich SKStrokeCap
wyliczenia:
Butt
(wartość domyślna)Square
Round
Są one najlepiej zilustrowane za pomocą przykładowego programu. Sekcja SkiaSharp Lines and Paths (Linie i ścieżki ) przykładowego programu rozpoczyna się od strony zatytułowanej Stroke Caps na StrokeCapsPage
podstawie klasy. Ta strona definiuje procedurę PaintSurface
obsługi zdarzeń, która wykonuje pętlę przez trzy elementy członkowskie SKStrokeCap
wyliczenia, wyświetlając zarówno nazwę elementu członkowskiego wyliczenia, jak i rysując wiersz przy użyciu tego limitu pociągnięcia:
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;
}
}
Dla każdego elementu członkowskiego SKStrokeCap
wyliczenia program obsługi rysuje dwie linie, jedną z grubością pociągnięcia 50 pikseli i drugą linią umieszczoną na górze z grubością pociągnięcia dwóch pikseli. Druga linia ma na celu zilustrowanie geometrycznego początku i końca linii niezależnie od grubości linii i czapki pociągnięcia:
Jak widać, Square
czapki i Round
pociągnięcia skutecznie rozszerzają długość linii o połowę szerokości pociągnięcia na początku linii i ponownie na końcu. To rozszerzenie staje się ważne, gdy konieczne jest określenie wymiarów renderowanego obiektu graficznego.
Klasa SKCanvas
zawiera również inną metodę rysowania wielu wierszy, która jest nieco osobliwa:
DrawPoints (SKPointMode mode, points, paint)
Parametr points
jest tablicą SKPoint
wartości i mode
jest elementem członkowskim wyliczenia, który ma trzy elementy SKPointMode
członkowskie:
Points
renderowanie poszczególnych punktówLines
aby połączyć każdą parę punktówPolygon
aby połączyć wszystkie kolejne punkty
Na stronie Wiele linii przedstawiono tę metodę. Plik MultipleLinesPage.xaml tworzy wystąpienie dwóch Picker
widoków, które umożliwiają wybranie elementu członkowskiego SKPointMode
wyliczenia i członka SKStrokeCap
wyliczenia:
<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>
Zwróć uwagę, że deklaracje przestrzeni nazw SkiaSharp są nieco inne, ponieważ SkiaSharp
przestrzeń nazw jest potrzebna do odwołowywania się do elementów SKPointMode
członkowskich i SKStrokeCap
wyliczenia. Procedura SelectedIndexChanged
obsługi dla obu Picker
widoków po prostu unieważnia SKCanvasView
obiekt:
void OnPickerSelectedIndexChanged(object sender, EventArgs args)
{
if (canvasView != null)
{
canvasView.InvalidateSurface();
}
}
Ta procedura obsługi musi sprawdzić istnienie SKCanvasView
obiektu, ponieważ program obsługi zdarzeń jest najpierw wywoływany, gdy SelectedIndex
właściwość Picker
obiektu jest ustawiona na wartość 0 w pliku XAML i występuje przed utworzeniem SKCanvasView
wystąpienia.
Procedura PaintSurface
obsługi uzyskuje dwie wartości wyliczenia z Picker
widoków:
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);
}
Zrzuty ekranu przedstawiają różne Picker
opcje:
Element i Telefon po lewej stronie pokazuje, jak SKPointMode.Points
element członkowski wyliczenia powoduje DrawPoints
renderowanie każdego z punktów w SKPoint
tablicy jako kwadratu, jeśli limit wiersza to Butt
lub Square
. Okręgi są renderowane, jeśli limit wiersza to Round
.
Zrzut ekranu systemu Android przedstawia wynik .SKPointMode.Lines
Metoda DrawPoints
rysuje linię między każdą parą wartości przy użyciu określonego SKPoint
limitu wiersza, w tym przypadku Round
.
Zamiast tego użyjesz SKPointMode.Polygon
metody , linia jest rysowana między kolejnymi punktami w tablicy, ale jeśli przyjrzysz się bardzo uważnie, zobaczysz, że te wiersze nie są połączone. Każdy z tych oddzielnych wierszy rozpoczyna się i kończy się określonym limitem wiersza. Jeśli wybierzesz Round
limity, wiersze mogą wydawać się połączone, ale naprawdę nie są połączone.
To, czy linie są połączone, czy nie są połączone, jest kluczowym aspektem pracy ze ścieżkami graficznymi.