private static void RenderFrame(object sender, SKSurface surface) { SkiaGLWidget gLWidget = sender as SkiaGLWidget; SKCanvas canvas = surface.Canvas; canvas.Clear(); SKPoint center = new SKPoint(gLWidget.Allocation.Width / 2, gLWidget.Allocation.Height / 2); float radius = Math.Min(gLWidget.Allocation.Width, gLWidget.Allocation.Height) / 4; SKPath path = new SKPath { FillType = SKPathFillType.EvenOdd }; path.AddCircle(center.X - radius / 2, center.Y - radius / 2, radius); path.AddCircle(center.X - radius / 2, center.Y + radius / 2, radius); path.AddCircle(center.X + radius / 2, center.Y - radius / 2, radius); path.AddCircle(center.X + radius / 2, center.Y + radius / 2, radius); SKPaint paint = new SKPaint() { Style = SKPaintStyle.Fill, Color = SKColors.Cyan }; canvas.DrawPath(path, paint); paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 10; paint.Color = SKColors.Magenta; canvas.DrawPath(path, paint); }
public void FillCircle(double x, double y, double radius) { BeginPath(); _path.AddCircle((float)x, (float)y, (float)radius); ClosePath(); Fill(); }
private static SKPath DefaultRoller() { // Изображение шарнирно-неподвижной опорной части SKPath pin = new SKPath(); // Шарнир вверху pin.AddCircle(0, 0, 1); pin.AddCircle(0, 3.6f, 1); // Вертикальная линия pin.MoveTo(0, 1); pin.LineTo(0, 3.6f - 1); // Нижняя линия основания pin.MoveTo(-1.8f, 3.6f + 1); pin.LineTo(1.8f, 3.6f + 1); // Штриховка основания float s = 2 * 1.6f / 4; float x1 = -1.6f; float y1 = 3.6f + 1; for (int i = 0; i < 5; i++) { pin.MoveTo(x1, y1); pin.LineTo(x1 - 1.6f, y1 + 1.6f); x1 += s; } return(pin); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); SKPoint center = new SKPoint(info.Width / 2, info.Height / 2); float radius = Math.Min(info.Width, info.Height) / 4; SKPath path = new SKPath { FillType = SKPathFillType.EvenOdd }; path.AddCircle(center.X - radius / 2, center.Y - radius / 2, radius); path.AddCircle(center.X - radius / 2, center.Y + radius / 2, radius); path.AddCircle(center.X + radius / 2, center.Y - radius / 2, radius); path.AddCircle(center.X + radius / 2, center.Y + radius / 2, radius); SKPaint paint = new SKPaint() { Style = SKPaintStyle.Fill, Color = SKColors.Cyan }; canvas.DrawPath(path, paint); paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = 10; paint.Color = SKColors.Magenta; canvas.DrawPath(path, paint); }
public static SKPath CreateSectorPath(float start, float end, float outerRadius, float innerRadius = 0.0f, float margin = 0.0f) { var path = new SKPath(); // If the sector has no size, then it has no path if (start == end) { return(path); } // The the sector is a full circle, then do that if (end - start == 1.0f) { path.AddCircle(0, 0, outerRadius, SKPathDirection.Clockwise); path.AddCircle(0, 0, innerRadius, SKPathDirection.Clockwise); path.FillType = SKPathFillType.EvenOdd; return(path); } // Calculate the angles var startAngle = (TotalAngle * start) - UprightAngle; var endAngle = (TotalAngle * end) - UprightAngle; var large = endAngle - startAngle > PI ? SKPathArcSize.Large : SKPathArcSize.Small; var sectorCenterAngle = ((endAngle - startAngle) / 2f) + startAngle; // Get the radius bits var cectorCenterRadius = ((outerRadius - innerRadius) / 2f) + innerRadius; // Calculate the angle for the margins var offsetR = outerRadius == 0 ? 0 : ((margin / (TotalAngle * outerRadius)) * TotalAngle); var offsetr = innerRadius == 0 ? 0 : ((margin / (TotalAngle * innerRadius)) * TotalAngle); // Get the points var a = GetCirclePoint(outerRadius, startAngle + offsetR); var b = GetCirclePoint(outerRadius, endAngle - offsetR); var c = GetCirclePoint(innerRadius, endAngle - offsetr); var d = GetCirclePoint(innerRadius, startAngle + offsetr); // Add the points to the path path.MoveTo(a); path.ArcTo(outerRadius, outerRadius, 0, large, SKPathDirection.Clockwise, b.X, b.Y); path.LineTo(c); if (innerRadius == 0.0f) { // Take a short cut path.LineTo(d); } else { path.ArcTo(innerRadius, innerRadius, 0, large, SKPathDirection.CounterClockwise, d.X, d.Y); } path.Close(); return(path); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); using (SKPath circlePath = new SKPath()) { circlePath.AddCircle(info.Width / 2, info.Height / 2, Math.Min(info.Width / 2, info.Height / 2) - redThickStroke.StrokeWidth); if (!outlineThePath) { canvas.DrawPath(circlePath, blueFill); canvas.DrawPath(circlePath, redThickStroke); } else { using (SKPath outlinePath = new SKPath()) { redThickStroke.GetFillPath(circlePath, outlinePath); canvas.DrawPath(outlinePath, blueFill); canvas.DrawPath(outlinePath, redThinStroke); } } } }
public World(int fps) : base(null) { Name = "World"; clipPath = new SKPath(); clipPath.AddCircle(180, 180, 180); this.fps = fps; IsClickable = true; startButton = new StartButton(this) { IsClickable = true }; butterCat = new ButterCat(this); butter = new Butter(this); startButton.Clicked += (s, e) => { startButton.IsVisible = false; if (!isStarted) { butter.Animate().ContinueWith(t => StartGame()); } }; random = new Random(); distance = new DistanceLabel(this) { IsVisible = false, ZOrder = 1 }; }
public void FillCircle(float x, float y, float radius) { BeginPath(); _path.AddCircle(x, y, radius); ClosePath(); Fill(); }
void UpdateShape() { var path = new SKPath(); path.AddCircle(0, 0, 1); UpdateShape(path); }
public override void Render(SKCanvas canvas, PlotSettings.Axes axes) { using (SKPath linePath = new SKPath()) { linePath.MoveTo(axes.GetPixel(xs[0], ys[0])); // draw lines for (int i = 1; i < xs.Length; i++) { linePath.LineTo(axes.GetPixel(xs[i], ys[i])); } style.paint.Style = SKPaintStyle.Stroke; canvas.DrawPath(linePath, style.paint); } // draw markers using (SKPath markerPath = new SKPath()) { for (int i = 0; i < xs.Length; i++) { SKPoint pt = axes.GetPixel(xs[i], ys[i]); markerPath.AddCircle(pt.X, pt.Y, 3); } style.paint.Style = SKPaintStyle.Fill; canvas.DrawPath(markerPath, style.paint); } }
void DisplayClipOp(SKCanvas canvas, SKRect rect, SKClipOperation clipOp) { float textSize = textPaint.TextSize; canvas.DrawText(clipOp.ToString(), rect.MidX, rect.Top + textSize, textPaint); rect.Top += textSize; float radius = 0.9f * Math.Min(rect.Width / 3, rect.Height / 2); float xCenter = rect.MidX; float yCenter = rect.MidY; canvas.Save(); using (SKPath path1 = new SKPath()) { path1.AddCircle(xCenter - radius / 2, yCenter, radius); canvas.ClipPath(path1); using (SKPath path2 = new SKPath()) { path2.AddCircle(xCenter + radius / 2, yCenter, radius); canvas.ClipPath(path2, clipOp); canvas.DrawPaint(fillPaint); } } canvas.Restore(); }
public void DrawHole(SKCanvas canvas, SKRect rect, float scale = 1) { using (SKPath path = new SKPath()) { path.AddCircle(rect.Left + rect.Width / 2, rect.Top + rect.Height / 2, rect.Width / 2); canvas.ClipPath(path, SKClipOperation.Difference); } }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { // Retrieve canvas state. SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; // Clear any drawing from previous draw call. canvas.Clear(); int radius = 10; // Create circular path using (SKPath circlePath = new SKPath()) { circlePath.AddCircle(0, 0, radius); // Create circular region using (SKRegion circleRegion = new SKRegion()) { // Defines a region that is 20 x 20 pixel units. circleRegion.SetRect(new SKRectI(-radius, -radius, radius, radius)); circleRegion.SetPath(circlePath); // Set transform to move it to center and scale up canvas.Translate(info.Width / 2, info.Height / 2); // This scales the region to be proportional to our arbitrary units. canvas.Scale(Math.Min(info.Width / 2, info.Height / 2) / radius); // Fill region using (SKPaint fillPaint = new SKPaint()) { fillPaint.Style = SKPaintStyle.Fill; fillPaint.Color = SKColors.Orange; // The circle appears pixelated because our // defined region defines the pixel count. canvas.DrawRegion(circleRegion, fillPaint); } // Fill paint is properly disposed of. // Stroke path for comparison using (SKPaint strokePaint = new SKPaint()) { strokePaint.Style = SKPaintStyle.Stroke; strokePaint.Color = SKColors.Blue; strokePaint.StrokeWidth = 0.1f; // The drawn path is not pixelated as it // is not bounded by a region. canvas.DrawPath(circlePath, strokePaint); } // Stoke paint is properly disposed of. } // Circle region is properly disposed of. } // Circle path is properly disposed of. }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; SKPaint Paint = new SKPaint { Style = SKPaintStyle.Fill, IsAntialias = true, Color = ((SKCanvasView)sender).BackgroundColor.ToSKColor() }; SKPoint center = new SKPoint(info.Width / 2, info.Height / 2); canvas.Clear(); float radius = Math.Min(info.Width / 2, info.Height / 2); using (SKPath path = new SKPath()) { path.MoveTo(center); path.AddCircle(center.X, center.Y, radius); path.Close(); canvas.DrawPath(path, Paint); canvas.Restore(); ((SKCanvasView)sender).BackgroundColor = Color.Transparent; } //SKCanvasView info = (SKCanvasView)sender; //float size = (float)info.WidthRequest; //SKSurface surface = args.Surface; //SKCanvas canvas = surface.Canvas; //SKPoint center = new SKPoint(size / 2, size / 2); //canvas.Clear(); //float radius = size / 2; //using (SKPath path = new SKPath()) //{ // path.MoveTo(center); // path.AddCircle(center.X - radius, center.Y - radius, radius); // path.Close(); // canvas.DrawPath(path, arcPaint); // canvas.Restore(); //} }
private static SKPath Hinge() { // Изображение шарнира SKPath pin = new SKPath(); // Шарнир вверху pin.AddCircle(0, 0, 1); return(pin); }
/// <summary> /// Creates Circle /// </summary> /// <param name="radius">The radius of the circle.</param> /// <returns>SKPath in the shape of a circle.</returns> internal static SKPath GetCirclePath(float radius) { var path = new SKPath() { FillType = SKPathFillType.EvenOdd, Convexity = SKPathConvexity.Convex }; path.AddCircle(0, 0, radius); return(path); }
public void SkiaSetup() { // square blockPath.MoveTo(0, 0); blockPath.LineTo(0, blockSize); blockPath.LineTo(blockSize, blockSize); blockPath.LineTo(blockSize, 0); blockPath.Close(); // triangle playerPath.MoveTo(0, 0); playerPath.LineTo(blockSize, 0); playerPath.LineTo(blockSize / 2, blockSize); playerPath.Close(); // triangle princessPath.MoveTo(0, 0); princessPath.LineTo(blockSize, 0); princessPath.LineTo(blockSize / 2, blockSize); princessPath.Close(); // triangle monsterPath.MoveTo(0, 0); monsterPath.LineTo(blockSize, 0); monsterPath.LineTo(blockSize / 2, blockSize); monsterPath.Close(); // square exitPath.MoveTo(0, 0); exitPath.LineTo(0, blockSize); exitPath.LineTo(blockSize, blockSize); exitPath.LineTo(blockSize, 0); exitPath.Close(); // circle weaponPath.AddCircle(blockSize / 2, blockSize / 2, blockSize / 2, SKPathDirection.Clockwise); weaponPath.Close(); // circle foodPath.AddCircle(blockSize / 2, blockSize / 2, blockSize / 2, SKPathDirection.Clockwise); foodPath.Close(); // circle lootPath.AddCircle(blockSize / 2, blockSize / 2, blockSize / 2, SKPathDirection.Clockwise); lootPath.Close(); // diamond puzzlePath.MoveTo(blockSize * 0.5f, 0); puzzlePath.LineTo(blockSize, blockSize * 0.5f); puzzlePath.LineTo(blockSize * 0.5f, blockSize); puzzlePath.LineTo(0, blockSize * 0.5f); puzzlePath.Close(); }
static void PrepBitmap(SKCanvas bitmapCanvas, int bitmapSize) { // Set clipping path based on bitmap size using (SKPath bitmapClipPath = new SKPath()) { bitmapClipPath.AddCircle(bitmapSize / 2, bitmapSize / 2, bitmapSize / 2); bitmapCanvas.ClipPath(bitmapClipPath); } // Color the bitmap background bitmapCanvas.Clear(backgroundColor); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); float size = Math.Min(info.Width, info.Height); float radius = 0.4f * size; float offset = size / 2 - radius; // Translate to center canvas.Translate(info.Width / 2, info.Height / 2); using (SKPath path = new SKPath()) { path.AddCircle(-offset, -offset, radius); canvas.ClipPath(path, SKClipOperation.Intersect); path.Reset(); path.AddCircle(-offset, offset, radius); canvas.ClipPath(path, SKClipOperation.Intersect); path.Reset(); path.AddCircle(offset, -offset, radius); canvas.ClipPath(path, SKClipOperation.Intersect); path.Reset(); path.AddCircle(offset, offset, radius); canvas.ClipPath(path, SKClipOperation.Intersect); using (SKPaint paint = new SKPaint()) { paint.Style = SKPaintStyle.Fill; paint.Color = SKColors.Blue; canvas.DrawPaint(paint); } } }
private void CanvasView_PaintSurface(object sender, SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); if (lastSize.Width != info.Width || lastSize.Height != info.Height) { lastSize.Width = info.Width; lastSize.Height = info.Height; radius = (float)Math.Min(lastSize.Width, lastSize.Height); isChanged = true; } if (isChanged) { circleMaskPath = CreateCircleMaskPath(info.Width, info.Height); isChanged = false; } wavePath = CreateWaveMaskPath(info.Width, info.Height, radius / 5 / 2 / 2 / 2, transX, transY, 5); if (wavePaint == null) { wavePaint = new SKPaint { Style = SKPaintStyle.Fill, Color = FullColor.ToSKColor() }; } SKPath cirlePath = new SKPath(); cirlePath.AddCircle(info.Width / 2, info.Height / 2, Math.Min(info.Width, info.Height) / 2); canvas.ClipPath(cirlePath); canvas.DrawPath(cirlePath, circlePaint); canvas.DrawPath(wavePath, wavePaint); //canvas.DrawPath(circleMaskPath, circlePaint); if (isAnimate == false) { Animate(); isAnimate = true; } }
public SKPath CreateCircleMaskPath(float width, float height) { var min = Math.Min(width, height); SKPath path = new SKPath(); path.FillType = SKPathFillType.EvenOdd; path.AddCircle(width / 2, height / 2, min / 2); path.AddRect(new SKRect(0, 0, width, height)); path.Close(); return(path); }
public SKPath Render(SKCanvas g, Rectangle r, NodeStyle o) { this.UpdateBounds(r); var skPath = new SKPath(); skPath.AddCircle(this.Bounds.Center().X, this.Bounds.Center().Y, this.Bounds.Center().Y - this.Bounds.Y); using (var p = new SKPaint() { IsAntialias = true }) { p.Color = new Pen(this.GetBackBrush()).Color.ToSKColor(); g.DrawPath(skPath, p); return(skPath); } }
private async void HandlePaintCanvas(object sender, SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKCanvas canvas = e.Surface.Canvas; canvas.Clear(); if (_doSave) { using (var hole = new SKPath()) { hole.AddCircle(info.Width / 2, info.Height / 2, info.Width / 3); canvas.ClipPath(hole, antialias: true); } } canvas.SetMatrix(_m); //Draw ball image SKSize imgSize = new SKSize(_bitmap.Width, _bitmap.Height); SKRect aspectRect = SKRect.Create(info.Width, info.Height).AspectFit(imgSize); canvas.DrawBitmap(_bitmap, aspectRect); if (!_doSave) { canvas.ResetMatrix(); //Draw circle overlay using (var frame = new SKPath()) using (var hole = new SKPath()) { frame.AddRect(info.Rect); hole.AddCircle(info.Width / 2, info.Height / 2, info.Width / 3); SKPath frameHole = frame.Op(hole, SKPathOp.Difference); using (var p = new SKPaint { IsAntialias = true, Style = SKPaintStyle.Fill, Color = new SKColor(128, 128, 128, 200) }) { canvas.DrawPath(frameHole, p); } } } else { SKImage snapI = e.Surface.Snapshot(); snapI = snapI.Subset(canvas.DeviceClipBounds); SKData pngImage = snapI.Encode(); File.WriteAllBytes(_ballFilename, pngImage.ToArray()); await Navigation.PopAsync(); OnBallImageUpdated(_ballFilename); } }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); int radius = 10; // Create circular path using (SKPath circlePath = new SKPath()) { circlePath.AddCircle(0, 0, radius); // Create circular region using (SKRegion circleRegion = new SKRegion()) { circleRegion.SetRect(new SKRectI(-radius, -radius, radius, radius)); circleRegion.SetPath(circlePath); // Set transform to move it to center and scale up canvas.Translate(info.Width / 2, info.Height / 2); canvas.Scale(Math.Min(info.Width / 2, info.Height / 2) / radius); // Fill region using (SKPaint fillPaint = new SKPaint()) { fillPaint.Style = SKPaintStyle.Fill; fillPaint.Color = SKColors.Orange; canvas.DrawRegion(circleRegion, fillPaint); } // Stroke path for comparison using (SKPaint strokePaint = new SKPaint()) { strokePaint.Style = SKPaintStyle.Stroke; strokePaint.Color = SKColors.Blue; strokePaint.StrokeWidth = 0.1f; canvas.DrawPath(circlePath, strokePaint); } } } }
public static byte[] CreateRoundImage(byte[] data, int size) { using (var bitmap = SKBitmap.Decode(data)) using (var resultBitmap = new SKBitmap(size, size)) using (var canvas = new SKCanvas(resultBitmap)) using (var path = new SKPath()) { var widthHeight = Math.Min(bitmap.Width, bitmap.Height); var scale = (float)size / widthHeight; canvas.Clear(); path.AddCircle(size / 2, size / 2, size / 2); canvas.ClipPath(path); canvas.Scale(scale, scale); canvas.DrawBitmap(bitmap, (widthHeight - bitmap.Width) / 2, (widthHeight - bitmap.Height) / 2); return(ToPngData(resultBitmap)); } }
void DisplayClipOp(SKCanvas canvas, SKRect rect, SKRegionOperation regionOp) { float textSize = textPaint.TextSize; canvas.DrawText(regionOp.ToString(), rect.MidX, rect.Top + textSize, textPaint); rect.Top += textSize; float radius = 0.9f * Math.Min(rect.Width / 3, rect.Height / 2); float xCenter = rect.MidX; float yCenter = rect.MidY; SKRectI recti = new SKRectI((int)rect.Left, (int)rect.Top, (int)rect.Right, (int)rect.Bottom); using (SKRegion wholeRectRegion = new SKRegion()) { wholeRectRegion.SetRect(recti); using (SKRegion region1 = new SKRegion(wholeRectRegion)) using (SKRegion region2 = new SKRegion(wholeRectRegion)) { using (SKPath path1 = new SKPath()) { path1.AddCircle(xCenter - radius / 2, yCenter, radius); region1.SetPath(path1); } using (SKPath path2 = new SKPath()) { path2.AddCircle(xCenter + radius / 2, yCenter, radius); region2.SetPath(path2); } region1.Op(region2, regionOp); canvas.Save(); canvas.ClipRegion(region1); canvas.DrawPaint(fillPaint); canvas.Restore(); } } }
private void Paint(object sender, SKPaintSurfaceEventArgs args) { var info = args.Info; var surface = args.Surface; var canvas = args.Surface.Canvas; canvas.Clear(SKColors.Transparent); var clippingPath = new SKPath(); var hypotenuse = Math.Sqrt(Math.Pow(info.Width, 2) + Math.Pow(info.Height, 2)); var radius = (float)(_revealProgress * hypotenuse); clippingPath.AddCircle(info.Width * HorizontalRevealAnchor, info.Height * VerticalRevealAnchor, radius); canvas.ClipPath(clippingPath); canvas.DrawBitmap(_childViewImage, new SKPoint(0.0f, 0.0f)); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); using (SKPath circularPath = new SKPath()) { float radius = 0.35f * Math.Min(info.Width, info.Height); circularPath.AddCircle(info.Width / 2, info.Height / 2, radius); using (SKPaint textPaint = new SKPaint()) { textPaint.TextSize = 100; float textWidth = textPaint.MeasureText(text); textPaint.TextSize *= 2 * 3.14f * radius / textWidth; canvas.DrawTextOnPath(text, circularPath, 0, 0, textPaint); } } }
public static SKPath CreateSectorPath(float start, float end, float outerRadius, float innerRadius = 0.0f, float margin = 0.0f, float explodeDistance = 0.0f, SKPathDirection direction = SKPathDirection.Clockwise) { var path = new SKPath(); // if the sector has no size, then it has no path if (start == end) { return(path); } // the the sector is a full circle, then do that if (end - start == 1.0f) { path.AddCircle(0, 0, outerRadius, direction); path.AddCircle(0, 0, innerRadius, direction); path.FillType = SKPathFillType.EvenOdd; return(path); } // calculate the angles var startAngle = TotalAngle * start - UprightAngle; var endAngle = TotalAngle * end - UprightAngle; var large = endAngle - startAngle > PI ? SKPathArcSize.Large : SKPathArcSize.Small; var sectorCenterAngle = (endAngle - startAngle) / 2f + startAngle; // get the radius bits var cectorCenterRadius = (outerRadius - innerRadius) / 2f + innerRadius; // move explosion around 90 degrees, since matrix use down as 0 var explosionMatrix = SKMatrix.MakeRotation(sectorCenterAngle - (PI / 2f)); var offset = explosionMatrix.MapPoint(new SKPoint(0, explodeDistance)); // calculate the angle for the margins margin = direction == SKPathDirection.Clockwise ? margin : -margin; var offsetR = outerRadius == 0 ? 0 : ((margin / (TotalAngle * outerRadius)) * TotalAngle); var offsetr = innerRadius == 0 ? 0 : ((margin / (TotalAngle * innerRadius)) * TotalAngle); // get the points var a = GetCirclePoint(outerRadius, startAngle + offsetR) + offset; var b = GetCirclePoint(outerRadius, endAngle - offsetR) + offset; var c = GetCirclePoint(innerRadius, endAngle - offsetr) + offset; var d = GetCirclePoint(innerRadius, startAngle + offsetr) + offset; // add the points to the path path.MoveTo(a); path.ArcTo(outerRadius, outerRadius, 0, large, direction, b.X, b.Y); path.LineTo(c); if (innerRadius == 0.0f) { // take a short cut path.LineTo(d); } else { var reverseDirection = direction == SKPathDirection.Clockwise ? SKPathDirection.CounterClockwise : SKPathDirection.Clockwise; path.ArcTo(innerRadius, innerRadius, 0, large, reverseDirection, d.X, d.Y); } path.Close(); return(path); }
public override void DrawContent(SKCanvas canvas, int width, int height) { var total = this.Entries?.Count() ?? 0; if (total > 0) { var captionHeight = this.Entries.Max(x => { var result = 0.0f; var hasLabel = !string.IsNullOrEmpty(x.Label); var hasValueLabel = !string.IsNullOrEmpty(x.ValueLabel); if (hasLabel || hasValueLabel) { var hasOffset = hasLabel && hasValueLabel; var captionMargin = this.LabelTextSize * 0.60f; var space = hasOffset ? captionMargin : 0; if (hasLabel) { result += this.LabelTextSize; } if (hasValueLabel) { result += this.LabelTextSize; } } return(result); }); var center = new SKPoint(width / 2, height / 2); var radius = ((Math.Min(width, height) - (2 * Margin)) / 2) - captionHeight; var rangeAngle = (float)((Math.PI * 2) / total); var startAngle = (float)Math.PI; var nextEntry = this.Entries.First(); var nextAngle = startAngle; var nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius); this.DrawBorder(canvas, center, radius); using (var clip = new SKPath()) { clip.AddCircle(center.X, center.Y, radius); for (int i = 0; i < total; i++) { var angle = nextAngle; var entry = nextEntry; var point = nextPoint; var nextIndex = (i + 1) % total; nextAngle = startAngle + (rangeAngle * nextIndex); nextEntry = this.Entries.ElementAt(nextIndex); nextPoint = this.GetPoint(nextEntry.Value * this.AnimationProgress, center, nextAngle, radius); canvas.Save(); canvas.ClipPath(clip); // Border center bars using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = this.BorderLineColor, IsAntialias = true, }) { var borderPoint = this.GetPoint(this.MaxValue, center, angle, radius); canvas.DrawLine(point.X, point.Y, borderPoint.X, borderPoint.Y, paint); } // Values points and lines using (var paint = new SKPaint() { Style = SKPaintStyle.Stroke, StrokeWidth = this.BorderLineSize, Color = entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f * this.AnimationProgress)), PathEffect = SKPathEffect.CreateDash(new[] { this.BorderLineSize, this.BorderLineSize * 2 }, 0), IsAntialias = true, }) { var amount = Math.Abs(entry.Value - this.AbsoluteMinimum) / this.ValueRange; canvas.DrawCircle(center.X, center.Y, radius * amount, paint); } canvas.DrawGradientLine(center, entry.Color.WithAlpha(0), point, entry.Color.WithAlpha((byte)(entry.Color.Alpha * 0.75f)), this.LineSize); canvas.DrawGradientLine(point, entry.Color, nextPoint, nextEntry.Color, this.LineSize); canvas.DrawPoint(point, entry.Color, this.PointSize, this.PointMode); canvas.Restore(); // Labels var labelPoint = new SKPoint(0, radius + this.LabelTextSize + (this.PointSize / 2)); var rotation = SKMatrix.MakeRotation(angle); labelPoint = center + rotation.MapPoint(labelPoint); var alignment = SKTextAlign.Left; if ((Math.Abs(angle - (startAngle + Math.PI)) < Epsilon) || (Math.Abs(angle - Math.PI) < Epsilon)) { alignment = SKTextAlign.Center; } else if (angle > (float)(startAngle + Math.PI)) { alignment = SKTextAlign.Right; } canvas.DrawCaptionLabels(entry.Label, entry.TextColor, entry.ValueLabel, entry.Color.WithAlpha((byte)(255 * this.AnimationProgress)), this.LabelTextSize, labelPoint, alignment, base.Typeface); } } } }