Udostępnij za pośrednictwem


Integrowanie z usługą Xamarin.Forms

Tworzenie grafiki SkiaSharp reagującej na dotyk i Xamarin.Forms elementy

Grafika SkiaSharp może być zintegrowana z resztą na Xamarin.Forms kilka sposobów. Możesz połączyć kanwę SkiaSharp i Xamarin.Forms elementy na tej samej stronie, a nawet umieścić Xamarin.Forms elementy na kanwie SkiaSharp:

Wybieranie koloru za pomocą suwaków

Innym podejściem do tworzenia interaktywnej grafiki SkiaSharp w programie Xamarin.Forms jest dotyk.

Druga strona w przykładowym programie ma tytuł Tap Toggle Fill (Przełącz wypełnienie). Rysuje proste kółko na dwa sposoby — bez wypełnienia i z wypełnieniem — przełączane przez naciśnięcie. Klasa TapToggleFillPage pokazuje, jak można zmienić grafikę SkiaSharp w odpowiedzi na dane wejściowe użytkownika.

Na tej stronie klasa SKCanvasView jest tworzone w pliku TapToggleFill.xaml , który również ustawia obiekt Xamarin.FormsTapGestureRecognizer w widoku:

<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"
             x:Class="SkiaSharpFormsDemos.TapToggleFillPage"
             Title="Tap Toggle Fill">

    <skia:SKCanvasView PaintSurface="OnCanvasViewPaintSurface">
        <skia:SKCanvasView.GestureRecognizers>
            <TapGestureRecognizer Tapped="OnCanvasViewTapped" />
        </skia:SKCanvasView.GestureRecognizers>
    </skia:SKCanvasView>
</ContentPage>

Zwróć uwagę na deklarację skia przestrzeni nazw XML.

Procedura Tapped obsługi obiektu TapGestureRecognizer po prostu przełącza wartość pola logicznego i wywołuje metodę InvalidateSurface SKCanvasView:

bool showFill = true;
...
void OnCanvasViewTapped(object sender, EventArgs args)
{
    showFill ^= true;
    (sender as SKCanvasView).InvalidateSurface();
}

Wywołanie w celu InvalidateSurface efektywnego wygenerowania wywołania PaintSurface programu obsługi, które używa showFill pola do wypełnienia lub braku wypełnienia okręgu:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    SKImageInfo info = args.Info;
    SKSurface surface = args.Surface;
    SKCanvas canvas = surface.Canvas;

    canvas.Clear();

    SKPaint paint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = Color.Red.ToSKColor(),
        StrokeWidth = 50
    };
    canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);

    if (showFill)
    {
        paint.Style = SKPaintStyle.Fill;
        paint.Color = SKColors.Blue;
        canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
    }
}

Właściwość StrokeWidth została ustawiona na 50, aby podkreślić różnicę. Możesz również zobaczyć całą szerokość linii, rysując najpierw wnętrze, a następnie kontur. Domyślnie rysunki graficzne rysowane w PaintSurface dalszej części programu obsługi zdarzeń ukrywają te rysowane wcześniej w procedurze obsługi.

Na stronie Color Explore pokazano, jak można również zintegrować grafikę SkiaSharp z innymi Xamarin.Forms elementami, a także pokazuje różnicę między dwiema alternatywnymi metodami definiowania kolorów w usłudze SkiaSharp. Metoda statyczna SKColor.FromHsl tworzy SKColor wartość na podstawie modelu Hue-Saturation-Lightness:

public static SKColor FromHsl (Single h, Single s, Single l, Byte a)

Metoda statyczna SKColor.FromHsv tworzy SKColor wartość na podstawie podobnego modelu Hue-Saturation-Value:

public static SKColor FromHsv (Single h, Single s, Single v, Byte a)

W obu przypadkach h argumenty wahają się od 0 do 360. Argumenty s, li v wahają się od 0 do 100. Argumenty a (alfa lub nieprzezroczystości) wahają się od 0 do 255.

Plik ColorExplorePage.xaml tworzy dwa SKCanvasView obiekty StackLayout obok siebie i Slider Label widoki, które umożliwiają użytkownikowi wybieranie wartości kolorów HSL i HSV:

<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"
             x:Class="SkiaSharpFormsDemos.Basics.ColorExplorePage"
             Title="Color Explore">
    <StackLayout>
        <!-- Hue slider -->
        <Slider x:Name="hueSlider"
                Maximum="360"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference hueSlider},
                              Path=Value,
                              StringFormat='Hue = {0:F0}'}" />

        <!-- Saturation slider -->
        <Slider x:Name="saturationSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference saturationSlider},
                              Path=Value,
                              StringFormat='Saturation = {0:F0}'}" />

        <!-- Lightness slider -->
        <Slider x:Name="lightnessSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference lightnessSlider},
                              Path=Value,
                              StringFormat='Lightness = {0:F0}'}" />

        <!-- HSL canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hslCanvasView"
                               PaintSurface="OnHslCanvasViewPaintSurface" />

            <Label x:Name="hslLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>

        <!-- Value slider -->
        <Slider x:Name="valueSlider"
                Maximum="100"
                Margin="20, 0"
                ValueChanged="OnSliderValueChanged" />

        <Label HorizontalTextAlignment="Center"
               Text="{Binding Source={x:Reference valueSlider},
                              Path=Value,
                              StringFormat='Value = {0:F0}'}" />

        <!-- HSV canvas view -->
        <Grid VerticalOptions="FillAndExpand">
            <skia:SKCanvasView x:Name="hsvCanvasView"
                               PaintSurface="OnHsvCanvasViewPaintSurface" />

            <Label x:Name="hsvLabel"
                   HorizontalOptions="Center"
                   VerticalOptions="Center"
                   BackgroundColor="Black"
                   TextColor="White" />
        </Grid>
    </StackLayout>
</ContentPage>

Dwa SKCanvasView elementy znajdują się w jednej komórce Grid z Label siedzeniem na górze w celu wyświetlenia wynikowej wartości koloru RGB.

Plik ColorExplorePage.xaml.cs jest stosunkowo prosty. Udostępniona ValueChanged procedura obsługi dla trzech Slider elementów po prostu unieważnia oba SKCanvasView elementy. Programy PaintSurface obsługi czyściją kanwę z kolorem wskazywanymi przez Slider elementy, a także ustawiają Label siedzenie na górze SKCanvasView elementów:

public partial class ColorExplorePage : ContentPage
{
    public ColorExplorePage()
    {
        InitializeComponent();

        hueSlider.Value = 0;
        saturationSlider.Value = 100;
        lightnessSlider.Value = 50;
        valueSlider.Value = 100;
    }

    void OnSliderValueChanged(object sender, ValueChangedEventArgs args)
    {
        hslCanvasView.InvalidateSurface();
        hsvCanvasView.InvalidateSurface();
    }

    void OnHslCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsl((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)lightnessSlider.Value);
        args.Surface.Canvas.Clear(color);

        hslLabel.Text = String.Format(" RGB = {0:X2}-{1:X2}-{2:X2} ",
                                      color.Red, color.Green, color.Blue);
    }

    void OnHsvCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
    {
        SKColor color = SKColor.FromHsv((float)hueSlider.Value,
                                        (float)saturationSlider.Value,
                                        (float)valueSlider.Value);
        args.Surface.Canvas.Clear(color);

        hsvLabel.Text = String.Format(" RGB = {0:X2}-{1:X2}-{2:X2} ",
                                      color.Red, color.Green, color.Blue);
    }
}

Zarówno w modelach kolorów HSL, jak i HSV wartość Hue waha się od 0 do 360 i wskazuje dominujący odcień koloru. Są to tradycyjne kolory tęczy: czerwony, pomarańczowy, żółty, zielony, niebieski, indigo, fioletowy i z powrotem w okręgu na czerwony.

W modelu HSL wartość 0 dla lightness jest zawsze, a wartość 100 jest zawsze biała. Gdy wartość nasycenia wynosi 0, wartości lekkości z zakresu od 0 do 100 są odcieniami szarości. Zwiększenie nasycenia zwiększa kolor. Czyste kolory (które są wartościami RGB z jednym składnikiem równym 255, inne równe 0, a trzeci z zakresu od 0 do 255) występują, gdy nasycenie wynosi 100, a światło wynosi 50.

W modelu HSV czystych kolorów wynik, gdy nasycenie i wartość wynosi 100. Gdy wartość to 0, niezależnie od innych ustawień, kolor jest. Szare odcienie występują, gdy nasycenie wynosi 0, a wartości wahają się od 0 do 100.

Ale najlepszym sposobem, aby poczuć się dla dwóch modeli, jest eksperymentowanie z nimi samodzielnie:

Potrójny zrzut ekranu przedstawiający stronę Eksplorowanie kolorów