4

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

LCJ
  • 22,196
  • 67
  • 260
  • 418
  • 2
    try removing the extra MoveTo calls - this may be confusing the fill algorithm? – Jason Jul 25 '17 at 19:37
  • @Jason Thanks. Removing `MoveTo` did the trick. Can you please post it as an answer? Also, can you please tell whether there is any GitHub projects that I can refer for advanced SkiaSharp samples? – LCJ Jul 25 '17 at 21:40

2 Answers2

8

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();
Jason
  • 86,222
  • 15
  • 131
  • 146
  • 1
    The reason the `MoveTo` is breaking the fill is because the move starts a new path. A `SKPath` can consist of multiple paths. In the case of your example, you are only closing the last segment of the last path. – Matthew Jul 26 '17 at 22:49
1

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

LCJ
  • 22,196
  • 67
  • 260
  • 418