Finger Painting in SkiaSharp
Utilisez vos doigts pour peindre sur le canevas.
Un SKPath
objet peut être continuellement mis à jour et affiché. Cette fonctionnalité permet d’utiliser un chemin d’accès pour le dessin interactif, par exemple dans un programme de peinture au doigt.
La prise en charge tactile dans ne permet pas de suivre des doigts individuels sur l’écran. Un effet de suivi tactile a donc Xamarin.Forms été développé pour fournir une prise en Xamarin.Forms charge tactile supplémentaire. Cet effet est décrit dans l’article Appel d’événements à partir d’effets. L’exemple de programme Touch-Tracking Effect Demos comprend deux pages qui utilisent SkiaSharp, y compris un programme de peinture sur les doigts.
La solution SkiaSharpFormsDemos inclut cet événement de suivi tactile. Le projet de bibliothèque .NET Standard inclut la TouchEffect
classe, l’énumération TouchActionType
, le TouchActionEventHandler
délégué et la TouchActionEventArgs
classe . Chacun des projets de plateforme inclut une TouchEffect
classe pour cette plateforme ; le projet iOS contient également une TouchRecognizer
classe.
La page Finger Paint dans SkiaSharpFormsDemos est une implémentation simplifiée de la peinture au doigt. Il ne permet pas de sélectionner la couleur ou la largeur du trait, il n’a aucun moyen d’effacer le canevas et, bien sûr, vous ne pouvez pas enregistrer votre illustration.
Le fichier FingerPaintPage.xaml place le SKCanvasView
dans une cellule Grid
unique et joint à TouchEffect
ce :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>
L’attachement direct au TouchEffect
SKCanvasView
ne fonctionne pas sous toutes les plateformes.
Le fichier code-behind FingerPaintPage.xaml.cs définit deux collections pour stocker les SKPath
objets, ainsi qu’un SKPaint
objet pour le rendu de ces chemins :
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();
}
...
}
Comme son nom l’indique, le inProgressPaths
dictionnaire stocke les chemins qui sont actuellement tracés par un ou plusieurs doigts. La clé de dictionnaire est l’ID tactile qui accompagne les événements tactiles. Le completedPaths
champ est une collection de chemins qui ont été terminés lorsqu’un doigt qui dessinait le chemin a été levé de l’écran.
Le TouchAction
gestionnaire gère ces deux collections. Lorsqu’un doigt touche l’écran pour la première fois, un nouveau SKPath
est ajouté à inProgressPaths
. À mesure que ce doigt se déplace, des points supplémentaires sont ajoutés au chemin. Lorsque le doigt est relâché, le chemin d’accès est transféré à la completedPaths
collection. Vous pouvez peindre avec plusieurs doigts simultanément. Après chaque modification apportée à l’un des chemins ou collections, est SKCanvasView
invalidé :
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));
}
}
Les points qui accompagnent les événements de suivi tactile sont Xamarin.Forms des coordonnées ; celles-ci doivent être converties en coordonnées SkiaSharp, qui sont des pixels. C’est l’objectif de la ConvertToPixel
méthode.
Le PaintSurface
gestionnaire affiche ensuite simplement les deux collections de chemins. Les chemins terminés précédemment s’affichent sous les chemins en cours :
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);
}
}
...
}
Vos peintures au doigt ne sont limitées que par votre talent :
Vous avez maintenant vu comment dessiner des lignes et définir des courbes à l’aide d’équations paramétriques. Une section ultérieure sur les courbes et chemins SkiaSharp couvre les différents types de courbes pris SKPath
en charge. Mais une condition préalable utile est l’exploration des transformations SkiaSharp.