Fingermalerei in SkiaSharp
Verwenden Sie Ihre Finger, um auf der Canvas zu malen.
Ein SKPath
Objekt kann kontinuierlich aktualisiert und angezeigt werden. Mit dieser Funktion kann ein Pfad für interaktives Zeichnen verwendet werden, z. B. in einem Programm zum Malen von Fingern.
Die Touchunterstützung in Xamarin.Forms erlaubt nicht das Nachverfolgen einzelner Finger auf dem Bildschirm, sodass ein Xamarin.Forms Touch-Tracking-Effekt entwickelt wurde, um zusätzliche Touchunterstützung zu bieten. Dieser Effekt wird im Artikel Aufrufen von Ereignissen aus Effekten beschrieben. Das Beispielprogramm Touch-Tracking Effect Demos umfasst zwei Seiten, die SkiaSharp verwenden, einschließlich eines Programms zum Malen von Fingern.
Die SkiaSharpFormsDemos-Lösung umfasst dieses Touchtracking-Ereignis. Das .NET Standard-Bibliotheksprojekt umfasst die TouchEffect
-Klasse, die TouchActionType
Enumeration, den TouchActionEventHandler
Delegaten und die TouchActionEventArgs
-Klasse. Jedes Der Plattformprojekte enthält eine TouchEffect
Klasse für diese Plattform; das iOS-Projekt enthält auch eine TouchRecognizer
Klasse.
Die Seite Finger Paint in SkiaSharpFormsDemos ist eine vereinfachte Implementierung von Fingermalen. Es ist nicht zulässig, Farbe oder Strichbreite auszuwählen, es gibt keine Möglichkeit, die Canvas zu löschen, und natürlich können Sie Ihr Kunstwerk nicht speichern.
Die Datei FingerPaintPage.xaml fügt das SKCanvasView
in eine einzelne Zelle Grid
ein und fügt das TouchEffect
an folgendes Grid
an:
<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>
Das direkte SKCanvasView
Anfügen des TouchEffect
funktioniert nicht auf allen Plattformen.
Die CodeBehind-Datei FingerPaintPage.xaml.cs definiert zwei Sammlungen zum Speichern der SKPath
Objekte sowie ein SKPaint
Objekt zum Rendern dieser Pfade:
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();
}
...
}
Wie der Name schon sagt, speichert das inProgressPaths
Wörterbuch die Pfade, die derzeit mit einem oder mehreren Fingern gezeichnet werden. Der Wörterbuchschlüssel ist die Touch-ID, die die Touchereignisse begleitet. Das completedPaths
Feld ist eine Sammlung von Pfaden, die beendet wurden, als ein Finger, der den Pfad zeichnete, vom Bildschirm gehoben wurde.
Der TouchAction
Handler verwaltet diese beiden Auflistungen. Wenn ein Finger den Bildschirm zum ersten Mal berührt, wird ein neuer SKPath
hinzugefügt inProgressPaths
. Wenn sich dieser Finger bewegt, werden dem Pfad zusätzliche Punkte hinzugefügt. Wenn der Finger losgelassen wird, wird der Pfad an die completedPaths
Auflistung übertragen. Sie können mit mehreren Fingern gleichzeitig malen. Nach jeder Änderung an einem der Pfade oder Auflistungen wird ungültig 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));
}
}
Die Punkte, die die Touchverfolgungsereignisse begleiten, sind Xamarin.Forms Koordinaten. Diese müssen in SkiaSharp-Koordinaten konvertiert werden, bei denen es sich um Pixel handelt. Das ist der Zweck der ConvertToPixel
Methode.
Der PaintSurface
Handler rendert dann einfach beide Auflistungen von Pfaden. Die zuvor abgeschlossenen Pfade werden unter den laufenden Pfaden angezeigt:
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);
}
}
...
}
Ihre Fingerbilder sind nur durch Ihr Talent begrenzt:
Sie haben nun erfahren, wie Sie Linien zeichnen und Kurven mithilfe parametrischer Formeln definieren. Ein späterer Abschnitt zu SkiaSharp Kurven und Pfaden behandelt die verschiedenen Arten von Kurven, die unterstützt SKPath
werden. Eine nützliche Voraussetzung ist jedoch eine Untersuchung von SkiaSharp-Transformationen.