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:
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 s
argumentos , 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: