Роспись пальцев в SkiaSharp
Используйте пальцы, чтобы нарисовать на холсте.
Объект SKPath
можно постоянно обновлять и отображать. Эта функция позволяет использовать путь для интерактивного рисования, например в программе рисования пальцев.
Поддержка сенсорного ввода не позволяет отслеживать отдельные пальцы на экране, поэтому Xamarin.Forms эффект сенсорного Xamarin.Forms отслеживания был разработан, чтобы обеспечить дополнительную поддержку сенсорного ввода. Этот эффект описан в статье "Вызов событий из эффектов". Пример программы включает две страницы, использующие SkiaSharp, включая программу рисования пальцев.
Пример решения включает это событие отслеживания сенсорного ввода. Проект библиотеки .NET Standard включает TouchEffect
класс, TouchActionType
перечисление, TouchActionEventHandler
делегат и TouchActionEventArgs
класс. Каждый из проектов платформы включает TouchEffect
класс для этой платформы; проект iOS также содержит TouchRecognizer
класс.
Страница "Палец краска" в SkiaSharpFormsDemos является упрощенной реализацией рисования пальцев. Он не позволяет выбирать цвет или ширину росчерка, он не имеет способа очистить холст, и, конечно, вы не можете сохранить изображение.
Файл FingerPaintPage.xaml помещает SKCanvasView
его в одну ячейку Grid
и присоединяет TouchEffect
его к этомуGrid
:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking"
x:Class="SkiaSharpFormsDemos.Paths.FingerPaintPage"
Title="Finger Paint">
<Grid BackgroundColor="White">
<skia:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface" />
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
</ContentPage>
Присоединение TouchEffect
непосредственно к нему SKCanvasView
не работает на всех платформах.
Файл кода FingerPaintPage.xaml.cs определяет две коллекции для хранения SKPath
объектов, а также SKPaint
объект для отрисовки этих путей:
public partial class FingerPaintPage : ContentPage
{
Dictionary<long, SKPath> inProgressPaths = new Dictionary<long, SKPath>();
List<SKPath> completedPaths = new List<SKPath>();
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = 10,
StrokeCap = SKStrokeCap.Round,
StrokeJoin = SKStrokeJoin.Round
};
public FingerPaintPage()
{
InitializeComponent();
}
...
}
Как показано в названии, inProgressPaths
словарь хранит пути, которые в настоящее время рисуются одним или несколькими пальцами. Ключ словаря — это идентификатор сенсорного ввода, который сопровождает события касания. Поле completedPaths
представляет собой коллекцию путей, которые были завершены, когда пальцем, который рисовал путь, поднятый с экрана.
Обработчик TouchAction
управляет этими двумя коллекциями. Когда пальцем сначала прикасается к экрану, добавляется inProgressPaths
новоеSKPath
. По мере перемещения пальца в путь добавляются дополнительные точки. При освобождении пальца путь передается в коллекцию completedPaths
. Вы можете одновременно рисовать с несколькими пальцами. После каждого изменения на один из путей или коллекций будет SKCanvasView
отменено:
public partial class FingerPaintPage : ContentPage
{
...
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
switch (args.Type)
{
case TouchActionType.Pressed:
if (!inProgressPaths.ContainsKey(args.Id))
{
SKPath path = new SKPath();
path.MoveTo(ConvertToPixel(args.Location));
inProgressPaths.Add(args.Id, path);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Moved:
if (inProgressPaths.ContainsKey(args.Id))
{
SKPath path = inProgressPaths[args.Id];
path.LineTo(ConvertToPixel(args.Location));
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Released:
if (inProgressPaths.ContainsKey(args.Id))
{
completedPaths.Add(inProgressPaths[args.Id]);
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
case TouchActionType.Cancelled:
if (inProgressPaths.ContainsKey(args.Id))
{
inProgressPaths.Remove(args.Id);
canvasView.InvalidateSurface();
}
break;
}
}
...
SKPoint ConvertToPixel(Point pt)
{
return new SKPoint((float)(canvasView.CanvasSize.Width * pt.X / canvasView.Width),
(float)(canvasView.CanvasSize.Height * pt.Y / canvasView.Height));
}
}
Точки, сопровождающие события сенсорного отслеживания, являются Xamarin.Forms координатами. Они должны быть преобразованы в координаты SkiaSharp, которые являются пикселями. Это цель ConvertToPixel
метода.
Затем PaintSurface
обработчик просто отрисовывает обе коллекции путей. Предыдущие завершенные пути отображаются под путями, которые выполняются:
public partial class FingerPaintPage : ContentPage
{
...
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKCanvas canvas = args.Surface.Canvas;
canvas.Clear();
foreach (SKPath path in completedPaths)
{
canvas.DrawPath(path, paint);
}
foreach (SKPath path in inProgressPaths.Values)
{
canvas.DrawPath(path, paint);
}
}
...
}
Ваши рисунки пальцев ограничены только вашим талантом:
Теперь вы узнали, как рисовать линии и определять кривые с помощью уравнений параметрики. Более поздний раздел о кривых и путях SkiaSharp охватывает различные типы кривых, которые SKPath
поддерживают. Но полезное условие заключается в изучении преобразований SkiaSharp.