Integrando com Xamarin.Forms

Crie gráficos SkiaSharp que respondam ao toque e Xamarin.Forms aos elementos

Os gráficos SkiaSharp podem se integrar com o resto de Xamarin.Forms várias maneiras. Você pode combinar uma tela do SkiaSharp e Xamarin.Forms elementos na mesma página e até mesmo posicionar Xamarin.Forms elementos em cima de uma tela do SkiaSharp:

Selecionando uma cor com controles deslizantes

Outra abordagem para criar gráficos interativos do SkiaSharp é Xamarin.Forms através do toque.

A segunda página do programa de exemplo é intitulada Toque em Alternar preenchimento. Ele desenha um círculo simples de duas maneiras - sem preenchimento e com preenchimento - alternado por um toque. A TapToggleFillPage aula mostra como você pode alterar os gráficos do SkiaSharp em resposta à entrada do usuário.

Para esta página, a SKCanvasView classe é instanciada no arquivo TapToggleFill.xaml , que também define um Xamarin.FormsTapGestureRecognizer no modo de exibição:

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

Observe a declaração de skia namespace XML.

O Tapped manipulador do TapGestureRecognizer objeto simplesmente alterna o valor de um campo booleano e chama o InvalidateSurface método de SKCanvasView:

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

A chamada para InvalidateSurface gera efetivamente uma chamada para o PaintSurface manipulador, que usa o showFill campo para preencher ou não o círculo:

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

A StrokeWidth propriedade foi definida como 50 para acentuar a diferença. Você também pode ver toda a largura da linha desenhando primeiro o interior e depois o contorno. Por padrão, as figuras gráficas desenhadas posteriormente no PaintSurface manipulador de eventos obscurecem as desenhadas anteriormente no manipulador.

A página Color Explore demonstra como você também pode integrar gráficos do SkiaSharp com outros Xamarin.Forms elementos e também demonstra a diferença entre dois métodos alternativos para definir cores no SkiaSharp. O método estático SKColor.FromHsl cria um SKColor valor com base no modelo Matiz-Saturação-Luminosidade:

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

O método estático SKColor.FromHsv cria um SKColor valor com base no modelo semelhante de Matiz-Saturação-Valor:

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

Em ambos os casos, o h argumento varia de 0 a 360. Os sargumentos , l, e v variam de 0 a 100. O a argumento (alfa ou opacidade) varia de 0 a 255.

O arquivo ColorExplorePage.xaml cria dois SKCanvasView objetos lado StackLayout a lado com Slider e Label exibições que permitem ao usuário selecionar valores de cor HSL e 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>

Os dois SKCanvasView elementos estão em uma única célula Grid com um Label assento na parte superior para exibir o valor de cor RGB resultante.

O ColorExplorePage.xaml.cs arquivo code-behind é relativamente simples. O manipulador compartilhado ValueChanged para os três Slider elementos simplesmente invalida ambos os SKCanvasView elementos. Os PaintSurface manipuladores limpam a tela com a cor indicada Slider pelos elementos e também definem a Label sessão em cima dos SKCanvasView elementos:

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

Nos modelos de cores HSL e HSV, o valor de Matiz varia de 0 a 360 e indica o matiz dominante da cor. Estas são as cores tradicionais do arco-íris: vermelho, laranja, amarelo, verde, azul, índigo, violeta e de volta em um círculo para o vermelho.

No modelo HSL, um valor 0 para Luminosidade é sempre preto e um valor 100 é sempre branco. Quando o valor de Saturação é 0, os valores de Luminosidade entre 0 e 100 são tons de cinza. Aumentar a saturação adiciona mais cor. As cores puras (que são valores RGB com um componente igual a 255, outro igual a 0 e o terceiro variando de 0 a 255) ocorrem quando a saturação é 100 e a luminosidade é 50.

No modelo HSV, as cores puras resultam quando a Saturação e o Valor são 100. Quando Valor é 0, independentemente de quaisquer outras configurações, a cor é preta. Os tons de cinza ocorrem quando a saturação é 0 e o valor varia de 0 a 100.

Mas a melhor maneira de ter uma ideia dos dois modelos é experimentá-los você mesmo:

Captura de tela tripla da página Color Explore