Integración con Xamarin.Forms

Download SampleDescargar el ejemplo

Crear gráficos SkiaSharp que respondan al tacto y Xamarin.Formselementos

Los gráficos SkiaSharp se pueden integrar con el resto de Xamarin.Forms varias maneras. Puede combinar un lienzo y Xamarin.Forms elementos SkiaSharp en la misma página e incluso colocar Xamarin.Forms elementos sobre un lienzo SkiaSharp:

Selecting a color with sliders

Otro enfoque para crear gráficos de SkiaSharp interactivos en Xamarin.Forms es a través de la función táctil. La segunda página del programa SkiaSharpFormsDemos tiene el título Tap Toggle Fill. Dibuja un círculo simple de dos maneras, sin un relleno y con un relleno, alternado por una pulsación. La clase TapToggleFillPage muestra cómo se pueden modificar los gráficos SkiaSharp en respuesta a la entrada del usuario.

Para esta página, se crea una instancia de la clase SKCanvasView en el archivo de TapToggleFill.xaml, que también establece un Xamarin.FormsTapGestureRecognizer en la vista:

<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 la declaración de espacio de nombres XML skia.

El controlador de Tapped para el objeto TapGestureRecognizer simplemente alterna el valor de un campo booleano y llama al método InvalidateSurface de SKCanvasView:

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

La llamada a InvalidateSurface genera eficazmente una llamada al controlador de PaintSurface, que usa el campo showFill para rellenar o no el 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);
    }
}

La propiedad StrokeWidth se ha establecido en 50 para acentuar la diferencia. También puede ver el ancho de línea completo dibujando primero el interior y luego el contorno. De manera predeterminada, las figuras gráficas que se dibujan más adelante en el PaintSurface controlador de eventos ocultan las dibujadas anteriormente en el controlador.

La página Exploración de colores muestra cómo también puede integrar gráficos SkiaSharp con otros elementos Xamarin.Forms, y también muestra la diferencia entre dos métodos alternativos para definir colores en SkiaSharp. El método estático SKColor.FromHsl crea un SKColor valor basado en el modelo Hue-Saturación-Luz:

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

El método SKColor.FromHsv estático crea un valor de SKColor basado en el modelo hue-Saturación-Valor similar:

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

En ambos casos, el argumento h oscila entre 0 y 360. Los argumentos s, ly v van de 0 a 100. El argumento a (alfa o opacidad) oscila entre 0 y 255.

El archivo ColorExplorePage.xaml crea dos objetos SKCanvasView en un StackLayout en paralelo con Slider y vistas Label que permiten al usuario seleccionar valores de color HSL y 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>

Los dos elementos SKCanvasView están en un Grid de una sola celda con un Label sentado en la parte superior para mostrar el valor de color RGB resultante.

El ColorExplorePage.xaml.cs archivo de código subyacente es relativamente sencillo. El controlador de ValueChanged compartido para los tres elementos Slider simplemente invalida ambos elementos SKCanvasView. Los controladores PaintSurface borran el lienzo con el color indicado por los elementos Slider y también establecen el Label sentado sobre los elementos SKCanvasView:

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

En los modelos de color HSL y HSV, el valor de Hue oscila entre 0 y 360 e indica el tono dominante del color. Estos son los colores tradicionales del arco iris: rojo, naranja, amarillo, verde, azul, índigo, violeta y de vuelta en un círculo a rojo.

En el modelo HSL, un valor 0 para Claridad siempre es negro y un valor de 100 siempre es blanco. Cuando el valor saturación es 0, los valores de claridad entre 0 y 100 son tonos de gris. Aumentar la saturación agrega más color. Los colores puros (que son valores RGB con un componente igual a 255, otro igual a 0 y el tercero que va de 0 a 255) se producen cuando la saturación es 100 y la luz es 50.

En el modelo HSV, los colores puros resultan cuando la saturación y el valor son 100. Cuando Value es 0, independientemente de cualquier otra configuración, el color es negro. Los tonos grises se producen cuando la saturación es 0 y el valor oscila entre 0 y 100.

Pero la mejor manera de sentir los dos modelos es experimentar con ellos usted mismo:

Triple screenshot of the Color Explore page