Integración con Xamarin.Forms
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:
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 de ejemplo tiene el título Tap Toggle Fill(Pulsar relleno). 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
, l
y 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: