Pittura di dito in SkiaSharp
Usa le dita per dipingere sull'area di disegno.
Un SKPath
oggetto può essere aggiornato e visualizzato continuamente. Questa funzionalità consente di utilizzare un percorso per il disegno interattivo, ad esempio in un programma di disegno con dita.
Il supporto tocco in Xamarin.Forms non consente di tenere traccia delle singole dita sullo schermo, quindi è stato sviluppato un Xamarin.Forms effetto di tracciamento del tocco per fornire ulteriore supporto tocco. Questo effetto è descritto nell'articolo Richiamo di eventi da Effetti. Il programma di esempio include due pagine che usano SkiaSharp, incluso un programma di dito.
La soluzione di esempio include questo evento di rilevamento tocco. Il progetto di libreria .NET Standard include la TouchEffect
classe , l'enumerazione TouchActionType
, il TouchActionEventHandler
delegato e la TouchActionEventArgs
classe . Ogni progetto di piattaforma include una TouchEffect
classe per tale piattaforma. Il progetto iOS contiene anche una TouchRecognizer
classe.
La pagina Finger Paint in SkiaSharpFormsDemos è un'implementazione semplificata della pittura delle dita. Non consente di selezionare il colore o la larghezza del tratto, non ha modo di cancellare l'area di disegno e naturalmente non è possibile salvare le opere d'arte.
Il file FingerPaintPage.xaml inserisce in SKCanvasView
una singola cella Grid
e associa a TouchEffect
tale Grid
oggetto :
<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
Il collegamento diretto a SKCanvasView
non funziona in tutte le piattaforme.
Il file code-behind FingerPaintPage.xaml.cs definisce due raccolte per l'archiviazione degli oggetti, nonché un SKPaint
oggetto per il SKPath
rendering di questi percorsi:
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();
}
...
}
Come suggerisce il nome, il inProgressPaths
dizionario archivia i percorsi attualmente disegnati da una o più dita. La chiave del dizionario è l'ID tocco che accompagna gli eventi di tocco. Il completedPaths
campo è una raccolta di percorsi che sono stati completati quando un dito che disegnava il percorso sollevato dallo schermo.
Il TouchAction
gestore gestisce queste due raccolte. Quando un dito tocca per la prima volta lo schermo, viene aggiunto un nuovo SKPath
oggetto a inProgressPaths
. Man mano che il dito si muove, vengono aggiunti punti aggiuntivi al percorso. Quando il dito viene rilasciato, il percorso viene trasferito alla completedPaths
raccolta. È possibile dipingere con più dita contemporaneamente. Dopo ogni modifica a uno dei percorsi o delle raccolte, l'oggetto SKCanvasView
viene invalidato:
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));
}
}
I punti che accompagnano gli eventi di rilevamento del tocco sono Xamarin.Forms coordinate, che devono essere convertite in coordinate SkiaSharp, ovvero pixel. Questo è lo scopo del ConvertToPixel
metodo .
Il gestore esegue quindi semplicemente il PaintSurface
rendering di entrambe le raccolte di percorsi. I percorsi completati precedenti vengono visualizzati sotto i percorsi in corso:
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);
}
}
...
}
I tuoi dita sono limitati solo dal tuo talento:
Si è visto come disegnare linee e definire le curve usando equazioni parametriche. Una sezione successiva su SkiaSharp Curves and Paths illustra i vari tipi di curve supportate SKPath
. Ma un prerequisito utile è un'esplorazione delle trasformazioni SkiaSharp.