LCJ
LCJ

Reputation: 22652

SkiaSharp does not fill triangle with StrokeAndFill

I am trying to draw and fill a triangle. I referred an android - question How to draw filled triangle on android Canvas and did the following. It draws the triangle but it doesn’t fill it. How to get it filled? Also, is it possible to get it filled with a different color than the line color?

Xamarin Forms

private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
{
        var surface = e.Surface;
        var canvas = surface.Canvas;
        canvas.Clear(SKColors.White);


        var pathStroke2 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(244, 0, 110, 200),
            StrokeWidth = 5
        };

        var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path2.MoveTo(0, 0);
        path2.LineTo(0, 140);
        path2.MoveTo(0, 140);
        path2.LineTo(140, 140);
        path2.MoveTo(140, 140);
        path2.LineTo(0, 0);
        path2.Close();
        canvas.DrawPath(path2, pathStroke2);

    }

enter image description here

Upvotes: 4

Views: 3890

Answers (2)

LCJ
LCJ

Reputation: 22652

Removing unwanted MoveTo lines solved it, as per the comment from Jason.

Following is complete code.

   private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
   {

        var surface = e.Surface;
        var canvas = surface.Canvas;
        canvas.Clear(SKColors.White);

        var w = e.Info.Width;
        var h = e.Info.Height;

        SKColor[] colors;
        colors = new SKColor[] {
                 new SKColor(244, 0, 110, 200), new SKColor(244, 0, 110, 220),
                 new SKColor(244, 0, 110, 240),new SKColor(244, 0, 110, 240),
                 new SKColor(244, 0, 100,240),
                 new SKColor(244, 0, 100),
                 new SKColor(255, 0, 70)
                };
        SKShader shaderLeft = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(w, h), colors, null, SKShaderTileMode.Clamp);
        var paint = new SKPaint() { Shader = shaderLeft };
        canvas.DrawPaint(paint);


       var path2 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path2.MoveTo(0, 0);
        path2.LineTo(0, 140);
        path2.LineTo(140, 140);
        path2.LineTo(0, 0);
        path2.Close();

        var pathStroke2 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(0, 0, 0, 30),
            StrokeWidth = 5
        };

        using (var cf = SKColorFilter.CreateBlendMode(new SKColor(244, 0, 110, 200), SKBlendMode.DstIn))
        {
            var transparency = SKColors.White.WithAlpha(127); 
            pathStroke2.ColorFilter = cf;

            // ... draw ...
            canvas.DrawPath(path2, pathStroke2);

            pathStroke2.ColorFilter = null;
        }

        var pathStroke3 = new SKPaint
        {
            IsAntialias = true,
            Style = SKPaintStyle.StrokeAndFill,
            Color = new SKColor(0, 0, 0, 30),
            StrokeWidth = 5
        };

        var path3 = new SKPath { FillType = SKPathFillType.EvenOdd };
        path3.MoveTo(170, 0);
        path3.LineTo(170, 140);
        path3.LineTo(300, 140);
        path3.LineTo(170, 0);
        path3.Close();
        canvas.DrawPath(path3, pathStroke3);

    }

enter image description here

Upvotes: 1

Jason
Jason

Reputation: 89102

you don't need to use both LineTo() and MoveTo() - I suspect doing so is breaking the fill algorithm. Instead, just use

path2.MoveTo(0, 0);
path2.LineTo(0, 140);
path2.LineTo(140, 140);
path2.LineTo(0, 0);
path2.Close();

Upvotes: 8

Related Questions