Eğme Dönüşümü
Eğme dönüştürmesinin SkiaSharp'ta eğimli grafik nesneleri nasıl oluşturabileceğini görün
SkiaSharp'ta eğme dönüşümü, bu görüntüdeki gölge gibi grafik nesneleri eğir:
Eğme, dikdörtgeni paralelograma dönüştürür, ancak eğik elips yine de üç noktadır.
Çeviri, ölçeklendirme ve döndürme özelliklerini tanımlasa Xamarin.Forms da, eğme için içinde Xamarin.Forms buna karşılık gelen özellik yoktur.
yöntemiSKCanvas
, Skew
yatay eğme ve dikey eğme için iki bağımsız değişken kabul eder:
public void Skew (Single xSkew, Single ySkew)
İkinci Skew
bir yöntem bu bağımsız değişkenleri tek SKPoint
bir değerde birleştirir:
public void Skew (SKPoint skew)
Ancak, bu iki yöntemden birini yalıtarak kullanmanız pek olası değildir.
Eğme Denemesi sayfası, –10 ile 10 arasında değişen eğriltme değerleriyle deneme yapmanıza olanak tanır. Metin dizesi, iki Slider
öğeden alınan eğme değerleriyle sayfanın sol üst köşesine konumlandırılır. sınıfındaki PaintSurface
işleyici aşağıdadır SkewExperimentPage
:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint textPaint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Blue,
TextSize = 200
})
{
string text = "SKEW";
SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);
canvas.Skew((float)xSkewSlider.Value, (float)ySkewSlider.Value);
canvas.DrawText(text, 0, -textBounds.Top, textPaint);
}
}
Bağımsız değişkeninin xSkew
değerleri, pozitif değerler için metnin alt kısmını sağa veya negatif değerler için sola kaydırıyor. Pozitif değerler ySkew
için metnin sağını aşağı veya negatif değerler için yukarı kaydırma değerleri:
xSkew
Değer değerin negatifiyse ySkew
sonuç döndürmedir, ancak bir şekilde ölçeklendirilir.
Dönüşüm formülleri aşağıdaki gibidir:
x' = x + xSkew · Y
y' = ySkew · x + y
Örneğin, pozitif xSkew
bir değer için, dönüştürülmüş x'
değer arttıkça y
artar. Eğime neden olan da bu.
200 piksel genişliğinde ve 100 piksel yüksekliğinde bir üçgen, sol üst köşesi noktasında (0, 0) konumlandırılır ve 1,5 değeriyle xSkew
işlenirse, aşağıdaki paralelkenar sonuçlanır:
Alt kenarın koordinatları 100 değerine sahip y
olduğundan 150 piksel sağa kaydırılır.
sıfır olmayan veya ySkew
değerleri xSkew
için yalnızca nokta (0, 0) aynı kalır. Bu nokta, dengesizlik merkezi olarak kabul edilebilir. Eğriltme merkezinin başka bir şey olması gerekiyorsa (genellikle böyledir), bunu sağlayan bir yöntem yoktur Skew
. Çağrıları çağrıyla Skew
açıkça birleştirmeniz Translate
gerekir. ve konumundaki dengesizliği px
py
ortalamak için aşağıdaki çağrıları yapın:
canvas.Translate(px, py);
canvas.Skew(xSkew, ySkew);
canvas.Translate(-px, -py);
Bileşik dönüştürme formülleri şunlardır:
x' = x + xSkew · (y – py)
y' = ySkew · (x – px) + y
Sıfır ise ySkew
, px
değer kullanılmaz. Değeri ilgisizdir ve benzer şekilde ve py
için ySkew
de olur.
Bu diyagramdaki açı α gibi eğme açısı olarak eğmeyi belirtmeyi daha rahat hissedebilirsiniz:
150 piksellik kaydırmanın 100 piksellik dikeye oranı, bu açının tanjantını oluşturur ve bu örnekte 56,3 derecedir.
Eğme Açısı Denemesi sayfasının XAML dosyası, Eğriltme Açısı sayfasına benzer, ancak Slider
öğelerin –90 derece ile 90 derece arasında olması gerekir. Arka SkewAngleExperiment
planda kod dosyası, sayfadaki metni ortalar ve çarpıklık merkezini sayfanın ortasına ayarlamak için kullanır Translate
. Kodun en altındaki kısa SkewDegrees
yöntem açıları eğme değerlerine dönüştürür:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint textPaint = new SKPaint
{
Style = SKPaintStyle.Fill,
Color = SKColors.Blue,
TextSize = 200
})
{
float xCenter = info.Width / 2;
float yCenter = info.Height / 2;
string text = "SKEW";
SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);
float xText = xCenter - textBounds.MidX;
float yText = yCenter - textBounds.MidY;
canvas.Translate(xCenter, yCenter);
SkewDegrees(canvas, xSkewSlider.Value, ySkewSlider.Value);
canvas.Translate(-xCenter, -yCenter);
canvas.DrawText(text, xText, yText, textPaint);
}
}
void SkewDegrees(SKCanvas canvas, double xDegrees, double yDegrees)
{
canvas.Skew((float)Math.Tan(Math.PI * xDegrees / 180),
(float)Math.Tan(Math.PI * yDegrees / 180));
}
Açı pozitif veya negatif 90 dereceye yaklaştıkça tanjant sonsuzluğa yaklaşır, ancak yaklaşık 80 dereceye kadar olan açılar kullanılabilir:
Küçük bir negatif yatay eğme, Eğik Metin sayfasında gösterildiği gibi eğik veya italik metinleri taklit edebilir. ObliqueTextPage
sınıfı bunun nasıl yapıldığını gösterir:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint textPaint = new SKPaint()
{
Style = SKPaintStyle.Fill,
Color = SKColors.Maroon,
TextAlign = SKTextAlign.Center,
TextSize = info.Width / 8 // empirically determined
})
{
canvas.Translate(info.Width / 2, info.Height / 2);
SkewDegrees(canvas, -20, 0);
canvas.DrawText(Title, 0, 0, textPaint);
}
}
void SkewDegrees(SKCanvas canvas, double xDegrees, double yDegrees)
{
canvas.Skew((float)Math.Tan(Math.PI * xDegrees / 180),
(float)Math.Tan(Math.PI * yDegrees / 180));
}
TextAlign
özelliği SKPaint
olarak Center
ayarlanır. Herhangi bir dönüşüm olmadan, DrawText
koordinatları (0, 0) olan çağrı metni taban çizgisinin yatay ortasını sol üst köşeye konumlandırabilir. metni SkewDegrees
taban çizgisine göre yatay olarak 20 derece eğer. Çağrı, Translate
metnin taban çizgisinin yatay ortasını tuvalin ortasına taşır:
Gölge Metni Eğ sayfası, metinden uzaklaşan bir metin gölgesi oluşturmak için 45 derece eğme ve dikey ölçek birleşiminin nasıl kullanılacağını gösterir. İşleyicinin ilgili bölümü aşağıdadır PaintSurface
:
using (SKPaint textPaint = new SKPaint())
{
textPaint.Style = SKPaintStyle.Fill;
textPaint.TextSize = info.Width / 6; // empirically determined
// Common to shadow and text
string text = "Shadow";
float xText = 20;
float yText = info.Height / 2;
// Shadow
textPaint.Color = SKColors.LightGray;
canvas.Save();
canvas.Translate(xText, yText);
canvas.Skew((float)Math.Tan(-Math.PI / 4), 0);
canvas.Scale(1, 3);
canvas.Translate(-xText, -yText);
canvas.DrawText(text, xText, yText, textPaint);
canvas.Restore();
// Text
textPaint.Color = SKColors.Blue;
canvas.DrawText(text, xText, yText, textPaint);
}
Önce gölge, sonra da metin görüntülenir:
Yöntemine DrawText
geçirilen dikey koordinat, metnin taban çizgisine göre konumunu gösterir. Bu, eğriltme merkezi için kullanılan dikey koordinatla aynıdır. Metin dizesi alt öğeleri içeriyorsa bu teknik çalışmaz. Örneğin, "quirky" sözcüğünü "Gölge" olarak değiştirin ve sonuç şu şekilde olur:
Gölge ve metin hala taban çizgisine hizalanır, ancak efekt yanlış görünür. Bunu düzeltmek için metin sınırlarını edinmeniz gerekir:
SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);
Çağrıların Translate
altların yüksekliğine göre ayarlanması gerekir:
canvas.Translate(xText, yText + textBounds.Bottom);
canvas.Skew((float)Math.Tan(-Math.PI / 4), 0);
canvas.Scale(1, 3);
canvas.Translate(-xText, -yText - textBounds.Bottom);
Şimdi gölge, bu alt türlerin altından genişler: