Finger Painting in SkiaSharp
Verwenden Sie Ihre Finger, um auf dem Zeichenbereich zu zeichnen.
Ein SKPath
Objekt kann kontinuierlich aktualisiert und angezeigt werden. Mit diesem Feature kann ein Pfad für interaktive Zeichnung verwendet werden, z. B. in einem Finger-Painting-Programm.
Die Touchunterstützung Xamarin.Forms lässt das Nachverfolgen einzelner Finger auf dem Bildschirm nicht zu, 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 enthält zwei Seiten, die SkiaSharp verwenden, einschließlich eines Finger-Painting-Programms.
Die Beispiellösung enthält dieses Ereignis zur Touchverfolgung. Das .NET Standard-Bibliotheksprojekt enthält 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 Finger Paint-Seite in SkiaSharpFormsDemos ist eine vereinfachte Implementierung von Finger painting. Die Auswahl von Farbe oder Strichbreite ist nicht zulässig, sie hat keine Möglichkeit, den Zeichenbereich zu löschen, und Natürlich können Sie Ihre Grafiken nicht speichern.
Die Datei "FingerPaintPage.xaml " fügt die SKCanvasView
Datei in eine einzelne Zelle Grid
ein und fügt die Datei 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 Anfügen der TouchEffect
Direkt an die SKCanvasView
Plattform funktioniert nicht unter allen Plattformen.
Die FingerPaintPage.xaml.cs CodeBehind-Datei definiert zwei Auflistungen 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 von einem oder mehreren Fingern gezeichnet werden. Die Wörterbuchtaste ist die Touch-ID, die die Touchereignisse begleitet. Das completedPaths
Feld ist eine Sammlung von Pfaden, die beendet wurden, wenn ein Finger, der den Vom Bildschirm angehobenen Pfad zeichnete.
Der TouchAction
Handler verwaltet diese beiden Auflistungen. Wenn ein Finger zum ersten Mal den Bildschirm berührt, wird ein neues SKPath
hinzugefügt inProgressPaths
. Während dieses Fingers bewegt, werden dem Pfad zusätzliche Punkte hinzugefügt. Wenn der Finger losgelassen wird, wird der Pfad in die completedPaths
Sammlung übertragen. Sie können mit mehreren Fingern gleichzeitig zeichnen. Nach jeder Änderung an einem der Pfade oder Auflistungen wird die SKCanvasView
Eigenschaft ungültig:
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 Touch-Tracking-Ereignisse begleiten, sind Xamarin.Forms Koordinaten. Diese müssen in SkiaSharp-Koordinaten konvertiert werden, die Pixel sind. Das ist der Zweck der ConvertToPixel
Methode.
Der PaintSurface
Handler rendert dann einfach beide Auflistungen von Pfaden. Die zuvor abgeschlossenen Pfade werden unterhalb der laufenden Pfade 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 gesehen, wie Sie Linien zeichnen und Kurven mithilfe parametrischer Formeln definieren. Ein späterer Abschnitt zu SkiaSharp Kurven und Pfaden deckt die verschiedenen Arten von Kurven ab, die SKPath
unterstützt werden. Aber eine nützliche Voraussetzung ist eine Erkundung von SkiaSharp Transforms.