My goal would be to have N shapes rotating around their axes, something like:
Would could be a viable approach in SkiaSharp (I'd just need some directions)?
Thanks :)
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
I am learning SkiaSharp and I'd like to have N shapes rotating around their own vertical axis, but I can't find a way to do it.
This is the result of my OnDraw method (rotationView is updated every N milliseconds):
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++;
}
}
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 around their own axis.
Do you have any hint on how that can be achieved? Do I need N rotation matrices?
Thanks!
My goal would be to have N shapes rotating around their axes, something like:
Would could be a viable approach in SkiaSharp (I'd just need some directions)?
Thanks :)
Hi, Sal-Datoccio. According to my search, it doesn't provide a way to get the drawing sharp. A workaround is using SKCanvasView to draw each sharp one separately, and rotate the skCanvasViews.
Here is the related code, you could refer to it.
public partial class TestPage : ContentPage
{
public TestPage()
{
Title = "Testing for Animated Rotation";
canvasView1 = new SKCanvasView() { AutomationId = "1" };
canvasView2 = new SKCanvasView() { AutomationId = "2" };
canvasView3 = new SKCanvasView() { AutomationId = "3" };
canvasView4 = new SKCanvasView() { AutomationId = "4" };
canvasView5 = new SKCanvasView() { AutomationId = "5" };
canvasView6 = new SKCanvasView() { AutomationId = "6" };
canvasView1.PaintSurface += OnCanvasViewPaintSurface;
canvasView2.PaintSurface += OnCanvasViewPaintSurface;
canvasView3.PaintSurface += OnCanvasViewPaintSurface;
canvasView4.PaintSurface += OnCanvasViewPaintSurface;
canvasView5.PaintSurface += OnCanvasViewPaintSurface;
canvasView6.PaintSurface += OnCanvasViewPaintSurface;
Content = new StackLayout()
{
HorizontalOptions = LayoutOptions.Center,
Orientation = StackOrientation.Horizontal,
Children = { canvasView1, canvasView2, canvasView3, canvasView4, canvasView5, canvasView6 }
};
// Measure the text
textPaint.MeasureText(text1, ref textBounds);
}
protected override void OnAppearing()
{
base.OnAppearing();
new Animation((value) =>
{
yRotationDegrees = 360 * (float)value;
canvasView1.InvalidateSurface();
canvasView2.InvalidateSurface();
canvasView3.InvalidateSurface();
canvasView4.InvalidateSurface();
canvasView5.InvalidateSurface();
canvasView6.InvalidateSurface();
}).Commit(this, "yRotationAnimation", length: 1000, repeat: () => true);
}
protected override void OnDisappearing()
{
base.OnDisappearing();
//this.AbortAnimation("xRotationAnimation");
this.AbortAnimation("yRotationAnimation");
//this.AbortAnimation("zRotationAnimation");
}
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Find center of canvas
float xCenter = info.Width / 2;
float yCenter = info.Height / 2;
// Translate center to origin
SKMatrix matrix = SKMatrix.MakeTranslation(-xCenter, -yCenter);
float scale = 1;
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeScale(scale, scale));
// Calculate composite 3D transforms
float depth = 0.75f * scale * textBounds.Width;
SKMatrix44 matrix44 = SKMatrix44.CreateIdentity();
//matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(1, 0, 0, xRotationDegrees));
matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 1, 0, yRotationDegrees));
//matrix44.PostConcat(SKMatrix44.CreateRotationDegrees(0, 0, 1, zRotationDegrees));
SKMatrix44 perspectiveMatrix = SKMatrix44.CreateIdentity();
perspectiveMatrix[3, 2] = -1 / depth;
matrix44.PostConcat(perspectiveMatrix);
// Concatenate with 2D matrix
SKMatrix.PostConcat(ref matrix, matrix44.Matrix);
// Translate back to center
SKMatrix.PostConcat(ref matrix,
SKMatrix.MakeTranslation(xCenter, yCenter));
// Set the matrix and display the text
canvas.SetMatrix(matrix);
float xText = xCenter - textBounds.MidX;
float yText = yCenter - textBounds.MidY;
SKCanvasView view = sender as SKCanvasView;
switch (view.AutomationId)
{
case "1":
canvas.DrawText(text1, xText, yText, textPaint);
break;
case "2":
canvas.DrawText(text2, xText, yText, textPaint);
break;
case "3":
canvas.DrawText(text3, xText, yText, textPaint);
break;
case "4":
canvas.DrawText(text4, xText, yText, textPaint);
break;
case "5":
canvas.DrawText(text5, xText, yText, textPaint);
break;
case "6":
canvas.DrawText(text6, xText, yText, textPaint);
break;
}
}
}