In this tutorial we'll see how integrate SkiaSharp drawing inside a ReactorUI component.
Let's first install ReactorUI SkiaSharp binding package:
Install-Package XamarinReactorUI.Skia
XamarinReactorUI.Skia package provides two classes: RxSKCanvasView and RxSKGLView. They can be used to integrate SkiaSharp backends in a component.
Let's create a sample empty page:
public class MainPage : RxComponent
{
public override VisualNode Render()
{
return new RxContentPage()
{
};
}
}
To draw some graphics we just need to create a RxSKCanvasView and handle the OnPaintSurfacecallback (sample drawing code is freely copied from Xamarin doc):
public class MainPageState : IState
{
public double RotationAngle { get; set; }
}
public class MainPage : RxComponent<MainPageState>
{
public override VisualNode Render()
{
return new RxContentPage()
{
new RxSKCanvasView()
.OnPaintSurface(OnPaintCanvasSurface)
};
}
private void OnPaintCanvasSurface(SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
string text = "OUTLINE";
// Create an SKPaint object to display the text
SKPaint textPaint = new SKPaint
{
Style = SKPaintStyle.Stroke,
StrokeWidth = 1,
FakeBoldText = true,
Color = SKColors.Blue
};
// Adjust TextSize property so text is 95% of screen width
float textWidth = textPaint.MeasureText(text);
textPaint.TextSize = 0.95f * info.Width * textPaint.TextSize / textWidth;
// Find the text bounds
SKRect textBounds = new SKRect();
textPaint.MeasureText(text, ref textBounds);
// Calculate offsets to center the text on the screen
float xText = info.Width / 2 - textBounds.MidX;
float yText = info.Height / 2 - textBounds.MidY;
// And draw the text
canvas.DrawText(text, xText, yText, textPaint);
}
}
If you run the app you should something like this:
Now let's add some interactivity: for example adding the ability to rotate the text. We need a state that hold the current rotation angle, a slider to allow user modify this value, finally we need to invalidate SkiaSharp canvas when angle changes:
public class MainPageState : IState
{
public double RotationAngle { get; set; }
}
public class MainPage : RxComponent<MainPageState>
{
private SKCanvasView _canvasView;
public override VisualNode Render()
{
return new RxContentPage()
{
new RxStackLayout()
{
new RxLabel("Rotation Angle"),
new RxSlider()
.Minimum(0)
.Maximum(360.0)
.Value(State.RotationAngle)
.OnValueChanged(v => SetState(s =>
{
s.RotationAngle = v.NewValue;
_canvasView.InvalidateSurface();
}))
.HFill()
.VStart(),
new RxSKCanvasView(canvasView => _canvasView = canvasView)
.OnPaintSurface(OnPaintCanvasSurface)
.VFillAndExpand()
}
};
}
private void OnPaintCanvasSurface(SKPaintSurfaceEventArgs args)
{
.... omitted for brevity ....
// And draw the text
canvas.RotateDegrees((float)State.RotationAngle, info.Width / 2, info.Height / 2);
canvas.DrawText(text, xText, yText, textPaint);
}
}