Интеграция с Xamarin.Forms

Download Sample Скачайте пример

Создание графики SkiaSharp, реагирующей на сенсорные и Xamarin.Forms элементы

Графика SkiaSharp может интегрироваться с остальной Xamarin.Forms частью несколькими способами. Вы можете объединить холст SkiaSharp и Xamarin.Forms элементы на одной странице и даже разместить Xamarin.Forms элементы на холсте SkiaSharp:

Selecting a color with sliders

Другим подходом к созданию интерактивной графики SkiaSharp является Xamarin.Forms сенсорный интерфейс. Вторая страница в программе SkiaSharpFormsDemos имеет право на нажатие кнопки "Заливка". Он рисует простой круг двумя способами — без заливки и заливки — переключение касанием. В TapToggleFillPage классе показано, как изменить графику SkiaSharp в ответ на входные данные пользователя.

На этой странице SKCanvasView класс создается в файле TapToggleFill.xaml , который также задает Xamarin.FormsTapGestureRecognizer представление:

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

Обратите внимание на skia объявление пространства имен XML.

Обработчик Tapped объекта TapGestureRecognizer просто переключает значение логического поля и вызывает InvalidateSurface метод SKCanvasView:

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

Вызов InvalidateSurface для эффективного создания вызова обработчика PaintSurface , который использует showFill поле для заполнения или не заполняет круг:

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

Свойство StrokeWidth имеет значение 50, чтобы подчеркнуть разницу. Вы также можете увидеть всю ширину линии, нарисовав интерьер сначала, а затем контур. По умолчанию рисунки, рисуемые позже в PaintSurface обработчике событий, скрывают те, которые рисуются ранее в обработчике.

На странице "Обзор цвета" показано, как можно также интегрировать графику SkiaSharp с другими Xamarin.Forms элементами, а также демонстрирует разницу между двумя альтернативными методами определения цветов в SkiaSharp. SKColor.FromHsl Статический SKColor метод создает значение на основе модели Hue-Saturation-Lightness:

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

SKColor.FromHsv Статический SKColor метод создает значение на основе аналогичной модели Hue-Saturation-Value:

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

В обоих случаях h аргументы варьируются от 0 до 360. lАргументы sи v аргументы варьируются от 0 до 100. Аргумент a (альфа-или непрозрачность) диапазонов от 0 до 255.

Файл ColorExplorePage.xaml создает два SKCanvasView объекта параллельно StackLayout с Slider представлениями, Label которые позволяют пользователю выбирать значения цветов HSL и 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>

Эти два SKCanvasView элемента находятся в одной ячейке Grid с Label сидящим сверху для отображения результирующих значений цвета RGB.

Файл ColorExplorePage.xaml.cs программной части относительно прост. Общий ValueChanged обработчик для трех Slider элементов просто отменяет оба SKCanvasView элемента. Обработчики PaintSurface очищают холст с цветом Slider , указанными элементами, а также устанавливают Label сидячий наверх 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);
    }
}

В моделях цветов HSL и HSV значение Hue варьируется от 0 до 360 и указывает доминирующий оттенок цвета. Это традиционные цвета радуги: красный, оранжевый, желтый, зеленый, синий, индиго, фиолетовый и обратно в круг к красному.

В модели HSL значение 0 для Lightness всегда черное, а значение 100 всегда белое. Если значение насыщенности равно 0, значения света от 0 до 100 являются оттенками серого. Увеличение насыщенности добавляет больше цвета. Чистые цвета (которые являются значенияМИ RGB с одним компонентом равным 255, еще один равен 0, а третий диапазон от 0 до 255) возникает, когда насыщенность составляет 100, и светность составляет 50.

В модели HSV чистые цвета приводят к результату как насыщенности, так и значения 100. Если значение равно 0, независимо от других параметров, цвет черный. Серые оттенки происходят, когда насыщенность составляет 0, а значение — от 0 до 100.

Но лучший способ получить чувство для двух моделей заключается в том, чтобы экспериментировать с ними самостоятельно:

Triple screenshot of the Color Explore page