Desenhando um círculo simples no SkiaSharp

Aprenda os conceitos básicos do desenho SkiaSharp, incluindo telas e objetos de pintura

Este artigo apresenta os conceitos de desenho de elementos gráficos no Xamarin.Forms uso do SkiaSharp, incluindo a criação de um SKCanvasView objeto para hospedar os elementos gráficos, a manipulação do evento e o PaintSurface uso de um SKPaint objeto para especificar a cor e outros atributos de desenho.

O programa de exemplo contém todo o código de exemplo para esta série de artigos SkiaSharp. A primeira página é intitulada Simple Circle e invoca a classe SimpleCirclePagede página . Este código mostra como desenhar um círculo no centro da página com um raio de 100 pixels. O contorno do círculo é vermelho e o interior do círculo é azul.

Um círculo azul delineado em vermelho

A SimpleCircle classe de página deriva de ContentPage e contém duas using diretivas para os namespaces SkiaSharp:

using SkiaSharp;
using SkiaSharp.Views.Forms;

O seguinte construtor da classe cria um SKCanvasView objeto, anexa um manipulador para o PaintSurface evento e define o SKCanvasView objeto como o conteúdo da página:

public SimpleCirclePage()
{
    Title = "Simple Circle";

    SKCanvasView canvasView = new SKCanvasView();
    canvasView.PaintSurface += OnCanvasViewPaintSurface;
    Content = canvasView;
}

O SKCanvasView ocupa toda a área de conteúdo da página. Você pode alternativamente combinar um SKCanvasView com outros Xamarin.FormsView derivados, como você verá em outros exemplos.

O PaintSurface manipulador de eventos é onde você faz todo o desenho. Esse método pode ser chamado várias vezes enquanto o programa está em execução, portanto, ele deve manter todas as informações necessárias para recriar a exibição de gráficos:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
}

O SKPaintSurfaceEventArgs objeto que acompanha o evento tem duas propriedades:

A SKImageInfo estrutura contém informações sobre a superfície de desenho, mais importante, sua largura e altura em pixels. O SKSurface objeto representa a própria superfície de desenho. Neste programa, a superfície de desenho é uma exibição de vídeo, mas em outros programas um SKSurface objeto também pode representar um bitmap que você usa SkiaSharp para desenhar.

A propriedade mais importante de SKSurface é Canvas do tipo SKCanvas. Essa classe é um contexto de desenho gráfico que você usa para executar o desenho real. O SKCanvas objeto encapsula um estado gráfico, que inclui transformações e recorte de gráficos.

Aqui está um início típico de um PaintSurface manipulador de eventos:

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

    canvas.Clear();
    ...
}

O Clear método limpa a tela com uma cor transparente. Uma sobrecarga permite especificar uma cor de plano de fundo para a tela.

O objetivo aqui é desenhar um círculo vermelho cheio de azul. Como essa imagem gráfica específica contém duas cores diferentes, o trabalho precisa ser feito em duas etapas. O primeiro passo é desenhar o contorno do círculo. Para especificar a cor e outra característica da linha, crie e inicialize um SKPaint objeto:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    SKPaint paint = new SKPaint
    {
        Style = SKPaintStyle.Stroke,
        Color = Colors.Red.ToSKColor(),
        StrokeWidth = 25
    };
    ...
}

A Style propriedade indica que você deseja traçar uma linha (neste caso, o contorno do círculo) em vez de preencher o interior. Os três membros da enumeração são os SKPaintStyle seguintes:

O padrão é Fill. Use a terceira opção para traçar a linha e preencher o interior com a mesma cor.

Defina a Color propriedade como um valor do tipo SKColor. Uma maneira de obter um SKColor valor é convertendo um Xamarin.FormsColor valor em um SKColor valor usando o método ToSKColorde extensão . A Extensions classe no SkiaSharp.Views.Forms namespace inclui outros métodos que convertem entre Xamarin.Forms valores e valores SkiaSharp.

A StrokeWidth propriedade indica a espessura da linha. Aqui ele é definido para 25 pixels.

Use esse SKPaint objeto para desenhar o círculo:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    canvas.DrawCircle(info.Width / 2, info.Height / 2, 100, paint);
    ...
}

As coordenadas são especificadas em relação ao canto superior esquerdo da superfície de exibição. As coordenadas X aumentam para a direita e as coordenadas Y aumentam descendo. Na discussão sobre gráficos, muitas vezes a notação matemática (x, y) é usada para denotar um ponto. O ponto (0, 0) é o canto superior esquerdo da superfície de exibição e é frequentemente chamado de origem.

Os dois primeiros argumentos de DrawCircle indicam as coordenadas X e Y do centro do círculo. Eles são atribuídos à metade da largura e altura da superfície de exibição para colocar o centro do círculo no centro da superfície de exibição. O terceiro argumento especifica o raio do círculo e o último argumento é o SKPaint objeto.

Para preencher o interior do círculo, você pode alterar duas propriedades do SKPaint objeto e chamar DrawCircle novamente. Esse código também mostra uma maneira alternativa de obter um SKColor valor de um dos muitos campos da SKColors estrutura:

void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
    ...
    paint.Style = SKPaintStyle.Fill;
    paint.Color = SKColors.Blue;
    canvas.DrawCircle(args.Info.Width / 2, args.Info.Height / 2, 100, paint);
}

Desta vez, a DrawCircle chamada preenche o círculo usando as SKPaint novas propriedades do objeto.

Aqui está o programa em execução no iOS e Android:

Captura de tela tripla da página Círculo Simples

Ao executar o programa sozinho, você pode virar o telefone ou simulador para os lados para ver como o gráfico é redesenhado. Cada vez que o gráfico precisa ser redesenhado, o PaintSurface manipulador de eventos é chamado novamente.

Também é possível colorir objetos gráficos com gradientes ou blocos de bitmap. Essas opções são discutidas na seção sobre sombreadores SkiaSharp.

Um SKPaint objeto é pouco mais do que uma coleção de propriedades de desenho gráfico. Esses objetos são leves. Você pode reutilizar SKPaint objetos como este programa faz, ou você pode criar vários SKPaint objetos para várias combinações de propriedades de desenho. Você pode criar e inicializar esses objetos fora do manipulador de eventos e salvá-los como campos em sua classe de PaintSurface página.

Observação

A SKPaint classe define um IsAntialias para habilitar a suavização de borda na renderização de seus elementos gráficos. A suavização de borda geralmente resulta em bordas visualmente mais suaves, então você provavelmente desejará definir essa propriedade como true na maioria dos seus SKPaint objetos. Para fins de simplicidade, essa propriedade não é definida na maioria das páginas de exemplo.

Embora a largura do contorno do círculo seja especificada como 25 pixels — ou um quarto do raio do círculo — ele parece ser mais fino, e há uma boa razão para isso: metade da largura da linha é obscurecida pelo círculo azul. Os argumentos para o DrawCircle método definem as coordenadas geométricas abstratas de um círculo. O interior azul é dimensionado para essa dimensão até o pixel mais próximo, mas o contorno de 25 pixels de largura atravessa o círculo geométrico - metade por dentro e metade por fora.

O próximo exemplo no artigo Integrando com Xamarin.Forms demonstra isso visualmente.