Интеграция с Xamarin.Forms
Создание графики SkiaSharp, реагирующей на сенсорные и Xamarin.Forms элементы
Графика SkiaSharp может интегрироваться с остальной Xamarin.Forms частью несколькими способами. Вы можете объединить холст SkiaSharp и Xamarin.Forms элементы на одной странице и даже разместить Xamarin.Forms элементы на холсте SkiaSharp:
Другим подходом к созданию интерактивной графики SkiaSharp является Xamarin.Forms сенсорный интерфейс.
Вторая страница в примере программы имеет право на нажатие кнопки "Заливка". Он рисует простой круг двумя способами — без заливки и заливки — переключение касанием. В 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.
Но лучший способ получить чувство для двух моделей заключается в том, чтобы экспериментировать с ними самостоятельно: