Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Мастер тонкостей рисования пунктирных и дефисированных линий в SkiaSharp
SkiaSharp позволяет нарисовать линии, которые не являются твердыми, но вместо этого состоят из точек и дефисов:

Это можно сделать с эффектом пути, который является экземпляром класса, заданного SKPathEffect свойством PathEffectSKPaint. Вы можете создать эффект пути (или объединить эффекты пути) с помощью одного из методов статического создания, определенных SKPathEffect. (SKPathEffect является одним из шести эффектов, поддерживаемых SkiaSharp; другие описаны в разделе SkiaSharp Effect.)
Чтобы нарисовать пунктирные или пунктирные линии, используйте статический SKPathEffect.CreateDash метод. Существует два аргумента: первый — это массив значений float , указывающий длину точек и дефисов и длину пробелов между ними. Этот массив должен иметь четное число элементов, и должно быть не менее двух элементов. (В массиве могут быть нулевые элементы, но это приводит к сплошной линии.) Если есть два элемента, первая — длина точки или тире, а вторая — длина пробела до следующей точки или тире. Если существует более двух элементов, то они находятся в этом порядке: длина тире, длина пробела, длина тире, длина пробела и т. д.
Как правило, вы хотите сделать тире и разрыв длиной кратной ширины штриха. Если ширина штриха равна 10 пикселям, например массив {10, 10 } нарисует пунктирную линию, где точки и пробелы совпадают с толщиной штриха.
StrokeCap Однако параметр SKPaint объекта также влияет на эти точки и дефисы. Как вы увидите вскоре, это влияет на элементы этого массива.
На странице "Точки и дефисы" показаны пунктирные и пунктирные линии. Файл DotsAndDashesPage.xaml создает экземпляры двух Picker представлений, один для выбора крышки штриха, а второй — для выбора массива дефисов:
<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>
Первые три элемента в предположим dashArrayPicker , что ширина штриха составляет 10 пикселей. Массив {10, 10 } предназначен для точечной линии, { 30, 10 } для дефисной линии, а { 10, 10, 30, 10 } предназначен для линии dot-and-dash. (Остальные три будут обсуждаться в ближайшее время.)
Файл DotsAndDashesPage программной части содержит PaintSurface обработчик событий и несколько вспомогательных подпрограмм для доступа к Picker представлениям:
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;
}
На следующих снимках экрана экран iOS в левом углу отображает пунктирную линию:
Однако экран Android также должен показать пунктирную линию с помощью массива { 10, 10 } но вместо этого линия является твердой. Что произошло? Проблема заключается в том, что экран Android также имеет параметр Squareзаголовков штрихов. Это расширяет все дефисы на половину ширины штриха, что приводит к их заполнению пробелов.
Чтобы обойти эту проблему при использовании штриховой крышки Square или Round, необходимо уменьшить длину тире в массиве на длину штриха (иногда в результате тире длиной 0), а также увеличить длину разрывов на длину штриха. Вот как вычислялись последние три массива дефисов в Picker XAML-файле:
- { 10, 10 } становится { 0, 20 } для пунктирной линии
- { 30, 10 } становится { 20, 20 } для тире линии
- { 10, 10, 30, 10 } становится { 0, 20, 20, 20} для пунктирной и пунктирной линии
На экране UWP показано, что точка и пунктирная линия для штриховой крышки Round. Крышка Round штриха часто дает лучший вид точек и тире в толстых линиях.
До сих пор упоминание не было сделано из второго параметра методаSKPathEffect.CreateDash. Этот параметр называется phase и ссылается на смещение в шаблоне dot-and-dash для начала строки. Например, если массив тире равен {10, 10 } и phase равен 10, то строка начинается с пробела, а не точки.
Одним из интересных приложений phase параметра является анимация. Страница анимированной спирали похожа на страницу Archimedean Spiral, за исключением того, что AnimatedSpiralPage класс анимирует phase параметр с помощью Xamarin.FormsDevice.Timer метода:
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;
});
}
···
}
Конечно, вам придется на самом деле запустить программу, чтобы увидеть анимацию:

