Salvuccino
Salvuccino

Reputation: 73

Skia / SkiaSharp - Rotating shapes around their own vertical axis

SKIA / SKIASHARP

I generate the scene above using the OnDraw method below:

  protected override void OnDraw(SKCanvas canvas, int width, int height)
    {
        int i = 0;
        int step = 0;
        List<SKRect> rects = new List<SKRect>();

        // get the 2D equivalent of the 3D matrix
        var rotationMatrix = rotationView.Matrix;

        // get the properties of the rectangle
        var length = Math.Min(width / 6, height / 6);

        canvas.Clear(EffectMedia.Colors.XamarinLightBlue);

        foreach (var n in numbers)
        {
            var rect = new SKRect(0 + step, 0, 100 + step, 100);
            rects.Add(rect);
            step += 120;
        }

        //var sideHoriz = rotationMatrix.MapPoint(new SKPoint(0, 1)).Y > 0;
        var sideVert = rotationMatrix.MapPoint(new SKPoint(1, 0)).X > 0;

        var paint = new SKPaint
        {
            Color = sideVert ? EffectMedia.Colors.XamarinPurple : EffectMedia.Colors.XamarinGreen,
            Style = SKPaintStyle.Fill,
            IsAntialias = true
        };

        // first do 2D translation to the center of the screen
        canvas.Translate((width - (120 * numbers.Count)) / 2, height / 2);

        // The following line is disabled because it makes the whole canvas rotate!
        // canvas.Concat(ref rotationMatrix);

        foreach (var n in numbers)
        {            
            canvas.RotateDegrees((float)-3);
            canvas.DrawRoundRect(rects[i], 30, 30, paint);

            var shadow = SKShader.CreateLinearGradient(
                    new SKPoint(0, 0), new SKPoint(0, length * 2),
                    new[] { paint.Color.WithAlpha(127), paint.Color.WithAlpha(0) },
                    null,
                    SKShaderTileMode.Clamp);

            var paintShadow = new SKPaint
            {
                Shader = shadow,
                Style = SKPaintStyle.Fill,
                IsAntialias = true,
                BlendMode = SKBlendMode.SoftLight
            };

            foreach (var r in rects)
            {
                r.Offset(0, 105);
                canvas.DrawRoundRect(r, 30, 30, paintShadow);
            }

            i++;
        }
    }

The idea is to make all those rounded boxes rotate (vertically) around their own axis.

I tried using SKPath + Transform, saving&restoring the rotationMatrix and/or the canvas but I can't find a way to have 6 rotating boxes ( canvas.Concat(ref rotationMatrix); makes the whole canvas rotate [*]).

Do you have any hint on how that can be achieved?

Note [*]: there's a call to rotationView.RotateYDegrees(5) every X milliseconds to update the rotationMatrix used by OnDraw.

Upvotes: 1

Views: 724

Answers (1)

Salvuccino
Salvuccino

Reputation: 73

This is what I'd like to achieve, any hints / directions would be really appreciated... :-)

enter image description here

The following piece of code rotates those shapes around their Z-axis:

canvas.Save();
canvas.RotateDegrees(degrees, rects[i].MidX, rects[i].MidY);
canvas.DrawRoundRect(rects[i], 30, 30, paint);
canvas.Restore();

Thanks

Upvotes: 1

Related Questions