기울이기 변환

Download Sample 샘플 다운로드

기울이기 변환이 SkiaSharp에서 기울어진 그래픽 개체를 만드는 방법 보기

SkiaSharp에서 기울이기 변환은 이 이미지의 그림자와 같은 그래픽 개체를 기울입니다.

An example of skewing from the Skew Shadow Text program

기울이기는 직사각형을 병렬로 변환하지만 기울어진 타원은 여전히 타원입니다.

변환, 크기 조정 및 회전에 대한 속성을 정의하지만 Xamarin.Forms 기울이기 속성에는 해당 속성 Xamarin.Forms 이 없습니다.

이 메서드 SKCanvasSkew 가로 기울이기 및 세로 기울이기의 두 인수를 허용합니다.

public void Skew (Single xSkew, Single ySkew)

두 번째 Skew 메서드는 이러한 인수를 단일 SKPoint 값으로 결합합니다.

public void Skew (SKPoint skew)

그러나 이러한 두 가지 방법 중 하나를 격리 상태로 사용할 가능성은 거의 없습니다.

기울이기 실험 페이지에서는 –10에서 10 사이의 기울이기 값을 실험할 수 있습니다. 텍스트 문자열은 두 Slider 요소에서 가져온 기울이기 값을 사용하여 페이지의 왼쪽 위 모서리에 배치됩니다. 클래스의 PaintSurface 처리기는 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);
    }
}

인수의 값은 xSkew 텍스트의 아래쪽을 양수 값으로 이동하거나 음수 값의 경우 왼쪽으로 이동합니다. 양수 ySkew 값의 경우 텍스트 오른쪽을 아래로 이동하거나 음수 값의 경우 위로 이동하는 값입니다.

Triple screenshot of the Skew Experiment page

값이 xSkew 값의 ySkew 음수이면 결과는 회전이지만 다소 크기가 조정됩니다.

변환 수식은 다음과 같습니다.

x' = x + xSkew · Y

y' = ySkew · x + y

예를 들어 양수 xSkew 값의 경우 변환된 값이 x' 증가하면 y 증가합니다. 이것이 기울기를 일으키는 원인입니다.

200픽셀 너비 및 100픽셀 높이의 삼각형이 점(0, 0)의 왼쪽 위 모서리와 함께 배치되고 값이 1.5인 xSkew 경우 다음 병렬 변환 결과가 표시됩니다.

The effect of the skew transform on a rectangle

아래쪽 가장자리의 좌표 값은 y 100이므로 오른쪽으로 150픽셀 이동됩니다.

0이 아닌 값 xSkewySkew경우 점(0, 0)만 동일하게 기본. 이 지점은 기울이기의 중심으로 간주될 수 있습니다. 기울이기의 중심이 다른 것(일반적으로 대개 해당)이어야 하는 경우 이를 제공하는 메서드가 없습니다 Skew . 호출을 호출과 Skew 명시적으로 결합 Translate 해야 합니다. 기울이기를 가운데에 px 배치하고 py다음을 호출합니다.

canvas.Translate(px, py);
canvas.Skew(xSkew, ySkew);
canvas.Translate(-px, -py);

복합 변환 수식은 다음과 같습니다.

x' = x + xSkew · (y – py)

y' = ySkew · (x – px) + y

0이면 ySkew 값이 px 사용되지 않습니다. 값은 관련이 없으며, 유사하게 및 에 대한 ySkew 값입니다 py.

이 다이어그램의 각도 α 같이 기울기 각도로 기울이기를 지정하는 것이 더 편할 수 있습니다.

The effect of the skew transform on a rectangle with a skewing angle indicated

150픽셀 시프트에서 100픽셀 세로로 이동하는 비율은 해당 각도의 탄젠트(이 예제에서는 56.3도)입니다.

기울이기 각도 실험 페이지의 XAML 파일은 요소가 –90도에서 90도까지의 범위를 제외하고 Slider 기울이기 각도 페이지와 유사합니다. 코드 숨김 파일은 SkewAngleExperiment 페이지의 텍스트를 가운데에 배치하고 페이지 가운데로 기울이기 중심을 설정하는 데 사용합니다 Translate . 코드 맨 아래에 있는 짧은 SkewDegrees 메서드는 각도를 기울이기 값으로 변환합니다.

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));
}

각도가 양수 또는 음수 90도에 가까워지면 탄젠트가 무한대에 접근하지만 최대 80도 정도의 각도를 사용할 수 있습니다.

Triple screenshot of the Skew Angle Experiment page

오블리크 텍스트 페이지에서 알 수 있듯이 작은 음의 가로 오차는 오블리크 또는 기울기 텍스트를 모방할 수 있습니다. 클래스는 ObliqueTextPage 수행 방법을 보여줍니다.

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));
}

TextAlignSKPaint 속성이 .로 설정됩니다 Center. 변환이 DrawText 없으면 좌표가 (0, 0)인 호출은 왼쪽 위 모서리에 기준선의 가로 가운데가 있는 텍스트를 배치합니다. 기준 SkewDegrees 선을 기준으로 텍스트를 가로로 20도 기울입니다. 호출은 Translate 텍스트 기준선의 가로 중심을 캔버스의 가운데로 이동합니다.

Triple screenshot of the Oblique Text page

기울이기 그림자 텍스트 페이지에서는 45도 기울이기와 세로 눈금의 조합을 사용하여 텍스트에서 멀리 기울어지는 텍스트 그림자를 만드는 방법을 보여 줍니다. 처리기의 관련 부분은 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);
}

그림자가 먼저 표시되고 텍스트가 표시됩니다.

Triple screenshot of the Skew Shadow Text page

메서드에 전달된 세로 DrawText 좌표는 기준선을 기준으로 텍스트의 위치를 나타냅니다. 이는 기울이기 가운데에 사용되는 것과 동일한 세로 좌표입니다. 텍스트 문자열에 하위 항목이 포함된 경우에는 이 기술이 작동하지 않습니다. 예를 들어 "Shadow"로 "quirky"라는 단어를 대체하면 결과는 다음과 같습니다.

Triple screenshot of the Skew Shadow Text page with an alternative word with descenders

그림자와 텍스트는 여전히 기준선에 맞춰지지만 효과는 잘못 보입니다. 이 문제를 해결하려면 텍스트 범위를 가져와야 합니다.

SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);

호출은 Translate 하위 항목의 높이에 따라 조정되어야 합니다.

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);

이제 그림자가 해당 하위 항목의 아래쪽에서 확장됩니다.

Triple screenshot of the Skew Shadow Text page with adjustments for descenders