Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Třída SKShader definuje statické metody pro vytvoření čtyř různých typů přechodů. Článek o lineárním přechodu SkiaSharp popisuje metodu CreateLinearGradient . Tento článek se zabývá dalšími třemi typy přechodů, z nichž všechny jsou založené na kruhech.
Metoda CreateRadialGradient vytvoří přechod, který vychází ze středu kruhu:

Metoda CreateSweepGradient vytvoří přechod, který zamíchá kolem středu kruhu:

Třetí typ přechodu je poměrně neobvyklý. Nazývá se dvoubodový kuželový přechod a je definován metodou CreateTwoPointConicalGradient . Přechod se rozšiřuje z jednoho kruhu na druhý:

Pokud jsou oba kruhy různé velikosti, přechod má tvar kužele.
Tento článek podrobněji zkoumá tyto přechody.
Paprskový přechod
Metoda CreateRadialGradient má následující syntaxi:
public static SKShader CreateRadialGradient (SKPoint center,
Single radius,
SKColor[] colors,
Single[] colorPos,
SKShaderTileMode mode)
Přetížení CreateRadialGradient obsahuje také parametr transformační matice.
První dva argumenty určují střed kruhu a poloměr. Přechod začíná na středu a rozšiřuje směrem ven pro radius pixely. Co se stane nad rámec radius , závisí na argumentu SKShaderTileMode . Parametr colors je matice dvou nebo více barev (stejně jako v metodách lineárního přechodu) a colorPos je pole celých čísel v rozsahu 0 až 1. Tato celá čísla označují relativní pozice barev podél této radius čáry. Tento argument můžete nastavit tak, aby null se barvy vyrovnaly.
Pokud použijete CreateRadialGradient k vyplnění kruhu, můžete nastavit střed přechodu na střed kruhu a poloměr přechodu na poloměr kruhu. V takovém případě SKShaderTileMode nemá argument žádný vliv na vykreslení přechodu. Pokud je ale oblast vyplněná přechodem větší než kruh definovaný přechodem, má SKShaderTileMode argument hluboký vliv na to, co se stane mimo kruh.
Účinek SKShaderMode je ukázaný na stránce paprskového přechodu v ukázce. Soubor XAML pro tuto stránku vytvoří Picker instanci, která umožňuje vybrat jeden ze tří členů výčtu SKShaderTileMode :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
xmlns:skiaforms="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
x:Class="SkiaSharpFormsDemos.Effects.RadialGradientPage"
Title="Radial Gradient">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<skiaforms:SKCanvasView x:Name="canvasView"
Grid.Row="0"
PaintSurface="OnCanvasViewPaintSurface" />
<Picker x:Name="tileModePicker"
Grid.Row="1"
Title="Shader Tile Mode"
Margin="10"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKShaderTileMode}">
<x:Static Member="skia:SKShaderTileMode.Clamp" />
<x:Static Member="skia:SKShaderTileMode.Repeat" />
<x:Static Member="skia:SKShaderTileMode.Mirror" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
</Grid>
</ContentPage>
Soubor s kódem se vybarví na celé plátno s paprskovým přechodem. Střed přechodu je nastavený na střed plátna a poloměr je nastavený na 100 pixelů. Přechod se skládá jenom ze dvou barev, černé a bílé:
public partial class RadialGradientPage : ContentPage
{
public RadialGradientPage ()
{
InitializeComponent ();
}
void OnPickerSelectedIndexChanged(object sender, EventArgs args)
{
canvasView.InvalidateSurface();
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKShaderTileMode tileMode =
(SKShaderTileMode)(tileModePicker.SelectedIndex == -1 ?
0 : tileModePicker.SelectedItem);
using (SKPaint paint = new SKPaint())
{
paint.Shader = SKShader.CreateRadialGradient(
new SKPoint(info.Rect.MidX, info.Rect.MidY),
100,
new SKColor[] { SKColors.Black, SKColors.White },
null,
tileMode);
canvas.DrawRect(info.Rect, paint);
}
}
}
Tento kód vytvoří přechod s černou na středu a postupně se zprostředkuje na bílou 100 pixelů. Co se stane nad rámec tohoto poloměru, závisí na argumentu SKShaderTileMode :
Ve všech třech případech přechod vyplní plátno. Na obrazovce iOS vlevo pokračuje přechod nad poloměrem poslední barvou, což je bílá. To je výsledek SKShaderTileMode.Clamp. Obrazovka Androidu ukazuje efekt SKShaderTileMode.Repeat: Při 100 pixelech od středu začíná přechod znovu první barvou, která je černá. Přechod opakuje každých 100 pixelů poloměru.
Na obrazovce Univerzální platforma Windows vpravo se dozvíte, jak SKShaderTileMode.Mirror se přechody mění na alternativní směry. První přechod je z černé na středu na bílou v poloměru 100 pixelů. Další je bílá z poloměru 100 pixelů na černou v poloměru 200 pixelů a další přechod je znovu obrácen.
V paprskovém přechodu můžete použít více než dvě barvy. Ukázka přechodu Duhový oblouk vytvoří matici osmi barev odpovídajících barvám duhy a končící červenou barvou a také pole osmi hodnot umístění:
public class RainbowArcGradientPage : ContentPage
{
public RainbowArcGradientPage ()
{
Title = "Rainbow Arc Gradient";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint paint = new SKPaint())
{
float rainbowWidth = Math.Min(info.Width, info.Height) / 4f;
// Center of arc and gradient is lower-right corner
SKPoint center = new SKPoint(info.Width, info.Height);
// Find outer, inner, and middle radius
float outerRadius = Math.Min(info.Width, info.Height);
float innerRadius = outerRadius - rainbowWidth;
float radius = outerRadius - rainbowWidth / 2;
// Calculate the colors and positions
SKColor[] colors = new SKColor[8];
float[] positions = new float[8];
for (int i = 0; i < colors.Length; i++)
{
colors[i] = SKColor.FromHsl(i * 360f / 7, 100, 50);
positions[i] = (i + (7f - i) * innerRadius / outerRadius) / 7f;
}
// Create sweep gradient based on center and outer radius
paint.Shader = SKShader.CreateRadialGradient(center,
outerRadius,
colors,
positions,
SKShaderTileMode.Clamp);
// Draw a circle with a wide line
paint.Style = SKPaintStyle.Stroke;
paint.StrokeWidth = rainbowWidth;
canvas.DrawCircle(center, radius, paint);
}
}
}
Předpokládejme, že minimální šířka a výška plátna je 1000, což znamená, že rainbowWidth hodnota je 250. Hodnoty outerRadius jsou innerRadius nastavené na 1 000 a 750. Tyto hodnoty se používají k výpočtu positions matice. Osm hodnot je v rozsahu od 0,75f do 1. Hodnota radius se používá k ladění kruhu. Hodnota 875 znamená, že šířka tahu o 250 pixelů se rozšiřuje mezi poloměrem 750 pixelů a poloměrem 1 000 pixelů:
Pokud jste celé plátno vyplnili tímto přechodem, viděli byste, že je červená uvnitř poloměru. Důvodem je to, že positions pole nezačíná na 0. První barva se používá pro posuny 0 až první maticovou hodnotou. Přechod je také červený nad vnějším poloměrem. To je výsledek Clamp režimu dlaždice. Vzhledem k tomu, že se přechod používá k zarážce silné čáry, tyto červené oblasti nejsou viditelné.
Paprskové přechody pro maskování
Stejně jako lineární přechody můžou paprskové přechody obsahovat průhledné nebo částečně průhledné barvy. Tato funkce je užitečná pro proces označovaný jako maskování, který skryje část obrázku a zvýrazní další část obrázku.
Na stránce Paprsková maska přechodu je příklad. Program načte jeden z rastrových obrázků zdrojů. Pole CENTER a RADIUS pole byla určena ze zkoumání rastrového obrázku a odkazovat na oblast, která by měla být zvýrazněna. Obslužná rutina PaintSurface začíná výpočtem obdélníku, který zobrazí rastrový obrázek, a pak ho zobrazí v daném obdélníku:
public class RadialGradientMaskPage : ContentPage
{
SKBitmap bitmap = BitmapExtensions.LoadBitmapResource(
typeof(RadialGradientMaskPage),
"SkiaSharpFormsDemos.Media.MountainClimbers.jpg");
static readonly SKPoint CENTER = new SKPoint(180, 300);
static readonly float RADIUS = 120;
public RadialGradientMaskPage ()
{
Title = "Radial Gradient Mask";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Find rectangle to display bitmap
float scale = Math.Min((float)info.Width / bitmap.Width,
(float)info.Height / bitmap.Height);
SKRect rect = SKRect.Create(scale * bitmap.Width, scale * bitmap.Height);
float x = (info.Width - rect.Width) / 2;
float y = (info.Height - rect.Height) / 2;
rect.Offset(x, y);
// Display bitmap in rectangle
canvas.DrawBitmap(bitmap, rect);
// Adjust center and radius for scaled and offset bitmap
SKPoint center = new SKPoint(scale * CENTER.X + x,
scale * CENTER.Y + y);
float radius = scale * RADIUS;
using (SKPaint paint = new SKPaint())
{
paint.Shader = SKShader.CreateRadialGradient(
center,
radius,
new SKColor[] { SKColors.Transparent,
SKColors.White },
new float[] { 0.6f, 1 },
SKShaderTileMode.Clamp);
// Display rectangle using that gradient
canvas.DrawRect(rect, paint);
}
}
}
Po nakreslení rastrového obrázku se některé jednoduché kódy CENTER převedou a RADIUS na center a radius, které odkazují na zvýrazněnou oblast v rastrovém obrázku, který byl měřítkem a posunut pro zobrazení. Tyto hodnoty slouží k vytvoření paprskového přechodu se středem a poloměrem. Dvě barvy začínají průhlednou ve středu a pro prvních 60 % poloměru. Přechod se pak zeslabí na bílou:
Tento přístup není nejlepší způsob, jak maskovat rastrový obrázek. Problémem je, že maska má většinou barvu bílou, která byla zvolena tak, aby odpovídala pozadí plátna. Pokud je pozadí jinou barvou nebo třeba přechodem, nebude se shodovat. Lepší přístup k maskování je znázorněn v článku SkiaSharp Porter-Duff režimy směsi.
Paprskové přechody pro specifikační zvýraznění
Když světlo přeškrtne zaoblenou plochu, odráží světlo v mnoha směrech, ale některé světlo se odrazí přímo do očí diváka. To často vytváří vzhled přibližné bílé oblasti na povrchu označované jako specifikární zvýraznění.
V trojrozměrné grafikě se specular často zvýrazňuje z algoritmů používaných k určení světelných cest a stínování. V dvojrozměrné grafikě jsou někdy přidány specifikátory, které naznačují vzhled 3D povrchu. Specifikační zvýraznění může transformovat plochý červený kruh na kulatý červený míč.
Stránka paprskového specifikačního zvýraznění používá k tomu paprskový přechod. Obslužná PaintSurface rutina vypočítá poloměr kruhu a dvě SKPoint hodnoty – center a je offCenter to napůl mezi středem a levým horním okrajem kruhu:
public class RadialSpecularHighlightPage : ContentPage
{
public RadialSpecularHighlightPage()
{
Title = "Radial Specular Highlight";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
float radius = 0.4f * Math.Min(info.Width, info.Height);
SKPoint center = new SKPoint(info.Rect.MidX, info.Rect.MidY);
SKPoint offCenter = center - new SKPoint(radius / 2, radius / 2);
using (SKPaint paint = new SKPaint())
{
paint.Shader = SKShader.CreateRadialGradient(
offCenter,
radius / 2,
new SKColor[] { SKColors.White, SKColors.Red },
null,
SKShaderTileMode.Clamp);
canvas.DrawCircle(center, radius, paint);
}
}
}
Volání CreateRadialGradient vytvoří přechod, který začíná v tomto offCenter bodě bílým a končí červenou ve vzdálenosti poloviny poloměru. Vypadá takto:
Pokud se na tento přechod podíváte pozorně, můžete se rozhodnout, že je chybný. Přechod je na střed kolem konkrétního bodu a možná budete chtít, aby byl o něco méně symetrický, aby odrážel zaoblenou plochu. V takovém případě můžete preferovat specifikární zvýraznění zobrazené níže v části Kuželové přechody pro specifikární zvýraznění.
Přechod uklidit
Metoda CreateSweepGradient má nejjednodušší syntaxi všech metod vytváření přechodu:
public static SKShader CreateSweepGradient (SKPoint center,
SKColor[] colors,
Single[] colorPos)
Je to jen střed, pole barev a umístění barev. Přechod začíná vpravo od středového bodu a zamítá 360 stupňů po směru hodinových ručiček kolem středu. Všimněte si, že neexistuje žádný SKShaderTileMode parametr.
K CreateSweepGradient dispozici je také přetížení s parametrem transformace matice. Na přechod můžete použít transformaci otočení a změnit tak výchozí bod. Pomocí transformace měřítka můžete také změnit směr z hodinových ručiček na proti směru hodinových ručiček.
Stránka Uklidit přechod používá přechod s úklidem k barevnému kruhu s šířkou tahu 50 pixelů:
Třída SweepGradientPage definuje pole osmi barev s různými hodnotami odstínu. Všimněte si, že pole začíná a končí červenou (hodnota odstínu 0 nebo 360), která se zobrazí úplně vpravo na snímcích obrazovky:
public class SweepGradientPage : ContentPage
{
bool drawBackground;
public SweepGradientPage ()
{
Title = "Sweep Gradient";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
TapGestureRecognizer tap = new TapGestureRecognizer();
tap.Tapped += (sender, args) =>
{
drawBackground ^= true;
canvasView.InvalidateSurface();
};
canvasView.GestureRecognizers.Add(tap);
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint paint = new SKPaint())
{
// Define an array of rainbow colors
SKColor[] colors = new SKColor[8];
for (int i = 0; i < colors.Length; i++)
{
colors[i] = SKColor.FromHsl(i * 360f / 7, 100, 50);
}
SKPoint center = new SKPoint(info.Rect.MidX, info.Rect.MidY);
// Create sweep gradient based on center of canvas
paint.Shader = SKShader.CreateSweepGradient(center, colors, null);
// Draw a circle with a wide line
const int strokeWidth = 50;
paint.Style = SKPaintStyle.Stroke;
paint.StrokeWidth = strokeWidth;
float radius = (Math.Min(info.Width, info.Height) - strokeWidth) / 2;
canvas.DrawCircle(center, radius, paint);
if (drawBackground)
{
// Draw the gradient on the whole canvas
paint.Style = SKPaintStyle.Fill;
canvas.DrawRect(info.Rect, paint);
}
}
}
}
Program také implementuje, TapGestureRecognizer který umožňuje určitý kód na konci obslužné rutiny PaintSurface . Tento kód používá stejný přechod k vyplnění plátna:
Tyto snímky obrazovky ukazují, že přechodová výplň vyplní libovolnou oblast, která je podle ní barevná. Pokud přechod nezačíná a končí stejnou barvou, dojde k přerušení napravo od středu bodu.
Dvoubodový kuželový přechod
Metoda CreateTwoPointConicalGradient má následující syntaxi:
public static SKShader CreateTwoPointConicalGradient (SKPoint startCenter,
Single startRadius,
SKPoint endCenter,
Single endRadius,
SKColor[] colors,
Single[] colorPos,
SKShaderTileMode mode)
Parametry začínají středovými body a paprsky pro dva kruhy, označované jako počáteční a koncový kruh. Zbývající tři parametry jsou stejné jako pro CreateLinearGradient a CreateRadialGradient. Přetížení CreateTwoPointConicalGradient zahrnuje maticovou transformaci.
Přechod začíná počátečním kruhem a končí na konci kruhu. Parametr SKShaderTileMode určuje, co se stane za dvěma kruhy. Dvoubodový kuželový přechod je jediný přechod, který zcela nezaplní oblast. Pokud mají dva kruhy stejný poloměr, je přechod omezen na obdélník s šířkou, která je stejná jako průměr kruhů. Pokud mají oba kruhy odlišné paprsky, vytvoří přechod kužel.
Pravděpodobně budete chtít experimentovat s dvoubodovým kuželovým přechodem, takže stránka Conical Gradient (Kuželový přechod ) je odvozená z InteractivePage toho, aby se dva dotykové body mohly přesouvat kolem dvou kruhových paprsků:
<local:InteractivePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:SkiaSharpFormsDemos"
xmlns:skia="clr-namespace:SkiaSharp;assembly=SkiaSharp"
xmlns:skiaforms="clr-namespace:SkiaSharp.Views.Forms;assembly=SkiaSharp.Views.Forms"
xmlns:tt="clr-namespace:TouchTracking"
x:Class="SkiaSharpFormsDemos.Effects.ConicalGradientPage"
Title="Conical Gradient">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid BackgroundColor="White"
Grid.Row="0">
<skiaforms:SKCanvasView x:Name="canvasView"
PaintSurface="OnCanvasViewPaintSurface" />
<Grid.Effects>
<tt:TouchEffect Capture="True"
TouchAction="OnTouchEffectAction" />
</Grid.Effects>
</Grid>
<Picker x:Name="tileModePicker"
Grid.Row="1"
Title="Shader Tile Mode"
Margin="10"
SelectedIndexChanged="OnPickerSelectedIndexChanged">
<Picker.ItemsSource>
<x:Array Type="{x:Type skia:SKShaderTileMode}">
<x:Static Member="skia:SKShaderTileMode.Clamp" />
<x:Static Member="skia:SKShaderTileMode.Repeat" />
<x:Static Member="skia:SKShaderTileMode.Mirror" />
</x:Array>
</Picker.ItemsSource>
<Picker.SelectedIndex>
0
</Picker.SelectedIndex>
</Picker>
</Grid>
</local:InteractivePage>
Soubor s kódem definuje dva TouchPoint objekty s pevnými paprsky 50 a 100:
public partial class ConicalGradientPage : InteractivePage
{
const int RADIUS1 = 50;
const int RADIUS2 = 100;
public ConicalGradientPage ()
{
touchPoints = new TouchPoint[2];
touchPoints[0] = new TouchPoint
{
Center = new SKPoint(100, 100),
Radius = RADIUS1
};
touchPoints[1] = new TouchPoint
{
Center = new SKPoint(300, 300),
Radius = RADIUS2
};
InitializeComponent();
baseCanvasView = canvasView;
}
void OnPickerSelectedIndexChanged(object sender, EventArgs args)
{
canvasView.InvalidateSurface();
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKColor[] colors = { SKColors.Red, SKColors.Green, SKColors.Blue };
SKShaderTileMode tileMode =
(SKShaderTileMode)(tileModePicker.SelectedIndex == -1 ?
0 : tileModePicker.SelectedItem);
using (SKPaint paint = new SKPaint())
{
paint.Shader = SKShader.CreateTwoPointConicalGradient(touchPoints[0].Center,
RADIUS1,
touchPoints[1].Center,
RADIUS2,
colors,
null,
tileMode);
canvas.DrawRect(info.Rect, paint);
}
// Display the touch points here rather than by TouchPoint
using (SKPaint paint = new SKPaint())
{
paint.Style = SKPaintStyle.Stroke;
paint.Color = SKColors.Black;
paint.StrokeWidth = 3;
foreach (TouchPoint touchPoint in touchPoints)
{
canvas.DrawCircle(touchPoint.Center, touchPoint.Radius, paint);
}
}
}
}
Pole colors je červené, zelené a modré. Kód směrem do dolní části PaintSurface obslužné rutiny nakreslí dva dotykové body jako černé kruhy, aby nepřekážely přechod.
Všimněte si, že DrawRect volání používá přechod k obarvení celého plátna. V obecném případě však většina plátna zůstává bezbarevná přechodem. Tady je program zobrazující tři možné konfigurace:
Obrazovka iOS na levé straně zobrazuje efekt SKShaderTileMode nastavení Clamp. Přechod začíná červeně uvnitř okraje menšího kruhu, který je naproti straně nejblíže druhému kruhu. Hodnota Clamp také způsobí, že červená bude pokračovat k bodu kužele. Přechod končí modře na vnějším okraji většího kruhu, který je nejblíže prvnímu kruhu, ale pokračuje modře uvnitř kruhu i za sebou.
Obrazovka Androidu je podobná, ale s .SKShaderTileMode Repeat Teď je jasnější, že přechod začíná uvnitř prvního kruhu a končí mimo druhý kruh. Nastavení Repeat způsobí, že se přechod znovu opakuje červeně uvnitř většího kruhu.
Obrazovka UPW ukazuje, co se stane, když se menší kruh přesune úplně uvnitř většího kruhu. Přechod přestane být kuželem a místo toho vyplní celou oblast. Efekt je podobný radiálnímu přechodu, ale asymetrický, pokud menší kruh není přesně zarovnaný do většího kruhu.
Možná budete pochybovat o praktické užitečnosti přechodu, když je jeden kruh vnořený do jiného, ale je ideální pro specifikární zvýraznění.
Kuželové přechody pro specifikární zvýraznění
Dříve v tomto článku jste viděli, jak pomocí paprskového přechodu vytvořit specifikační zvýraznění. Pro tento účel můžete také použít dvoubodový kuželový přechod a můžete chtít, jak vypadá:
Asymetrický vzhled lépe naznačuje zaoblený povrch objektu.
Kód výkresu na stránce Kuželové specifikační zvýraznění je stejný jako stránka zvýraznění paprskového specifikátoru s výjimkou shaderu:
public class ConicalSpecularHighlightPage : ContentPage
{
···
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
···
using (SKPaint paint = new SKPaint())
{
paint.Shader = SKShader.CreateTwoPointConicalGradient(
offCenter,
1,
center,
radius,
new SKColor[] { SKColors.White, SKColors.Red },
null,
SKShaderTileMode.Clamp);
canvas.DrawCircle(center, radius, paint);
}
}
}
Dva kruhy mají středy offCenter a center. Kruh uprostřed center je spojený s poloměrem, který zahrnuje celý míč, ale kruh uprostřed má offCenter poloměr jen jednoho pixelu. Přechod efektivně začíná v tomto bodě a končí na okraji míče.







