Last active
October 7, 2020 04:48
-
-
Save benoitjadinon/c0055013da4f256917ad7f538c1fcbff to your computer and use it in GitHub Desktop.
SkiaSharp Xamarin Coach Marks Overlay
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Collections.Generic; | |
| using System.Drawing; | |
| using SkiaSharp; | |
| #if __IOS__ | |
| using SkiaSharp.Views.iOS; | |
| using UIKit; | |
| #elif __ANDROID__ | |
| using SkiaSharp.Views.Android; | |
| #endif | |
| namespace some | |
| { | |
| public class CoachMarks : ICoachMarks | |
| { | |
| private List<CoachMark> Marks { get; } = new List<CoachMark>(); | |
| SKPaint paint = new SKPaint { | |
| IsAntialias = true, | |
| Color = 0xFF0000FF, | |
| Style = SKPaintStyle.Fill, | |
| }; | |
| SKPaint bgPaint = new SKPaint { | |
| IsAntialias = false, | |
| Color = 0xAA000000, | |
| Style = SKPaintStyle.Fill, | |
| }; | |
| private SKPaint textPaint = new SKPaint | |
| { | |
| IsAntialias = true, | |
| Color = 0xFF00FF00, | |
| TextSize = 40, | |
| FakeBoldText = true | |
| //Typeface = | |
| }; | |
| private SKCanvasView skiaCanvasView = null; | |
| public ICoachMarks Add(RectangleF rect, string text, CoachMarkPosition textPosition = null) | |
| { | |
| this.Marks.Add(new CoachMark(rect, text, textPosition)); | |
| ReDraw(); | |
| return this; | |
| } | |
| public ICoachMarks Create() | |
| { | |
| Marks.Clear(); | |
| #if __IOS__ | |
| if (skiaCanvasView == null) | |
| { | |
| skiaCanvasView = new SKCanvasView(UIApplication.SharedApplication.KeyWindow.Bounds); | |
| skiaCanvasView.BackgroundColor = UIColor.Clear; | |
| skiaCanvasView.Opaque = false; | |
| UIApplication.SharedApplication.KeyWindow.AddSubview(skiaCanvasView); | |
| skiaCanvasView.FillParent(); | |
| skiaCanvasView.UserInteractionEnabled = true; | |
| skiaCanvasView.AddGestureRecognizer (new UITapGestureRecognizer(skiaCanvasView.RemoveFromSuperview)); | |
| skiaCanvasView.PaintSurface += (sender, e) => | |
| { | |
| var canvas = e.Surface.Canvas; | |
| var size = e.Info.Size; | |
| Draw(canvas, size, (float)skiaCanvasView.ContentScaleFactor); | |
| }; | |
| } | |
| #elif __ANDROID__ | |
| //TODO | |
| #endif | |
| ReDraw(); | |
| return this; | |
| } | |
| private void ReDraw() | |
| { | |
| #if __IOS__ | |
| skiaCanvasView.SetNeedsDisplay(); | |
| #elif __ANDROID__ | |
| skiaCanvasView.Invalidate(); | |
| #endif | |
| } | |
| private void Draw(SKCanvas canvas, SKSize size, float scale = 1) | |
| { | |
| canvas.Clear(); | |
| // clipping | |
| foreach (var mark in Marks) | |
| { | |
| var pos = mark.Pos.Scale(scale); | |
| canvas.ClipRect(new SKRect(pos.Left, pos.Top, pos.Right, pos.Bottom), SKClipOperation.Difference); | |
| } | |
| // clipping reset | |
| canvas.ResetMatrix(); | |
| // background | |
| canvas.DrawRect(0, 0, size.Width, size.Height, bgPaint); | |
| // mark texts | |
| foreach (var mark in this.Marks) | |
| { | |
| var pos = mark.Pos.Scale(scale); | |
| if (mark.TextPosition.V == -1) | |
| canvas.DrawText(mark.Text, pos.X, pos.Y, textPaint); | |
| else if (mark.TextPosition.V == 0) | |
| canvas.DrawText(mark.Text, pos.X, pos.Y + pos.Height, textPaint); | |
| else if (mark.TextPosition.V == +1) | |
| { | |
| SKFontMetrics metrics; | |
| textPaint.GetFontMetrics(out metrics, scale); | |
| canvas.DrawText(mark.Text, pos.X, pos.Y + pos.Height + metrics.XHeight, textPaint); | |
| } | |
| } | |
| } | |
| private class CoachMark | |
| { | |
| public RectangleF Pos { get; } | |
| public string Text { get; } | |
| public CoachMarkPosition TextPosition { get; } | |
| public CoachMark(RectangleF pos, string text, CoachMarkPosition textPosition = null) | |
| { | |
| Pos = pos; | |
| Text = text; | |
| TextPosition = textPosition ?? CoachMarkPosition.Below; | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.