0

In a nutshell, let's say, I need to draw a complex object (arrow) which consists of certain amount of objects, like five (or more) lines, for instance. And what's more important, that object must be transformed with particular (dynamic) coordinates (including scaling, possibly).

My question is whether SkiaSharp has anything which I can use for manipulating of this complex object transformation (some sort of grouping etc.) or do I still need to calculate every single point manually (with matrix, for instance).

This question is related particularly to SkiaSharp as I use it on Xamarin, but maybe some general answers from Skia can also help with it?


I think, the question might be too common (and possibly not for stackoverflow exactly), but I just can't find any specific information in google.

Yes, I know how to use SkiaSharp for drawing primitives.

Agat
  • 4,577
  • 2
  • 34
  • 62
  • you can apply a transform to an entire SKPath – Jason Sep 21 '20 at 12:32
  • @Jason, what do you mean by "entire SKPath"? I am using canvas.DrawLine (... SKPaint) for drawing a piece of the object. So, the transformation must be applied to this particular object, when there might be some other objects drawn with their own transformations... – Agat Sep 21 '20 at 14:05
  • First, this is why you need to show code in your questions, so people know what you are doing and don't have to guess – Jason Sep 21 '20 at 14:08
  • second, "A path encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves." https://learn.microsoft.com/en-us/dotnet/api/skiasharp.skpath?view=skiasharp-1.68.2 – Jason Sep 21 '20 at 14:08
  • 1
    You can draw a shape like an arrow with paths and then apply a transform to the entire path – Jason Sep 21 '20 at 14:09

2 Answers2

2

create an SKPath and add lines and other shapes to it

SKPath path = new SKPath();
path.LineTo(...);
... 
...

then draw the SKPath on your canvas

canvas.DrawPath(path,paint);

you can apply a transform to the entire path before drawing

var rot = new SKMatrix();
SKMatrix.RotateDegrees(ref rot, 45.0f);
path.Transform(rot);
Jason
  • 86,222
  • 15
  • 131
  • 146
0

If you are drawing something more complex than a path SKPicture is perfect for this. You can set it up so that you construct it once and then reuse it easily and efficiently. In the example below, the SKPicture's origin is in the center of a 100 x 100 rectangle but that is arbitrary.

SKPicture myPicture;
SKPicture MyPicture {
    get {
        if(myPicture != null) {
            return myPicture;
        }
        using(SKPictureRecorder recorder = new SKPictureRecorder())
        using(SKCanvas canvas = recorder.BeginRecording(new SKRect(-50, -50, 50, 50)))
            // draw using primitives
            ...
            myPicture = recorder.EndRecording();
        }
        return myPicture;
    }
}

Then you apply your transforms to the canvas, draw the picture and restore the canvas state. offsetX and offsetY correspond to where the origin of the SKPicture will be rendered.

canvas.Save();
canvas.Translate(offsetX, offsetY);
canvas.Scale(scaleAmount);
canvas.RotateDegrees(degrees);
canvas.DrawPicture(MyPicture);
canvas.Restore();
Harlan
  • 141
  • 8