Pixely a jednotky nezávislé na zařízení
Prozkoumání rozdílů mezi souřadnicemi a Xamarin.Forms souřadnicemi SkiaSharp
Tento článek popisuje rozdíly v souřadnicovém systému používaném ve SkiaSharpu a Xamarin.Forms. Můžete získat informace pro převod mezi těmito dvěma souřadnicovými systémy a také kreslit grafiku, která vyplní určitou oblast:
Pokud už nějakou dobu programujete Xamarin.Forms , můžete mít pocit, Xamarin.Forms že máte souřadnice a velikosti. Kruhy nakreslené v obou předchozích článcích se vám můžou zdát trochu malé.
Tyto kruhy jsou ve srovnání s velikostmi Xamarin.Forms malé. SkiaSharp ve výchozím nastavení kreslí v jednotkách pixelů, zatímco Xamarin.Forms základy souřadnic a velikosti jsou na jednotce nezávislé na zařízení vytvořené podkladovou platformou. (Další informace o souřadnicovém Xamarin.Forms systému naleznete v kapitole 5. Práce s velikostmi knihy Vytváření mobilních aplikací s Xamarin.Forms.)
Stránka v ukázkovém programu s názvem Surface Size používá textový výstup SkiaSharp k zobrazení velikosti plochy displeje ze tří různých zdrojů:
- Normální Xamarin.Forms
Width
vlastnosti aHeight
vlastnosti objektuSKCanvasView
. - Vlastnost
CanvasSize
objektuSKCanvasView
. - Vlastnost
Size
SKImageInfo
hodnoty, která je konzistentní s vlastnostmiWidth
použitýmiHeight
na dvou předchozích stránkách.
Třída SurfaceSizePage
ukazuje, jak tyto hodnoty zobrazit. Konstruktor uloží SKCanvasView
objekt jako pole, aby k němu bylo možné přistupovat v obslužné rutině PaintSurface
události:
SKCanvasView canvasView;
public SurfaceSizePage()
{
Title = "Surface Size";
canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
}
SKCanvas
zahrnuje šest různých DrawText
metod, ale tato DrawText
metoda je nejjednodušší:
public void DrawText (String text, Single x, Single y, SKPaint paint)
Zadáte textový řetězec, souřadnice X a Y, kde má text začínat, a SKPaint
objekt. Souřadnice X určuje umístění levé strany textu, ale pozor: Souřadnice Y určuje pozici účaří textu. Pokud jste někdy napsali ručně na linkovaný papír, je směrný plán čárou, na které znaky sedí a pod kterými sestupně (například ty na písmenech g, p, q a y) sestupně.
Objekt SKPaint
umožňuje zadat barvu textu, rodinu písem a velikost textu. Ve výchozím nastavení má vlastnost hodnotu 12, což má za následek malý text na zařízeních s vysokým rozlišením, TextSize
jako jsou telefony. V čemkoli, ale v nejjednodušších aplikacích budete potřebovat také informace o velikosti zobrazeného textu. Třída SKPaint
definuje FontMetrics
vlastnost a několik MeasureText
metod, ale pro méně fancy potřeby poskytuje FontSpacing
vlastnost doporučenou hodnotu pro řádkování po sobě jdoucích řádků textu.
Následující PaintSurface
obslužná rutina vytvoří SKPaint
objekt pro TextSize
40 pixelů, což je požadovaná svislá výška textu z horní části vzestupných hodnot do dolní části sestupných objektů. Hodnota FontSpacing
, kterou SKPaint
objekt vrátí, je o něco větší, asi 47 pixelů.
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
SKPaint paint = new SKPaint
{
Color = SKColors.Black,
TextSize = 40
};
float fontSpacing = paint.FontSpacing;
float x = 20; // left margin
float y = fontSpacing; // first baseline
float indent = 100;
canvas.DrawText("SKCanvasView Height and Width:", x, y, paint);
y += fontSpacing;
canvas.DrawText(String.Format("{0:F2} x {1:F2}",
canvasView.Width, canvasView.Height),
x + indent, y, paint);
y += fontSpacing * 2;
canvas.DrawText("SKCanvasView CanvasSize:", x, y, paint);
y += fontSpacing;
canvas.DrawText(canvasView.CanvasSize.ToString(), x + indent, y, paint);
y += fontSpacing * 2;
canvas.DrawText("SKImageInfo Size:", x, y, paint);
y += fontSpacing;
canvas.DrawText(info.Size.ToString(), x + indent, y, paint);
}
Metoda začíná první řádek textu souřadnicí X 20 (pro malý okraj vlevo) a souřadnicí fontSpacing
Y , což je o něco víc, než je nutné k zobrazení úplné výšky prvního řádku textu v horní části plochy zobrazení. Po každém volání DrawText
se souřadnice Y zvýší o jeden nebo dva přírůstky fontSpacing
.
Tady je spuštěný program:
Jak můžete vidět, CanvasSize
vlastnost SKCanvasView
a Size
vlastnost SKImageInfo
hodnoty jsou konzistentní při vykazování rozměrů pixelů. Vlastnosti Height
a Width
vlastnosti SKCanvasView
jsou Xamarin.Forms vlastnosti a hlásí velikost zobrazení v jednotkách nezávislých na zařízení definovaných platformou.
Simulátor iOS sedm na levé straně má dva pixely na jednotku nezávislou na zařízení a Android Nexus 5 ve středu má tři pixely na jednotku. Proto má jednoduchý kruh zobrazený dříve různé velikosti na různých platformách.
Pokud chcete pracovat zcela v jednotkách nezávislých na zařízeních, můžete to udělat nastavením IgnorePixelScaling
vlastnosti SKCanvasView
na true
hodnotu . Výsledky se ale nemusí líbit. SkiaSharp vykreslí grafiku na menší ploše zařízení s velikostí pixelů rovnající se velikosti zobrazení v jednotkách nezávislých na zařízeních. (Například SkiaSharp by použil plochu displeje 360 x 512 pixelů na Nexusu 5.) Potom vertikálně navýší velikost obrázku, což vede k znatelnému rastru jaggies.
Pokud chcete zachovat stejné rozlišení obrázků, lepším řešením je napsat vlastní jednoduché funkce pro převod mezi těmito dvěma souřadnicovými systémy.
Kromě DrawCircle
metody definuje také dvě DrawOval
metody, SKCanvas
které nakreslely tři tečky. Tři tečky jsou definovány dvěma paprsky, nikoli jedním poloměrem. Označují se jako hlavní poloměr a vedlejší poloměr. Metoda DrawOval
nakreslí tři tečky se dvěma paprsky paralelně s osami X a Y. (Pokud potřebujete nakreslit tři tečky se osami, které nejsou paralelní se osami X a Y, můžete použít transformaci otočení, jak je popsáno v článku.Otočit transformaci nebo grafickou cestu, jak je popsáno v článku Tři způsoby kreslení oblouku). Toto přetížení DrawOval
metody pojmenuje dva parametry rx
radii a ry
indikuje, že jsou paralelní se osami X a Y:
public void DrawOval (Single cx, Single cy, Single rx, Single ry, SKPaint paint)
Je možné nakreslit tři tečky, které vyplní plochu displeje? Stránka Výplň tří teček ukazuje, jak na to. Obslužná rutina PaintSurface
události ve třídě EllipseFillPage.xaml.cs odečte polovinu šířky tahu od xRadius
a yRadius
hodnot tak, aby odpovídala celému třemi tečkám a jeho obrysu na ploše zobrazení:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
float strokeWidth = 50;
float xRadius = (info.Width - strokeWidth) / 2;
float yRadius = (info.Height - strokeWidth) / 2;
SKPaint paint = new SKPaint
{
Style = SKPaintStyle.Stroke,
Color = SKColors.Blue,
StrokeWidth = strokeWidth
};
canvas.DrawOval(info.Width / 2, info.Height / 2, xRadius, yRadius, paint);
}
Tady je spuštěný:
Druhá DrawOval
metoda má SKRect
argument, což je obdélník definovaný z hlediska souřadnic X a Y jeho levého horního a pravého dolního rohu. Ovál vyplní tento obdélník, což naznačuje, že by ho mohlo být možné použít na stránce Výplň se třemi tečkami takto:
SKRect rect = new SKRect(0, 0, info.Width, info.Height);
canvas.DrawOval(rect, paint);
To však zkracuje všechny okraje obrysu tří teček na čtyřech stranách. Musíte upravit všechny argumenty konstruktoru SKRect
strokeWidth
na základě toho, aby to fungovalo správně:
SKRect rect = new SKRect(strokeWidth / 2,
strokeWidth / 2,
info.Width - strokeWidth / 2,
info.Height - strokeWidth / 2);
canvas.DrawOval(rect, paint);