Pochylenie — przekształcenie
Zobacz, jak transformacja niesymetryczności może tworzyć przechylone obiekty graficzne w skiaSharp
W skiaSharp przekształć przekształć przechyla obiekty graficzne, takie jak cień na poniższej ilustracji:
Niesymetryczność zamienia prostokąt w równoległyogram, ale niesymetryczny wielokropek jest nadal wielokropkiem.
Mimo że Xamarin.Forms definiuje właściwości tłumaczenia, skalowania i rotacji, nie ma odpowiedniej właściwości dla Xamarin.Forms niesymetryczności.
Metoda Skew
akceptowania SKCanvas
dwóch argumentów dla niesymetryczności poziomej i niesymetryczności pionowej:
public void Skew (Single xSkew, Single ySkew)
Druga Skew
metoda łączy te argumenty w jednej SKPoint
wartości:
public void Skew (SKPoint skew)
Jest jednak mało prawdopodobne, że będziesz używać jednej z tych dwóch metod w izolacji.
Strona Niesymetryczność eksperymentu umożliwia eksperymentowanie z niesymetrycznymi wartościami z zakresu od –10 do 10. Ciąg tekstowy jest umieszczony w lewym górnym rogu strony z niesymetrycznymi wartościami uzyskanymi z dwóch Slider
elementów. PaintSurface
Oto procedura obsługi w SkewExperimentPage
klasie:
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);
}
}
xSkew
Wartości argumentu przesuwają dolną część tekstu w prawo dla wartości dodatnich lub pozostawione dla wartości ujemnych. ySkew
Wartości przesunięcia po prawej stronie tekstu w dół dla wartości dodatnich lub w górę dla wartości ujemnych:
xSkew
Jeśli wartość jest ujemna ySkew
wartości, wynik jest obracany, ale również nieco skalowany.
Formuły przekształcania są następujące:
x' = x + xSkew · Y
y' = ySkew · x + y
Na przykład w przypadku wartości dodatniej xSkew
przekształcona x'
wartość zwiększa się wraz ze y
wzrostem. To właśnie powoduje pochylenie.
Jeśli trójkąt o szerokości 200 pikseli i wysokości 100 pikseli jest umieszczony w lewym górnym rogu w punkcie (0, 0) i jest renderowany z wartością xSkew
1,5, następujące wyniki równoległości:
Współrzędne dolnej krawędzi mają y
wartości 100, więc jest przesunięty 150 pikseli po prawej stronie.
W przypadku wartości xSkew
innych niż zero lub ySkew
tylko punkt (0, 0) pozostaje taki sam. Ten punkt można uznać za środek niesymetryczności. Jeśli potrzebujesz środka niesymetryczności, aby być czymś innym (zwykle jest to przypadek), nie Skew
ma metody, która to zapewnia. Należy jawnie połączyć Translate
wywołania z wywołaniem Skew
. Aby wyśrodkować niesymetryczność na px
i py
, wykonaj następujące wywołania:
canvas.Translate(px, py);
canvas.Skew(xSkew, ySkew);
canvas.Translate(-px, -py);
Formuły transformacji złożonej to:
x' = x + xSkew · (y – py)
y' = ySkew · (x – px) + y
Jeśli ySkew
wartość jest równa zero, px
wartość nie jest używana. Wartość jest nieistotna i podobnie dla ySkew
i py
.
Możesz czuć się bardziej komfortowo, określając niesymetryczność jako kąt pochylenia, taki jak kąt α na tym diagramie:
Współczynnik przesunięcia 150 pikseli do 100 pikseli w pionie jest tangensem tego kąta, w tym przykładzie 56,3 stopni.
Plik XAML strony Niesymetryczny eksperyment kątowy jest podobny do strony Kąt niesymetryczny, z tą różnicą, że Slider
elementy wahają się od –90 stopni do 90 stopni. Plik SkewAngleExperiment
związany z kodem koncentruje tekst na stronie i używa Translate
go do ustawienia środka niesymetryczności do środka strony. Krótka SkewDegrees
metoda w dolnej części kodu konwertuje kąty na niesymetryczne wartości:
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));
}
Gdy kąt zbliża się do dodatnich lub ujemnych 90 stopni, tangens zbliża się do nieskończoności, ale kąty do około 80 stopni lub tak są użyteczne:
Mała ujemna niesymetryczność pozioma może naśladować ukośny lub kursywę tekstu, jak pokazuje strona Ukośny tekst . Klasa ObliqueTextPage
pokazuje, jak to zrobić:
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));
}
Właściwość TextAlign
właściwości jest ustawiona SKPaint
na Center
. Bez żadnych przekształceń DrawText
wywołanie ze współrzędnymi (0, 0) umieściłoby tekst w poziomie w środku linii bazowej w lewym górnym rogu. Pochylenie SkewDegrees
tekstu w poziomie 20 stopni względem punktu odniesienia. Translate
Wywołanie przenosi poziome środek linii bazowej tekstu do środka kanwy:
Na stronie Niesymetryczny tekst w tle pokazano, jak używać kombinacji niesymetryczności 45 stopni i skali pionowej, aby utworzyć cień tekstu, który odchyla się od tekstu. Oto istotnych części PaintSurface
programu obsługi:
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);
}
Cień jest wyświetlany najpierw, a następnie tekst:
Współrzędna pionowa przekazana do DrawText
metody wskazuje położenie tekstu względem punktu odniesienia. Jest to ta sama współrzędna pionowa używana do środka niesymetryczności. Ta technika nie będzie działać, jeśli ciąg tekstowy zawiera malejąco. Na przykład zastąp wyraz "dziwactwa" "Shadow", a oto wynik:
Cień i tekst są nadal wyrównane do linii bazowej, ale efekt po prostu wygląda źle. Aby rozwiązać ten problem, należy uzyskać ograniczenia tekstowe:
SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);
Wywołania Translate
muszą być dostosowywane przez wysokość malejących:
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);
Teraz cień rozciąga się od dołu tych malejących: