Disegno a mano libera in SkiaSharpFinger Painting in SkiaSharp

Scaricare l'esempio scaricare l'esempioDownload Sample Download the sample

Usare le dita per disegnare nell'area di disegno.Use your fingers to paint on the canvas.

Un SKPath oggetto può essere continuamente aggiornato e visualizzato.An SKPath object can be continually updated and displayed. Questa funzionalità consente a un percorso da utilizzare per il disegno interattiva, ad esempio in un programma dipingere.This feature allows a path to be used for interactive drawing, such as in a finger-painting program.

Il supporto per il tocco in xamarin. Forms non consente di rilevamento delle singole dita sullo schermo, in modo che un effetto di tocco di rilevamento di xamarin. Forms è stato sviluppato per fornire il supporto di tocco aggiuntive.The touch support in Xamarin.Forms does not allow tracking individual fingers on the screen, so a Xamarin.Forms touch-tracking effect has been developed to provide additional touch support. Questo effetto è descritto nell'articolo richiamo eventi dagli effetti.This effect is described in the article Invoking Events from Effects. Il programma di esempio Touch-rilevamento effetto demo include due pagine che utilizzano SkiaSharp, tra cui un programma dipingere.The sample program Touch-Tracking Effect Demos includes two pages that use SkiaSharp, including a finger-painting program.

Il SkiaSharpFormsDemos soluzione include questo evento di tocco di rilevamento.The SkiaSharpFormsDemos solution includes this touch-tracking event. Il progetto di libreria .NET Standard include la TouchEffect (classe), il TouchActionType enumerazione, la TouchActionEventHandler delegato e il TouchActionEventArgs classe.The .NET Standard library project includes the TouchEffect class, the TouchActionType enumeration, the TouchActionEventHandler delegate, and the TouchActionEventArgs class. Ognuno dei progetti della piattaforma include un' TouchEffect classe per la piattaforma, il progetto iOS contiene anche un TouchRecognizer classe.Each of the platform projects includes a TouchEffect class for that platform; the iOS project also contains a TouchRecognizer class.

Il dito Paint nella pagina SkiaSharpFormsDemos è un'implementazione semplificata di disegno a mano libera.The Finger Paint page in SkiaSharpFormsDemos is a simplified implementation of finger painting. Non consentire la selezione di colore o tracciare larghezza non è possibile cancellare l'area di disegno e ovviamente non è possibile salvare l'oggetto grafico.It does not allow selecting color or stroke width, it has no way to clear the canvas, and of course you can't save your artwork.

Il FingerPaintPage.xaml file inserisce il SKCanvasView in una cella singola Grid e la collega il TouchEffect a quella Grid:The FingerPaintPage.xaml file puts the SKCanvasView in a single-cell Grid and attaches the TouchEffect to that 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>

Collegare il TouchEffect direttamente al SKCanvasView non funziona in tutte le piattaforme.Attaching the TouchEffect directly to the SKCanvasView does not work under all platforms.

Il FingerPaintPage.xaml.cs file code-behind definisce due raccolte per l'archiviazione la SKPath oggetti, nonché un SKPaint oggetto per il rendering di questi percorsi:The FingerPaintPage.xaml.cs code-behind file defines two collections for storing the SKPath objects, as well as an SKPaint object for rendering these paths:

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 che sono attualmente in corso disegnati in una o più dita.As the name suggests, the inProgressPaths dictionary stores the paths that are currently being drawn by one or more fingers. La chiave del dizionario è l'ID tocco che accompagna gli eventi di tocco.The dictionary key is the touch ID that accompanies the touch events. Il completedPaths campo è una raccolta di percorsi che sono state terminate quando un dito che era il percorso di disegno sollevato dallo schermo.The completedPaths field is a collection of paths that were finished when a finger that was drawing the path lifted from the screen.

Il TouchAction gestore gestisce questi due insiemi.The TouchAction handler manages these two collections. Quando un dito tocca prima schermata, una nuova SKPath viene aggiunto a inProgressPaths.When a finger first touches the screen, a new SKPath is added to inProgressPaths. Come si sposta il dito, punti aggiuntivi vengono aggiunti al percorso.As that finger moves, additional points are added to the path. Quando viene rilasciato il dito, il percorso viene trasferito al completedPaths raccolta.When the finger is released, the path is transferred to the completedPaths collection. È possibile disegnare con più dita contemporaneamente.You can paint with multiple fingers simultaneously. Dopo ogni modifica apportata a uno dei percorsi o le raccolte, il SKCanvasView viene invalidata:After each change to one of the paths or collections, the SKCanvasView is invalidated:

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 di tocco sono coordinate di xamarin. Forms; questi devono essere convertiti alle coordinate di SkiaSharp, quali sono i pixel.The points accompanying the touch-tracking events are Xamarin.Forms coordinates; these must be converted to SkiaSharp coordinates, which are pixels. Lo scopo del ConvertToPixel (metodo).That's the purpose of the ConvertToPixel method.

Il PaintSurface gestore quindi semplicemente esegue il rendering di entrambe le raccolte dei percorsi.The PaintSurface handler then simply renders both collections of paths. Sotto i percorsi in corso verranno visualizzati i percorsi completati in precedenza:The earlier completed paths appear underneath the paths in progress:

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);
        }
    }
    ...
}

Dipinti i dito sono limitate solo dai dimostra il tuo talento:Your finger paintings are only limited by your talent:

A questo punto si è appreso come per disegnare linee e curve utilizzando equazioni parametriche definire.You've now seen how to draw lines and to define curves using parametric equations. Una sezione successiva sul SkiaSharp curve e tracciati illustra i vari tipi di curve che SKPath supporta.A later section on SkiaSharp Curves and Paths covers the various types of curves that SKPath supports. Ma un prerequisito utile prevede un'esplorazione dei trasformazioni di SkiaSharp.But a useful prerequisite is an exploration of SkiaSharp Transforms.