Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
La SKShader classe definisce metodi statici per creare quattro diversi tipi di sfumature. L'articolo Relativo alla sfumatura lineare SkiaSharp illustra il CreateLinearGradient metodo . Questo articolo illustra gli altri tre tipi di sfumature, tutti basati su cerchi.
Il CreateRadialGradient metodo crea una sfumatura che deriva dal centro di un cerchio:

Il CreateSweepGradient metodo crea una sfumatura che spazza intorno al centro di un cerchio:

Il terzo tipo di sfumatura è piuttosto insolito. Viene chiamato gradiente conico a due punti ed è definito dal CreateTwoPointConicalGradient metodo . La sfumatura si estende da un cerchio a un altro:

Se i due cerchi sono di dimensioni diverse, la sfumatura assume la forma di un cono.
Questo articolo illustra in modo più dettagliato queste sfumature.
Sfumatura radiale
Il CreateRadialGradient metodo ha la sintassi seguente:
public static SKShader CreateRadialGradient (SKPoint center,
Single radius,
SKColor[] colors,
Single[] colorPos,
SKShaderTileMode mode)
Un CreateRadialGradient overload include anche un parametro della matrice di trasformazione.
I primi due argomenti specificano il centro di un cerchio e un raggio. La sfumatura inizia al centro ed estende verso l'esterno per radius i pixel. Ciò che accade oltre radius dipende dall'argomento SKShaderTileMode . Il colors parametro è una matrice di due o più colori (come nei metodi con sfumatura lineare) ed colorPos è una matrice di numeri interi nell'intervallo da 0 a 1. Questi interi indicano le posizioni relative dei colori lungo tale radius linea. È possibile impostare tale argomento su per spaziare null allo stesso modo i colori.
Se si utilizza CreateRadialGradient per riempire un cerchio, è possibile impostare il centro della sfumatura sul centro del cerchio e il raggio della sfumatura al raggio del cerchio. In tal caso, l'argomento SKShaderTileMode non ha alcun effetto sul rendering della sfumatura. Tuttavia, se l'area riempita dalla sfumatura è maggiore del cerchio definito dalla sfumatura, l'argomento SKShaderTileMode ha un effetto profondo su ciò che accade all'esterno del cerchio.
L'effetto di SKShaderMode è illustrato nella pagina Sfumatura radiale dell'esempio. Il file XAML per questa pagina crea un'istanza di che Picker consente di selezionare uno dei tre membri dell'enumerazione 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>
Il file code-behind colora l'intera area di disegno con una sfumatura radiale. Il centro della sfumatura viene impostato sul centro dell'area di disegno e il raggio è impostato su 100 pixel. La sfumatura è costituita da soli due colori, nero e bianco:
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);
}
}
}
Questo codice crea una sfumatura con nero al centro, gradualmente sfumato a bianco 100 pixel dal centro. Ciò che accade oltre tale raggio dipende dall'argomento SKShaderTileMode :
In tutti e tre i casi, la sfumatura riempie l'area di disegno. Nella schermata iOS a sinistra, la sfumatura oltre il raggio continua con l'ultimo colore, ovvero bianco. Questo è il risultato di SKShaderTileMode.Clamp. La schermata Android mostra l'effetto di SKShaderTileMode.Repeat: a 100 pixel dal centro, la sfumatura inizia di nuovo con il primo colore, ovvero nero. La sfumatura si ripete ogni 100 pixel di raggio.
La schermata piattaforma UWP (Universal Windows Platform) a destra mostra come SKShaderTileMode.Mirror fa sì che le sfumature si avviino in direzione alternative. La prima sfumatura è dal nero al centro al bianco in corrispondenza di un raggio di 100 pixel. Il successivo è bianco dal raggio di 100 pixel al nero in corrispondenza di un raggio di 200 pixel e la sfumatura successiva viene nuovamente invertita.
È possibile usare più di due colori in una sfumatura radiale. L'esempio Rainbow Arc Gradient crea una matrice di otto colori corrispondenti ai colori dell'arcobaleno e termina con il rosso e una matrice di otto valori di posizione:
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);
}
}
}
Si supponga che il valore minimo della larghezza e dell'altezza dell'area di disegno sia 1000, il che significa che il rainbowWidth valore è 250. I outerRadius valori e innerRadius sono impostati rispettivamente su 1000 e 750. Questi valori vengono usati per calcolare la positions matrice; gli otto valori sono compresi tra 0,75f e 1. Il radius valore viene usato per ritagliare il cerchio. Il valore di 875 indica che la larghezza del tratto da 250 pixel si estende tra il raggio di 750 pixel e il raggio di 1000 pixel:
Se l'intera area di disegno è stata riempita con questa sfumatura, si noterà che è rossa all'interno del raggio interno. Ciò è dovuto al fatto che la positions matrice non inizia con 0. Il primo colore viene usato per gli offset da 0 al primo valore della matrice. La sfumatura è anche rossa oltre il raggio esterno. Questo è il risultato della Clamp modalità riquadro. Poiché la sfumatura viene usata per accarezzare una linea spessa, queste aree rosse non sono visibili.
Sfumature radiali per la maschera
Come le sfumature lineari, le sfumature radiali possono incorporare colori trasparenti o parzialmente trasparenti. Questa funzionalità è utile per un processo denominato mascheramento, che nasconde parte di un'immagine per accentuare un'altra parte dell'immagine.
La pagina Maschera sfumatura radiale mostra un esempio. Il programma carica una delle bitmap delle risorse. I CENTER campi e RADIUS sono stati determinati da un esame della bitmap e fanno riferimento a un'area che deve essere evidenziata. Il PaintSurface gestore inizia calcolando un rettangolo per visualizzare la bitmap e quindi la visualizza nel rettangolo:
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);
}
}
}
Dopo aver disegnato la bitmap, il codice semplice converte CENTER e RADIUS in center e radius, che fanno riferimento all'area evidenziata nella bitmap ridimensionata e spostata per la visualizzazione. Questi valori vengono usati per creare una sfumatura radiale con tale centro e raggio. I due colori iniziano in modo trasparente al centro e per il primo 60% del raggio. La sfumatura si dissolve quindi in bianco:
Questo approccio non è il modo migliore per mascherare una bitmap. Il problema è che la maschera ha principalmente un colore bianco, che è stato scelto per trovare la corrispondenza con lo sfondo dell'area di disegno. Se lo sfondo è un altro colore, o forse una sfumatura stessa, non corrisponderà. Un approccio migliore alla maschera è illustrato nell'articolo Modalità di fusione SkiaSharp Porter-Duff.
Sfumature radiali per evidenziazioni speculari
Quando una luce colpisce una superficie arrotondata, riflette la luce in molte direzioni, ma alcune delle luci rimbalzano direttamente nell'occhio dello spettatore. Questo spesso crea l'aspetto di un'area bianca fuzzy sulla superficie denominata evidenziazione speculare.
Nella grafica tridimensionale, le evidenziazioni speculari spesso derivano dagli algoritmi usati per determinare i percorsi di luce e l'ombreggiatura. Nella grafica bidimensionale, le evidenziazioni speculari vengono talvolta aggiunte per suggerire l'aspetto di una superficie 3D. Un'evidenziazione speculare può trasformare un cerchio rosso piatto in una palla rossa rotonda.
La pagina Evidenziazione speculare radiale usa una sfumatura radiale per eseguire esattamente questa operazione. Gli PaintSurface esseri del gestore calcolando un raggio per il cerchio e due SKPoint valori : e center un oggetto offCenter che si trova a metà strada tra il centro e il bordo superiore sinistro del cerchio:
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);
}
}
}
La CreateRadialGradient chiamata crea una sfumatura che inizia a quel offCenter punto con bianco e termina con rosso a una distanza di metà del raggio. Di seguito è riportata un'immagine di tale finestra:
Se si esamina attentamente questa sfumatura, si potrebbe decidere che è difettoso. La sfumatura è allineata al centro di un particolare punto e potrebbe essere preferibile che fosse un po' meno simmetrica per riflettere la superficie arrotondata. In tal caso, è possibile preferire l'evidenziazione speculare illustrata di seguito nella sezione Sfumature coniche per evidenziazioni speculari.
Sfumatura di sweep
Il CreateSweepGradient metodo ha la sintassi più semplice di tutti i metodi di creazione della sfumatura:
public static SKShader CreateSweepGradient (SKPoint center,
SKColor[] colors,
Single[] colorPos)
È solo un centro, una matrice di colori e le posizioni dei colori. La sfumatura inizia a destra del punto centrale e spazza 360 gradi in senso orario intorno al centro. Si noti che non esiste alcun SKShaderTileMode parametro.
CreateSweepGradient È disponibile anche un overload con un parametro di trasformazione matrice. È possibile applicare una trasformazione di rotazione alla sfumatura per modificare il punto iniziale. È anche possibile applicare una trasformazione di scala per modificare la direzione da senso orario a in senso antiorario.
La pagina Sweep Gradient usa una sfumatura sweep per colorare un cerchio con una larghezza del tratto di 50 pixel:
La SweepGradientPage classe definisce una matrice di otto colori con valori di tonalità diversi. Si noti che la matrice inizia e termina con il rosso (un valore di tonalità pari a 0 o 360), visualizzato all'estrema destra negli screenshot:
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);
}
}
}
}
Il programma implementa anche un oggetto TapGestureRecognizer che abilita codice alla fine del PaintSurface gestore. Questo codice usa la stessa sfumatura per riempire l'area di disegno:
Questi screenshot mostrano che il riempimento sfumato di qualsiasi area è colorata da esso. Se la sfumatura non inizia e termina con lo stesso colore, vi sarà una discontinuità a destra del punto centrale.
Sfumatura conica a due punti
Il CreateTwoPointConicalGradient metodo ha la sintassi seguente:
public static SKShader CreateTwoPointConicalGradient (SKPoint startCenter,
Single startRadius,
SKPoint endCenter,
Single endRadius,
SKColor[] colors,
Single[] colorPos,
SKShaderTileMode mode)
I parametri iniziano con i punti centrali e i raggi per due cerchi, definiti cerchio iniziale e cerchio finale . I tre parametri rimanenti sono uguali a per CreateLinearGradient e CreateRadialGradient. Un CreateTwoPointConicalGradient overload include una trasformazione matrice.
La sfumatura inizia in corrispondenza del cerchio iniziale e termina in corrispondenza del cerchio finale. Il SKShaderTileMode parametro regola ciò che accade oltre i due cerchi. La sfumatura conica a due punti è l'unica sfumatura che non riempie completamente un'area. Se i due cerchi hanno lo stesso raggio, la sfumatura è limitata a un rettangolo con una larghezza uguale al diametro dei cerchi. Se i due cerchi hanno raggi diversi, la sfumatura forma un cono.
È probabile che si voglia sperimentare con la sfumatura conica a due punti, quindi la pagina Sfumatura conica deriva da InteractivePage per consentire lo spostamento di due punti di tocco per i due raggi circolari:
<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>
Il file code-behind definisce i due TouchPoint oggetti con raggi fissi di 50 e 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);
}
}
}
}
La colors matrice è rossa, verde e blu. Il codice verso la parte inferiore del PaintSurface gestore disegna i due punti di tocco come cerchi neri in modo che non ostacolino la sfumatura.
Si noti che DrawRect la chiamata usa la sfumatura per colorare l'intera area di disegno. Nel caso generale, tuttavia, gran parte dell'area di disegno rimane scolorata dalla sfumatura. Ecco il programma che mostra tre possibili configurazioni:
La schermata iOS a sinistra mostra l'effetto dell'impostazione SKShaderTileMode di Clamp. La sfumatura inizia con il rosso all'interno del bordo del cerchio più piccolo che è opposto al lato più vicino al secondo cerchio. Il Clamp valore fa anche in modo che il rosso continui fino al punto del cono. La sfumatura termina con il blu al bordo esterno del cerchio più grande più vicino al primo cerchio, ma continua con il blu all'interno di tale cerchio e oltre.
La schermata Android è simile ma con un SKShaderTileMode di Repeat. Ora è più chiaro che la sfumatura inizia all'interno del primo cerchio e termina all'esterno del secondo cerchio. L'impostazione Repeat fa sì che la sfumatura si ripeta nuovamente con il rosso all'interno del cerchio più grande.
La schermata UWP mostra cosa accade quando il cerchio più piccolo viene spostato interamente all'interno del cerchio più grande. La sfumatura smette di essere un cono e riempie invece l'intera area. L'effetto è simile alla sfumatura radiale, ma è asimmetrico se il cerchio più piccolo non è esattamente centrato all'interno del cerchio più grande.
È possibile dubitare dell'utilità pratica della sfumatura quando un cerchio è annidato in un altro, ma è ideale per un'evidenziazione speculare.
Sfumature coniche per evidenziazioni speculari
In precedenza in questo articolo è stato illustrato come usare una sfumatura radiale per creare un'evidenziazione speculare. È anche possibile usare la sfumatura conica a due punti per questo scopo e si potrebbe preferire l'aspetto:
L'aspetto asimmetrico suggerisce meglio la superficie arrotondata dell'oggetto.
Il codice di disegno nella pagina Evidenziazione speculare conicale è uguale alla pagina Evidenziazione speculare radiale ad eccezione dello shader:
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);
}
}
}
I due cerchi hanno centri di offCenter e center. Il cerchio centrato a center è associato a un raggio che comprende l'intera palla, ma il cerchio centrato su offCenter ha un raggio di un solo pixel. La sfumatura inizia in modo efficace a quel punto e termina al bordo della palla.







