共用方式為


與整合 Xamarin.Forms

建立可響應觸控和 Xamarin.Forms 元素的SkiaSharp圖形

SkiaSharp 圖形可以透過數種方式與其餘部分 Xamarin.Forms 整合。 您可以在相同的頁面上結合 SkiaSharp 畫布和 Xamarin.Forms 元素,甚至將元素放置在 Xamarin.Forms SkiaSharp 畫布上方:

選取具有滑桿的色彩

在中 Xamarin.Forms 建立互動式 SkiaSharp 圖形的另一種方法是透過觸控。

範例程式中的第二頁名為 [點選切換填滿]。 它會以兩種方式繪製簡單的圓形, 沒有填滿和填滿 — 由點選切換。 類別 TapToggleFillPage 示範如何改變 SkiaSharp 圖形以回應用戶輸入。

針對此頁面,類別會在 TapToggleFill.xaml 檔案中具現化,該檔案也會在檢視上設定 : SKCanvasViewXamarin.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 只會切換布爾值欄位的值,並呼叫 InvalidateSurfaceSKCanvasView方法:

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

的呼叫會有效產生處理程式的PaintSurface呼叫InvalidateSurface,該處理程式會使用 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 方法會根據 Hue-Saturation-Lightness 模型建立 SKColor 值:

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

靜態 SKColor.FromHsv 方法會根據類似的 Hue-Saturation-Value 模型建立 SKColor 值:

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

在這兩種情況下,自 h 變數的範圍從 0 到 360。 slv 自變數的範圍從 0 到 100。 a (alpha 或不透明度) 自變數的範圍從 0 到 255。

ColorExplorePage.xaml 檔案會與 檢視並排Slider建立兩SKCanvasViewStackLayout物件,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>

這兩SKCanvasViewLabel元素位於單一數據格Grid中,其位於頂端,以顯示產生的 RGB 色彩值。

程序 代碼後置檔案ColorExplorePage.xaml.cs 相對簡單。 這三Slider個元素的共享ValueChanged處理程式只會使這兩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 模型中,Lightness 的 0 值一律為黑色,而 100 值一律為白色。 當飽和度值為 0 時,介於 0 到 100 之間的淺度值為灰色陰影。 增加飽和度會增加更多色彩。 純色(其中一個元件等於 255 的 RGB 值,另一個元件等於 0,而第三個範圍從 0 到 255)發生在飽和度為 100 且光度為 50 時。

在 HSV 模型中,純色會在飽和度和值為 100 時產生。 當 Value 為 0 時,不論任何其他設定為何,色彩都是黑色。 當飽和度為 0 且 Value 範圍從 0 到 100 時,就會發生灰色陰影。

但獲得這兩個模型感覺的最佳方式是自行試驗:

色彩探索頁面的三重螢幕快照