Udostępnij za pośrednictwem


Obraz palca w SkiaSharp

Użyj palców, aby malować na kanwie.

Obiekt SKPath może być stale aktualizowany i wyświetlany. Ta funkcja umożliwia użycie ścieżki do interaktywnego rysowania, takiego jak w programie malowania palcami.

Ćwiczenie w malowaniu palcami

Obsługa dotykowa w Xamarin.Forms systemie nie umożliwia śledzenia pojedynczych palców na ekranie, dlatego Xamarin.Forms opracowano efekt śledzenia dotykowego w celu zapewnienia dodatkowej obsługi dotykowej. Ten efekt został opisany w artykule Wywoływanie zdarzeń z efektów. Przykładowy program zawiera dwie strony korzystające z biblioteki SkiaSharp, w tym program malowania palcami.

Przykładowe rozwiązanie obejmuje to zdarzenie śledzenia dotykowego. Projekt biblioteki .NET Standard obejmuje klasę TouchEffect , TouchActionType wyliczenie, TouchActionEventHandler delegat i klasę TouchActionEventArgs . Każdy projekt platformy zawiera klasę TouchEffect dla tej platformy. Projekt systemu iOS zawiera również klasę TouchRecognizer .

Strona Finger Paint w SkiaSharpFormsDemos to uproszczona implementacja malowania palcami. Nie zezwala na wybór koloru lub szerokości pociągnięcia, nie ma możliwości wyczyszczenia kanwy i oczywiście nie można zapisać grafiki.

Plik FingerPaintPage.xaml umieszcza SKCanvasView element w jednej komórce Grid i dołącza TouchEffect element do tego Gridpliku :

<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>

Dołączanie TouchEffect bezpośrednio do programu SKCanvasView nie działa na wszystkich platformach.

Plik FingerPaintPage.xaml.cs kodu definiuje dwie kolekcje do przechowywania SKPath obiektów, a także SKPaint obiekt do renderowania następujących ścieżek:

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 sugeruje nazwa, inProgressPaths słownik przechowuje ścieżki, które są obecnie rysowane przez co najmniej jeden palec. Klucz słownika to identyfikator dotykowy, który towarzyszy zdarzeń dotykowych. Pole completedPaths jest kolekcją ścieżek, które zostały zakończone, gdy palec, który rysował ścieżkę podniesioną z ekranu.

Program TouchAction obsługi zarządza tymi dwiema kolekcjami. Gdy palec po raz pierwszy dotyka ekranu, do elementu zostanie dodany inProgressPathsnowy SKPath element . W miarę poruszania się palcem do ścieżki są dodawane dodatkowe punkty. Po zwolnieniu palca ścieżka jest przenoszona do completedPaths kolekcji. Można malować jednocześnie wieloma palcami. Po każdej zmianie na jedną ze ścieżek lub kolekcji SKCanvasView element jest unieważniany:

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

Punkty towarzyszące zdarzeń śledzenia dotykowego są Xamarin.Forms współrzędnymi. Muszą one być konwertowane na współrzędne SkiaSharp, które są pikselami. Jest to cel ConvertToPixel metody .

Następnie PaintSurface program obsługi renderuje obie kolekcje ścieżek. Wcześniejsze ukończone ścieżki są wyświetlane poniżej ścieżek w toku:

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

Twoje obrazy palców są ograniczone tylko przez twój talent:

Potrójny zrzut ekranu przedstawiający stronę Finger Paint

Wiesz już, jak rysować linie i definiować krzywe przy użyciu równań parametrycznych. Późniejsza sekcja na temat krzywych i ścieżek SkiaSharp obejmuje różne typy krzywych, które SKPath obsługują. Ale przydatne wymaganie wstępne to eksploracja przekształceń SkiaSharp.