Malování prstem ve skiaSharpu

Pomocí prstů nakreslujte na plátně.

Objekt SKPath lze průběžně aktualizovat a zobrazit. Tato funkce umožňuje použít cestu pro interaktivní kreslení, například v programu kreslení prstem.

Cvičení malování prstem

Podpora Xamarin.Forms dotykového ovládání neumožňuje sledování jednotlivých prstů na obrazovce, takže byl vyvinut efekt pro sledování dotykového ovládání, který Xamarin.Forms poskytuje další podporu dotykového ovládání. Tento efekt je popsán v článku Vyvolání událostí z efektů. Ukázkový program obsahuje dvě stránky, které používají SkiaSharp, včetně programu malování prstem.

Ukázkové řešení zahrnuje tuto událost dotykového sledování. Projekt knihovny .NET Standard zahrnuje TouchEffect třídu, TouchActionType výčet, TouchActionEventHandler delegáta a TouchActionEventArgs třídu. Každý z projektů platformy zahrnuje třídu pro danou TouchEffect platformu; projekt iOS obsahuje TouchRecognizer také třídu.

Stránka Malování Prst v SkiaSharpFormsDemos je zjednodušená implementace malování prstem. Neumožňuje výběr barvy nebo šířky tahu, nemá způsob, jak vymazat plátno a samozřejmě nemůžete uložit kresbu.

Soubor Finger Malování Page.xaml umístí do SKCanvasView jedné buňky Grid a připojí TouchEffect k tomuGrid:

<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 Připojení přímo k SKCanvasView sadě nefunguje na všech platformách.

Soubor Prst Malování Page.xaml.cs za kódem definuje dvě kolekce pro ukládání SKPath objektů a objekt SKPaint pro vykreslení těchto cest:

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

Jak název napovídá, inProgressPaths slovník ukládá cesty, které jsou aktuálně kresleny jedním nebo více prsty. Klíč slovníku je touch ID, které doprovází dotykové události. Pole completedPaths je kolekce cest, které byly dokončeny, když prst nakreslený cestou zvedl z obrazovky.

Obslužná rutina TouchAction spravuje tyto dvě kolekce. Když se prst poprvé dotkne obrazovky, přidá se do inProgressPathssouboru nový SKPath . Při přesouvání prstu se do cesty přidají další body. Po uvolnění prstu se cesta přesune do completedPaths kolekce. Můžete malovat více prsty současně. Po každé změně jedné z cest nebo kolekcí dojde k SKCanvasView zneplatnění:

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

Body, které doprovázejí události dotykového ovládání, jsou Xamarin.Forms souřadnice; musí být převedeny na souřadnice SkiaSharp, což jsou pixely. To je účel ConvertToPixel metody.

Obslužná rutina PaintSurface pak jednoduše vykreslí obě kolekce cest. Dříve dokončené cesty se zobrazují pod probíhajícími cestami:

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

Malování prsty jsou omezeny pouze vaším talentem:

Trojitý snímek obrazovky se stránkou Malování prstem

Seznámili jste se s tím, jak nakreslit čáry a definovat křivky pomocí parametrických rovnic. Další část o křivkách a cestách SkiaSharp pokrývá různé typy křivek, které SKPath podporují. Užitečným předpokladem je prozkoumání transformací SkiaSharp.