Points et tirets dans SkiaSharp
Maîtriser les intricités du dessin pointillés et des traits pointillés dans SkiaSharp
SkiaSharp vous permet de dessiner des lignes qui ne sont pas solides, mais sont plutôt composées de points et de tirets :
Pour ce faire, vous utilisez un effet de chemin d’accès, qui est une instance de la SKPathEffect
classe que vous avez définie sur la PathEffect
propriété de SKPaint
. Vous pouvez créer un effet de chemin (ou combiner des effets de chemin) à l’aide de l’une des méthodes de création statique définies par SKPathEffect
. (SKPathEffect
est l’un des six effets pris en charge par SkiaSharp ; les autres sont décrits dans la section Effet SkiaSharp.)
Pour dessiner des lignes pointillées ou en pointillés, vous utilisez la SKPathEffect.CreateDash
méthode statique. Il existe deux arguments : il s’agit d’un tableau de float
valeurs qui indiquent les longueurs des points et des tirets et la longueur des espaces entre eux. Ce tableau doit avoir un nombre pair d’éléments, et il doit y avoir au moins deux éléments. (Il peut y avoir zéro élément dans le tableau, mais cela entraîne une ligne solide.) S’il existe deux éléments, la première est la longueur d’un point ou d’un tiret, et la seconde est la longueur de l’écart avant le point ou le tiret suivant. S’il existe plus de deux éléments, ils se trouvent dans cet ordre : longueur de tiret, longueur d’écart, longueur de tiret, longueur d’écart, longueur d’écart, etc.
En règle générale, vous souhaiterez faire en sorte que le tiret et la longueur de l’écart soient multiples de la largeur du trait. Si la largeur du trait est de 10 pixels, par exemple, le tableau { 10, 10 } dessine une ligne en pointillés où les points et les écarts sont de la même longueur que l’épaisseur du trait.
Toutefois, le StrokeCap
paramètre de l’objet SKPaint
affecte également ces points et tirets. Comme vous le verrez bientôt, cela a un impact sur les éléments de ce tableau.
Les lignes pointillées et pointillées sont illustrées sur la page Points et Tirets . Le fichier DotsAndDashesPage.xaml instancie deux Picker
vues, une pour vous permettre de sélectionner une limite de trait et la seconde pour sélectionner un tableau de tirets :
<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.DotsAndDashesPage"
Title="Dots and Dashes">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Picker x:Name="strokeCapPicker"
Title="Stroke Cap"
Grid.Row="0"
Grid.Column="0"
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>
<Picker x:Name="dashArrayPicker"
Title="Dash Array"
Grid.Row="0"
Grid.Column="1"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>10, 10</x:String>
<x:String>30, 10</x:String>
<x:String>10, 10, 30, 10</x:String>
<x:String>0, 20</x:String>
<x:String>20, 20</x:String>
<x:String>0, 20, 20, 20</x:String>
</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>
Les trois premiers éléments du dashArrayPicker
principe que la largeur du trait est de 10 pixels. Le tableau { 10, 10 } est destiné à une ligne en pointillés, { 30, 10 } est destiné à une ligne en pointillés et { 10, 10, 30, 10 } est destiné à une ligne point-et-tiret. (Les trois autres seront abordés sous peu.)
Le DotsAndDashesPage
fichier code-behind contient le PaintSurface
gestionnaire d’événements et quelques routines d’assistance pour accéder aux Picker
vues :
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = 10,
StrokeCap = (SKStrokeCap)strokeCapPicker.SelectedItem,
PathEffect = SKPathEffect.CreateDash(GetPickerArray(dashArrayPicker), 20)
};
SKPath path = new SKPath();
path.MoveTo(0.2f * info.Width, 0.2f * info.Height);
path.LineTo(0.8f * info.Width, 0.8f * info.Height);
path.LineTo(0.2f * info.Width, 0.8f * info.Height);
path.LineTo(0.8f * info.Width, 0.2f * info.Height);
canvas.DrawPath(path, paint);
}
float[] GetPickerArray(Picker picker)
{
if (picker.SelectedIndex == -1)
{
return new float[0];
}
string str = (string)picker.SelectedItem;
string[] strs = str.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
float[] array = new float[strs.Length];
for (int i = 0; i < strs.Length; i++)
{
array[i] = Convert.ToSingle(strs[i]);
}
return array;
}
Dans les captures d’écran suivantes, l’écran iOS situé à l’extrême gauche montre une ligne en pointillés :
Toutefois, l’écran Android est également censé afficher une ligne en pointillé à l’aide du tableau { 10, 10 } mais au lieu de cela, la ligne est solide. Que s’est-il passé ? Le problème est que l’écran Android a également un paramètre de limite de traits de Square
. Cela étend tous les tirets de la moitié de la largeur du trait, ce qui les oblige à combler les lacunes.
Pour contourner ce problème lors de l’utilisation d’une limite de Square
Round
trait ou , vous devez réduire les longueurs de tirets dans le tableau par la longueur de trait (parfois résultant d’une longueur de tiret de 0) et augmenter les longueurs d’écart par la longueur du trait. Voici comment les trois tableaux de tirets finaux du Picker
fichier XAML ont été calculés :
- { 10, 10 } devient { 0, 20 } pour une ligne en pointillé
- { 30, 10 } devient { 20, 20 } pour une ligne en pointillés
- { 10, 10, 30, 10 } devient { 0, 20, 20, 20} pour une ligne pointillée et pointillée
L’écran UWP montre que la ligne pointillée et pointillée pour un capuchon de trait .Round
Le Round
capuchon de trait donne souvent la meilleure apparence des points et tirets en lignes épaisses.
Jusqu’à présent, aucune mention n’a été faite du deuxième paramètre à la SKPathEffect.CreateDash
méthode. Ce paramètre est nommé phase
et fait référence à un décalage dans le modèle point-and-dash pour le début de la ligne. Par exemple, si le tableau de tirets est { 10, 10 } et que la phase
valeur est 10, la ligne commence par un écart plutôt qu’un point.
Une application intéressante du phase
paramètre est dans une animation. La page Spirale animée est similaire à la page Spirale Archimedean, sauf que la AnimatedSpiralPage
classe anime le phase
paramètre à l’aide de la Xamarin.FormsDevice.Timer
méthode :
public class AnimatedSpiralPage : ContentPage
{
const double cycleTime = 250; // in milliseconds
SKCanvasView canvasView;
Stopwatch stopwatch = new Stopwatch();
bool pageIsActive;
float dashPhase;
public AnimatedSpiralPage()
{
Title = "Animated Spiral";
canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
protected override void OnAppearing()
{
base.OnAppearing();
pageIsActive = true;
stopwatch.Start();
Device.StartTimer(TimeSpan.FromMilliseconds(33), () =>
{
double t = stopwatch.Elapsed.TotalMilliseconds % cycleTime / cycleTime;
dashPhase = (float)(10 * t);
canvasView.InvalidateSurface();
if (!pageIsActive)
{
stopwatch.Stop();
}
return pageIsActive;
});
}
···
}
Bien sûr, vous devrez exécuter le programme pour voir l’animation :