/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static SKPath ToSKPath(this PathGeometry xpg, double dx, double dy, Func <double, float> scale) { var path = new SKPath(); path.FillType = xpg.FillRule == FillRule.EvenOdd ? SKPathFillType.EvenOdd : SKPathFillType.Winding; foreach (var xpf in xpg.Figures) { var previous = default(PointShape); // Begin new figure. path.MoveTo( scale(xpf.StartPoint.X + dx), scale(xpf.StartPoint.Y + dy)); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is ArcSegment) { var arcSegment = segment as ArcSegment; path.ArcTo( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height), (float)arcSegment.RotationAngle, arcSegment.IsLargeArc ? SKPathArcSize.Large : SKPathArcSize.Small, arcSegment.SweepDirection == SweepDirection.Clockwise ? SKPathDirection.Clockwise : SKPathDirection.CounterClockwise, scale(arcSegment.Point.X + dx), scale(arcSegment.Point.Y + dy)); previous = arcSegment.Point; } else if (segment is CubicBezierSegment) { var cubicBezierSegment = segment as CubicBezierSegment; path.CubicTo( scale(cubicBezierSegment.Point1.X + dx), scale(cubicBezierSegment.Point1.Y + dy), scale(cubicBezierSegment.Point2.X + dx), scale(cubicBezierSegment.Point2.Y + dy), scale(cubicBezierSegment.Point3.X + dx), scale(cubicBezierSegment.Point3.Y + dy)); previous = cubicBezierSegment.Point3; } else if (segment is LineSegment) { var lineSegment = segment as LineSegment; path.LineTo( scale(lineSegment.Point.X + dx), scale(lineSegment.Point.Y + dy)); previous = lineSegment.Point; } else if (segment is PolyCubicBezierSegment) { var polyCubicBezierSegment = segment as PolyCubicBezierSegment; if (polyCubicBezierSegment.Points.Length >= 3) { path.CubicTo( scale(polyCubicBezierSegment.Points[0].X + dx), scale(polyCubicBezierSegment.Points[0].Y + dy), scale(polyCubicBezierSegment.Points[1].X + dx), scale(polyCubicBezierSegment.Points[1].Y + dy), scale(polyCubicBezierSegment.Points[2].X + dx), scale(polyCubicBezierSegment.Points[2].Y + dy)); previous = polyCubicBezierSegment.Points[2]; } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { path.CubicTo( scale(polyCubicBezierSegment.Points[i].X + dx), scale(polyCubicBezierSegment.Points[i].Y + dy), scale(polyCubicBezierSegment.Points[i + 1].X + dx), scale(polyCubicBezierSegment.Points[i + 1].Y + dy), scale(polyCubicBezierSegment.Points[i + 2].X + dx), scale(polyCubicBezierSegment.Points[i + 2].Y + dy)); previous = polyCubicBezierSegment.Points[i + 2]; } } } else if (segment is PolyLineSegment) { var polyLineSegment = segment as PolyLineSegment; if (polyLineSegment.Points.Length >= 1) { path.LineTo( scale(polyLineSegment.Points[0].X + dx), scale(polyLineSegment.Points[0].Y + dy)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { path.LineTo( scale(polyLineSegment.Points[i].X + dx), scale(polyLineSegment.Points[i].Y + dy)); previous = polyLineSegment.Points[i]; } } } else if (segment is PolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Length >= 2) { path.QuadTo( scale(polyQuadraticSegment.Points[0].X + dx), scale(polyQuadraticSegment.Points[0].Y + dy), scale(polyQuadraticSegment.Points[1].X + dx), scale(polyQuadraticSegment.Points[1].Y + dy)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { path.QuadTo( scale(polyQuadraticSegment.Points[i].X + dx), scale(polyQuadraticSegment.Points[i].Y + dy), scale(polyQuadraticSegment.Points[i + 1].X + dx), scale(polyQuadraticSegment.Points[i + 1].Y + dy)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is QuadraticBezierSegment) { var quadraticBezierSegment = segment as QuadraticBezierSegment; path.QuadTo( scale(quadraticBezierSegment.Point1.X + dx), scale(quadraticBezierSegment.Point1.Y + dy), scale(quadraticBezierSegment.Point2.X + dx), scale(quadraticBezierSegment.Point2.Y + dy)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (xpf.IsClosed) { path.Close(); } } return(path); }
/// <summary> /// Update path /// </summary> private void UpdatePath() { var width = Width - _shadowWidth * 2; var height = Height - _shadowWidth * 2; var halfWidth = width * ArrowPosition; var halfHeight = height * ArrowPosition; var bottom = (float)height - _shadowWidth; var left = _shadowWidth; var top = _shadowWidth; var right = (float)width - _shadowWidth; var start = new Point(); var center = new Point(); var end = new Point(); // Check, if we are to near of the corners if (halfWidth - ArrowWidth * 0.5 < RectRadius) { halfWidth = ArrowWidth * 0.5 + RectRadius; } if (halfWidth + ArrowWidth * 0.5 > width - RectRadius) { halfWidth = width - ArrowWidth * 0.5 - RectRadius; } if (halfHeight - ArrowWidth * 0.5 < RectRadius) { halfHeight = ArrowWidth * 0.5 + RectRadius; } if (halfHeight + ArrowWidth * 0.5 > height - RectRadius) { halfHeight = height - ArrowWidth * 0.5 - RectRadius; } switch (ArrowAlignment) { case ArrowAlignment.Bottom: start = new Point(halfWidth + ArrowWidth * 0.5, bottom - ArrowHeight); center = new Point(halfWidth, bottom); end = new Point(halfWidth - ArrowWidth * 0.5, bottom - ArrowHeight); bottom -= ArrowHeight; break; case ArrowAlignment.Top: start = new Point(halfWidth - ArrowWidth * 0.5, top + ArrowHeight); center = new Point(halfWidth, top); end = new Point(halfWidth + ArrowWidth * 0.5, top + ArrowHeight); top += ArrowHeight; break; case ArrowAlignment.Left: start = new Point(left + ArrowHeight, halfHeight + ArrowWidth * 0.5); center = new Point(left, halfHeight); end = new Point(left + ArrowHeight, halfHeight - ArrowWidth * 0.5); left += ArrowHeight; break; case ArrowAlignment.Right: start = new Point(right - ArrowHeight, halfHeight - ArrowWidth * 0.5); center = new Point(right, halfHeight); end = new Point(right - ArrowHeight, halfHeight + ArrowWidth * 0.5); right -= ArrowHeight; break; } // Create path _path = new SKPath(); // Move to start point at left/top _path.MoveTo(left + RectRadius, top); // Top horizontal line if (ArrowAlignment == ArrowAlignment.Top) { DrawArrow(start, center, end); } // Top right arc _path.ArcTo(new SKRect(right - RectRadius, top, right, top + RectRadius), 270, 90, false); // Right vertical line if (ArrowAlignment == ArrowAlignment.Right) { DrawArrow(start, center, end); } // Bottom right arc _path.ArcTo(new SKRect(right - RectRadius, bottom - RectRadius, right, bottom), 0, 90, false); // Bottom horizontal line if (ArrowAlignment == ArrowAlignment.Bottom) { DrawArrow(start, center, end); } // Bottom left arc _path.ArcTo(new SKRect(left, bottom - RectRadius, left + RectRadius, bottom), 90, 90, false); // Left vertical line if (ArrowAlignment == ArrowAlignment.Left) { DrawArrow(start, center, end); } // Top left arc _path.ArcTo(new SKRect(left, top, left + RectRadius, top + RectRadius), 180, 90, false); _path.Close(); // Set center as new anchor point _offset = center; // We changed so much, so update screen position UpdateScreenPosition(); }
/// <summary> /// This is triggered whenever the canvas needs to redraw. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void OnCanvasViewPaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs args) { if (viewModel.ChartData == null) { return; } if (viewModel.ChartData.Count == 0) { return; } SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; var y = info.Height / 2; canvas.Clear(); SKPoint center = new SKPoint(info.Width / 2, info.Height / 2); float radius = Math.Min(info.Width / 2, info.Height / 2) - 2 * Constants.ExplodeOffset; SKRect rect = new SKRect(center.X - radius, center.Y - radius, center.X + radius, center.Y + radius); float startAngle = -90; //This is alighed to the marker to make tracking the winning prize easier. //for text float xCenter = info.Width / 2; float yCenter = info.Height / 2; foreach (ChartData item in viewModel.ChartData) { float sweepAngle = 360f / viewModel.ChartData.Count; using (SKPath path = new SKPath()) using (SKPaint fillPaint = new SKPaint()) using (SKPaint outlinePaint = new SKPaint()) using (SKPaint textPaint = new SKPaint()) { path.MoveTo(center); path.ArcTo(rect, startAngle, sweepAngle, false); path.Close(); fillPaint.Style = SKPaintStyle.Fill; fillPaint.Color = item.Color; outlinePaint.Style = SKPaintStyle.Stroke; outlinePaint.StrokeWidth = 5; outlinePaint.Color = SKColors.White; #region Text Writer //write text to the screen textPaint.TextSize = 40; textPaint.StrokeWidth = 1; textPaint.Color = SKColors.White; //Adjust text size. SKRect textBounds = new SKRect(); textPaint.MeasureText(item.Text, ref textBounds); float yText = yCenter - textBounds.Height / 2 - textBounds.Top; // Adjust TextSize property so text is 95% of the ARC // float textWidth = textPaint.MeasureText(item.Text); // textPaint.TextSize = 0.95f * info.Width * textPaint.TextSize / textWidth; #endregion canvas.Save(); DrawRotatedWithMatrices(canvas, path, fillPaint, outlinePaint, item, _degrees, (int)center.X, y); //Writing Actual texts var test_angle = _degrees + (360 / viewModel.ChartData.Count / 2) - (360 / viewModel.ChartData.Count * 2); float sweepAngleText = 360f / viewModel.ChartData.Count; float startAngleText = sweepAngleText - sweepAngleText / 2; foreach (ChartData itemer in viewModel.ChartData) { canvas.Save(); canvas.RotateDegrees(startAngleText + _degrees - 90, xCenter, yCenter); if (itemer.Text.Trim().Length > 6) { textPaint.TextSize = 30; } else { textPaint.TextSize = 40; } canvas.DrawText(itemer.Text, xCenter, yText, textPaint); canvas.Restore(); test_angle += 360 / viewModel.ChartData.Count; if (test_angle > 360) { test_angle = test_angle - 360; } if (startAngleText > 360) { startAngleText = startAngleText - 360; } startAngleText += sweepAngleText; } canvas.Restore(); } startAngle += sweepAngle; } #region Marker //draw the Mark using (SKPaint fillMarkCirclePaint = new SKPaint()) using (SKPaint fillMarkCirclePaintOuter = new SKPaint()) using (SKPaint fillMarkTrianglePaint = new SKPaint()) { fillMarkCirclePaint.Style = SKPaintStyle.StrokeAndFill; fillMarkCirclePaintOuter.Style = SKPaintStyle.StrokeAndFill; fillMarkCirclePaintOuter.Color = Color.FromHex("#FFF180").ToSKColor(); // Define an array of rainbow colors List <SKColor> colors = new List <SKColor>(); foreach (var col in viewModel.Colors) { colors.Add(Color.FromHex(col).ToSKColor()); } //draw outer circle canvas.DrawCircle(args.Info.Width / 2, args.Info.Height / 2, 60, fillMarkCirclePaintOuter); //outer //draw triangle fillMarkTrianglePaint.Style = SKPaintStyle.StrokeAndFill; fillMarkTrianglePaint.Color = Color.FromHex("#FFF180").ToSKColor(); SKPath trianglePath = new SKPath(); trianglePath.MoveTo((args.Info.Width / 2) - 55, args.Info.Height / 2); trianglePath.LineTo((args.Info.Width / 2) - 55, args.Info.Height / 2); trianglePath.LineTo((args.Info.Width / 2) + 55, args.Info.Height / 2); trianglePath.LineTo(args.Info.Width / 2, (float)(args.Info.Height / 2.5)); trianglePath.Close(); canvas.DrawPath(trianglePath, fillMarkTrianglePaint); //draw inner circle SKPoint circle_center = new SKPoint(info.Rect.MidX, info.Rect.MidY); fillMarkCirclePaint.Shader = SKShader.CreateSweepGradient(circle_center, colors.ToArray()); canvas.DrawCircle(args.Info.Width / 2, args.Info.Height / 2, 50, fillMarkCirclePaint); //inner } #endregion //Get the current prize. float prize_degree = _degrees + (360 / viewModel.ChartData.Count / 2); if (_degrees == 0 || Math.Round(_degrees, MidpointRounding.AwayFromZero) == 360) { prize_degree = _degrees; } var segment = ((prize_degree / 360f) * viewModel.ChartData.Count); var int_segment2 = Math.Round(segment, MidpointRounding.AwayFromZero); var realIndex = viewModel.ChartData.Count == viewModel.ChartData.Count - (int)int_segment2 ? 0 : viewModel.ChartData.Count - (int)int_segment2; viewModel.Prize = viewModel.ChartData[realIndex].Sector; //add back resultBox.Text = viewModel.Prize?.Game; // currentBox.Text = ((int)realIndex).ToString(); if (viewModel.EnableHaptic) { TryHaptic(); } IncrementDegrees(); }
public void ArcTo(float radiusX, float radiusY, int xAxisRotate, PathArcSize arcSize, PathDirection direction, float x, int y) => _path.ArcTo(radiusX, radiusY, xAxisRotate, arcSize.ToSkia(), direction.ToSkia(), x, y);
private static void DrawRenderOptions(RenderOptions renderOptions, DistanceInfo distanceInfo, Cell cell, int imageCenter, SKSurface surface, ShortestPathInfo shortestPathInfo, CircularMaze maze) { var position = maze.GetPositionOfCell(cell); var centerOfCell = GetCenterOfCell(position, imageCenter); var whitePaint = new SKPaint { Color = SKColors.White, StrokeWidth = 1, TextAlign = SKTextAlign.Center }; var startPaint = new SKPaint { Color = SKColors.Green, StrokeWidth = 1, TextAlign = SKTextAlign.Center }; var finishPaint = new SKPaint { Color = SKColors.Red, StrokeWidth = 1, TextAlign = SKTextAlign.Center }; var pathPaint = new SKPaint { Color = SKColors.Yellow, StrokeWidth = 1, TextAlign = SKTextAlign.Center }; if (renderOptions.ShowGradientOfDistanceFromStart) { var path = new SKPath(); if (position.RingNumber > 0) { var innerRadius = GetRadiusAtRing(position.RingNumber - 1); var outerRadius = GetRadiusAtRing(position.RingNumber); var innerBounds = new SKRect(imageCenter - innerRadius, imageCenter - innerRadius, imageCenter + innerRadius, imageCenter + innerRadius); var outerBounds = new SKRect(imageCenter - outerRadius, imageCenter - outerRadius, imageCenter + outerRadius, imageCenter + outerRadius); var degreeDifference = position.EndingDegree - position.StartingDegree; var firstLineCoords = GetCoords(outerRadius, position.EndingDegree); var secondLineCoords = GetCoords(innerRadius, position.StartingDegree); path.AddArc(innerBounds, NormalizeAngle(position.StartingDegree), NormalizeAngle(degreeDifference)); path.LineTo(imageCenter + firstLineCoords.x, imageCenter + firstLineCoords.y); path.ArcTo(outerBounds, position.EndingDegree, -degreeDifference, false); path.LineTo(imageCenter + secondLineCoords.x, imageCenter + secondLineCoords.y); } else { // Center cell should be fully shaded path.AddCircle(imageCenter, imageCenter, CenterCellRadius); } var finishingCellDistance = distanceInfo.DistanceFromStartMap[distanceInfo.FarthestCell]; var currentCellDistance = distanceInfo.DistanceFromStartMap[cell]; var intensity = (byte)(255 * (currentCellDistance / (decimal)finishingCellDistance)); var color = new SKColor(0, 0, intensity); var paint = new SKPaint { Color = color }; surface.Canvas.DrawPath(path, paint); } if (renderOptions.HighlightShortestPath && shortestPathInfo.IsCellInPath(cell)) { var paint = cell == maze.StartingCell ? startPaint : cell == maze.FinishingCell ? finishPaint : pathPaint; var distance = distanceInfo.DistanceFromStartMap[cell]; surface.Canvas.DrawText(distance.ToString(), centerOfCell.x, centerOfCell.y, paint); } else if (renderOptions.ShowAllDistances && distanceInfo.DistanceFromStartMap.ContainsKey(cell)) { var distance = distanceInfo.DistanceFromStartMap[cell]; surface.Canvas.DrawText(distance.ToString(), centerOfCell.x, centerOfCell.y, whitePaint); } else if (cell == maze.StartingCell) { surface.Canvas.DrawText("S", centerOfCell.x, centerOfCell.y, startPaint); } else if (cell == maze.FinishingCell) { surface.Canvas.DrawText("E", centerOfCell.x, centerOfCell.y, finishPaint); } }
public static void DrawCardSuit(this SKCanvas thisCanvas, EnumSuitList suitCategory, SKRect thisRect, SKPaint solidPaint, SKPaint?borderPaint) { TempPosition temps = GetTempRect(thisRect); if (solidPaint == null) { throw new BasicBlankException("All Cards Must Have Solid Brushes"); } if (borderPaint != null && suitCategory == EnumSuitList.Clubs) { throw new BasicBlankException("Clubs can't have stroke paint currently"); } if (borderPaint != null && suitCategory == EnumSuitList.Spades) { throw new BasicBlankException("Spades can't have stroke paint currently"); } switch (suitCategory) { case EnumSuitList.Clubs: { SKPath thisPath = new SKPath(); //used proportions here. seemed to work great. var firstRect = GetActualRectangle(125, 0, 150, 150, temps); thisPath.AddOval(firstRect, SKPathDirection.Clockwise); var secondRect = GetActualRectangle(0, 150, 150, 150, temps); thisPath.AddOval(secondRect, SKPathDirection.Clockwise); var thirdRect = GetActualRectangle(250, 150, 150, 150, temps); thisPath.AddOval(thirdRect, SKPathDirection.Clockwise); SKPoint point1; SKPoint point2; point1 = GetActualPoint(185, 150, temps); point2 = GetActualPoint(150, 200, temps); thisPath.MoveTo(point1); point1 = GetActualPoint(175, 180, temps); thisPath.QuadTo(point1, point2); point2 = GetActualPoint(150, 250, temps); thisPath.LineTo(point2); point1 = GetActualPoint(175, 270, temps); point2 = GetActualPoint(175, 280, temps); thisPath.QuadTo(point1, point2); point2 = GetActualPoint(150, 400, temps); thisPath.LineTo(point2); var tempLine = GetActualPoint(250, 400, temps); thisPath.LineTo(tempLine); point1 = GetActualPoint(225, 350, temps); point2 = GetActualPoint(225, 280, temps); thisPath.QuadTo(point1, point2); point1 = GetActualPoint(225, 270, temps); point2 = GetActualPoint(250, 250, temps); thisPath.QuadTo(point1, point2); point2 = GetActualPoint(250, 200, temps); thisPath.LineTo(point2); point1 = GetActualPoint(230, 180, temps); point2 = GetActualPoint(220, 150, temps); thisPath.QuadTo(point1, point2); thisPath.Close(); thisCanvas.DrawPath(thisPath, solidPaint); break; } case EnumSuitList.Diamonds: { SKPoint[] pts = new SKPoint[4]; pts[0] = new SKPoint(thisRect.Location.X + (thisRect.Width / 2), thisRect.Location.Y); pts[1] = new SKPoint(thisRect.Location.X + (thisRect.Width * 3 / 4), thisRect.Location.Y + (thisRect.Height / 2)); pts[2] = new SKPoint(thisRect.Location.X + (thisRect.Width / 2), thisRect.Location.Y + thisRect.Height); pts[3] = new SKPoint(thisRect.Location.X + (thisRect.Width / 4), thisRect.Location.Y + (thisRect.Height / 2)); SKPath ThisPath = new SKPath(); ThisPath.AddLines(pts, true); thisCanvas.DrawPath(ThisPath, solidPaint); if (borderPaint == null == false) { thisCanvas.DrawPath(ThisPath, borderPaint); } break; } case EnumSuitList.Hearts: { int avg; avg = System.Convert.ToInt32((thisRect.Width + thisRect.Height) / 2); int radius; radius = System.Convert.ToInt32(avg / (double)2); var topleftcorner = new SKPoint(thisRect.Location.X, thisRect.Location.Y); var topleftsquare = SKRect.Create(topleftcorner.X, topleftcorner.Y, radius, radius); var toprightsquare = SKRect.Create(topleftcorner.X + radius, topleftcorner.Y, radius, radius); var thisPath = new SKPath(); thisPath.ArcTo(topleftsquare, 135, 225, false); thisPath.ArcTo(toprightsquare, 180, 225, false); thisPath.LineTo(radius + thisRect.Location.X, avg + thisRect.Location.Y); thisPath.Close(); thisCanvas.DrawPath(thisPath, solidPaint); if (borderPaint == null == false) { thisCanvas.DrawPath(thisPath, borderPaint); } break; } case EnumSuitList.Spades: { var firstRect = GetActualRectangle(0, 100, 200, 200, temps); thisCanvas.DrawOval(firstRect, solidPaint); var secondRect = GetActualRectangle(200, 100, 200, 200, temps); thisCanvas.DrawOval(secondRect, solidPaint); var nextRect = GetActualRectangle(175, 175, 50, 200, temps); thisCanvas.DrawRect(nextRect, solidPaint); var tempRect = GetActualRectangle(0, 0, 400, 175, temps); thisCanvas.DrawTriangle(tempRect, solidPaint, null !); break; } default: throw new BasicBlankException("Must choose one of the 4 suits to draw"); } }
void OnPaintCanvas(object sender, SKPaintSurfaceEventArgs e) { var canvas = e.Surface.Canvas; canvas.Clear(); var left = formsGeometry.Left - canvasView.Geometry.Left; var top = formsGeometry.Top - canvasView.Geometry.Top; var path = new SKPath(); var rect = new SKRect(left, top, left + formsGeometry.Width, top + formsGeometry.Height); var borderTop = new SKPath(); var borderRight = new SKPath(); var borderBottom = new SKPath(); var borderLeft = new SKPath(); var topLeft = new SKRect(rect.Left, rect.Top, rect.Left + (float)Self.Border.TopLeft.Width * 2, rect.Top + (float)Self.Border.TopLeft.Height * 2); var topRight = new SKRect(rect.Right - (float)Self.Border.TopRight.Width * 2, rect.Top, rect.Right, rect.Top + (float)Self.Border.TopRight.Height * 2); var bottomLeft = new SKRect(rect.Left, rect.Bottom - (float)Self.Border.BottomLeft.Height * 2, rect.Left + (float)Self.Border.BottomLeft.Width * 2, rect.Bottom); var bottomRight = new SKRect(rect.Right - (float)Self.Border.BottomRight.Width * 2, rect.Bottom - (float)Self.Border.BottomRight.Height * 2, rect.Right, rect.Bottom); path.ArcTo(topLeft, 180, 90, false); path.ArcTo(topRight, 270, 90, false); path.ArcTo(bottomRight, 0, 90, false); path.ArcTo(bottomLeft, 90, 90, false); path.Close(); borderTop.ArcTo(topLeft, 225, 45, false); borderTop.ArcTo(topRight, 270, 45, false); borderLeft.ArcTo(bottomLeft, 135, 45, false); borderLeft.ArcTo(topLeft, 180, 45, false); borderRight.ArcTo(topRight, 315, 45, false); borderRight.ArcTo(bottomRight, 0, 45, false); borderBottom.ArcTo(bottomRight, 45, 45, false); borderBottom.ArcTo(bottomLeft, 90, 45, false); using (var paint = new SKPaint()) { paint.IsAntialias = true; paint.Style = SKPaintStyle.StrokeAndFill; foreach (var shadow in Self.Shadows) { if (shadow.Inset) { continue; } canvas.Save(); canvas.ClipPath(path, SKClipOperation.Difference, true); paint.StrokeWidth = (float)shadow.SpreadRadius; paint.ImageFilter = SKImageFilter.CreateDropShadow((float)shadow.OffsetX, (float)shadow.OffsetY, (float)shadow.BlurRadius, (float)shadow.BlurRadius, shadow.Color.ToSK(), SKDropShadowImageFilterShadowMode.DrawShadowOnly); canvas.DrawPath(path, paint); canvas.Restore(); } paint.ImageFilter = null; foreach (var bg in Self.Backgrounds) { switch (bg.Source) { case SolidColor solid: paint.Style = SKPaintStyle.Fill; paint.Color = solid.Color.ToSK(); canvas.DrawPath(path, paint); break; case LinearGradient linear: path.GetBounds(out var bgRect); paint.Style = SKPaintStyle.Fill; paint.StrokeWidth = 0; var rad = Math.PI / 180 * linear.Angle; var cx = bgRect.Left + bgRect.Width / 2; var cy = bgRect.Top + bgRect.Height / 2; var tan = (float)Math.Tan(rad); var cos = (float)Math.Cos(rad); float x1 = 0, y1 = 0, x2 = 0, y2 = 0, px = 0, py = 0; if (tan == 0) { x1 = bgRect.Left; y1 = cy; x2 = bgRect.Right; y2 = cy; } else if (cos == 0) { x1 = cx; y1 = bgRect.Top; x2 = cx; y2 = bgRect.Bottom; } else { if (tan > 0 && cos > 0) { px = bgRect.Right; py = bgRect.Bottom; } else if (tan > 0 && cos < 0) { px = bgRect.Left; py = bgRect.Top; } else if (tan < 0 && cos > 0) { px = bgRect.Right; py = bgRect.Top; } else if (tan < 0 && cos < 0) { px = bgRect.Left; py = bgRect.Bottom; } var p = (-tan * px + py + tan * cx - cy) / (tan * tan + 1); x1 = p * tan + px; y1 = py - p; x2 = 2 * cx - x1; y2 = 2 * cy - y1; } paint.StrokeWidth = 0; paint.Style = SKPaintStyle.Fill; paint.Shader = SKShader.CreateLinearGradient( new SKPoint(x1, y1), new SKPoint(x2, y2), linear.Colors.Select(color => color.ToSK()).ToArray(), linear.ColorPosition.ToArray(), SKShaderTileMode.Repeat); canvas.DrawPath(path, paint); break; } } paint.Shader = null; paint.Style = SKPaintStyle.Stroke; foreach (var shadow in Self.Shadows) { if (!shadow.Inset) { continue; } canvas.Save(); paint.StrokeWidth = (float)shadow.SpreadRadius; paint.ImageFilter = SKImageFilter.CreateDropShadow((float)shadow.OffsetX, (float)shadow.OffsetY, (float)shadow.BlurRadius, (float)shadow.BlurRadius, shadow.Color.ToSK(), SKDropShadowImageFilterShadowMode.DrawShadowOnly); canvas.ClipPath(path, antialias: true); canvas.DrawPath(path, paint); canvas.Restore(); } paint.ImageFilter = null; paint.StrokeCap = SKStrokeCap.Square; paint.Style = SKPaintStyle.Stroke; if (Self.Border.TopWidth > 0) { paint.Color = Self.Border.TopColor.ToSK(); paint.StrokeWidth = (float)Self.Border.TopWidth; canvas.DrawPath(borderTop, paint); } if (Self.Border.RightWidth > 0) { paint.Color = Self.Border.RightColor.ToSK(); paint.StrokeWidth = (float)Self.Border.RightWidth; canvas.DrawPath(borderRight, paint); } if (Self.Border.BottomWidth > 0) { paint.Color = Self.Border.BottomColor.ToSK(); paint.StrokeWidth = (float)Self.Border.BottomWidth; canvas.DrawPath(borderBottom, paint); } if (Self.Border.LeftWidth > 0) { paint.Color = Self.Border.LeftColor.ToSK(); paint.StrokeWidth = (float)Self.Border.LeftWidth; canvas.DrawPath(borderLeft, paint); } } }
public void DrawPath(Point start, IList <IPathCommand> commands, double thickness, bool fill = false) { var s = start.ToSkPoint(); var path = new SKPath(); path.MoveTo(s); foreach (var c in commands) { switch (c) { case LineTo line: { path.LineTo(s + line.End.ToSkPoint()); break; } case CurveTo curve: { path.CubicTo(s + curve.ControlStart.ToSkPoint(), s + curve.ControlEnd.ToSkPoint(), s + curve.End.ToSkPoint()); break; } case MoveTo move: { path.MoveTo(s + move.End.ToSkPoint()); break; } case QuadraticBeizerCurveTo curve: { path.QuadTo(s + curve.Control.ToSkPoint(), s + curve.End.ToSkPoint()); break; } case EllipticalArcTo arc: { path.ArcTo((float)arc.Size.Width, (float)arc.Size.Height, (float)arc.RotationAngle, arc.IsLargeArc ? SKPathArcSize.Large : SKPathArcSize.Small, arc.SweepDirection == SweepDirection.Clockwise ? SKPathDirection.Clockwise : SKPathDirection.CounterClockwise, s.X + (float)arc.End.X, s.Y + (float)arc.End.Y); break; } case ClosePath close: { path.Close(); break; } default: { path.MoveTo(s + c.End.ToSkPoint()); break; } } } var paint = new SKPaint { Color = Color, IsAntialias = true, Style = fill ? SKPaintStyle.StrokeAndFill : SKPaintStyle.Stroke, StrokeWidth = (float)thickness, StrokeCap = SKStrokeCap.Square, }; surface.Canvas.DrawPath(path, paint); }
protected virtual void OnCanvasViewOnPaintSurface(object sender, SKPaintSurfaceEventArgs e) { var info = e.Info; var surface = e.Surface; var canvas = surface.Canvas; canvas.Clear(); if (Gradients != null && Gradients.Any()) { _fillPaint.Shader = GetGradient(info, Gradients, GradientOrientation); } else { _fillPaint.Color = Color.ToSKColor(); } var topLeftRadius = ConvertToDeviceScaleFactor(CornerRadius.Left); var topRightRadius = ConvertToDeviceScaleFactor(CornerRadius.Top); var bottomRightRadius = ConvertToDeviceScaleFactor(CornerRadius.Right); var bottomLeftRadius = ConvertToDeviceScaleFactor(CornerRadius.Bottom); var topLeft = new SKPoint(0, 0); var topRight = new SKPoint(info.Width, 0); var bottomRight = new SKPoint(info.Width, info.Height); var bottomLeft = new SKPoint(0, info.Height); using (var path = new SKPath()) { path.MoveTo(bottomLeft); path.ArcTo(topLeft, topRight, topLeftRadius); path.ArcTo(topRight, bottomRight, topRightRadius); path.ArcTo(bottomRight, bottomLeft, bottomRightRadius); path.ArcTo(bottomLeft, topLeft, bottomLeftRadius); path.Close(); canvas.ClipPath(path); if (IsOnlyBorder) { var border = ConvertToDeviceScaleFactor(BorderWidth) * 2; var scalaX = (info.Width - border) / info.Width; var scalaY = (info.Height - border) / info.Height; canvas.Translate(ConvertToDeviceScaleFactor(BorderWidth), ConvertToDeviceScaleFactor(BorderWidth)); canvas.Scale(scalaX, scalaY); using (var center = new SKPath()) { center.MoveTo(bottomLeft); center.ArcTo(topLeft, topRight, topLeftRadius); center.ArcTo(topRight, bottomRight, topRightRadius); center.ArcTo(bottomRight, bottomLeft, bottomRightRadius); center.ArcTo(bottomLeft, topLeft, bottomLeftRadius); center.Close(); canvas.ClipPath(center, SKClipOperation.Difference); } } } canvas.DrawPaint(_fillPaint); }
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args) { SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); float cornerRadius = 100; int numVertices = 7; float radius = 0.45f * Math.Min(info.Width, info.Height); SKPoint[] vertices = new SKPoint[numVertices]; SKPoint[] midPoints = new SKPoint[numVertices]; double vertexAngle = -0.5f * Math.PI; // straight up // Coordinates of the vertices of the polygon for (int vertex = 0; vertex < numVertices; vertex++) { vertices[vertex] = new SKPoint(radius * (float)Math.Cos(vertexAngle), radius * (float)Math.Sin(vertexAngle)); vertexAngle += 2 * Math.PI / numVertices; } // Coordinates of the midpoints of the sides connecting the vertices for (int vertex = 0; vertex < numVertices; vertex++) { int prevVertex = (vertex + numVertices - 1) % numVertices; midPoints[vertex] = new SKPoint((vertices[prevVertex].X + vertices[vertex].X) / 2, (vertices[prevVertex].Y + vertices[vertex].Y) / 2); } // Create the path using (SKPath path = new SKPath()) { // Begin at the first midpoint path.MoveTo(midPoints[0]); for (int vertex = 0; vertex < numVertices; vertex++) { SKPoint nextMidPoint = midPoints[(vertex + 1) % numVertices]; // Draws a line from the current point, and then the arc path.ArcTo(vertices[vertex], nextMidPoint, cornerRadius); // Connect the arc with the next midpoint path.LineTo(nextMidPoint); } path.Close(); // Render the path in the center of the screen using (SKPaint paint = new SKPaint()) { paint.Style = SKPaintStyle.Stroke; paint.Color = SKColors.Blue; paint.StrokeWidth = 10; canvas.Translate(info.Width / 2, info.Height / 2); canvas.DrawPath(path, paint); } } }
public void AddPathSegment(SKPath canvasPathBuilder, ref bool closed) { canvasPathBuilder.ArcTo(_endPoint.ToSkPoint(), (float)MathExt.ToRadians(_sweepAngle), SKPathArcSize.Small, SKPathDirection.Clockwise, new SKPoint(_a, _b)); closed = false; }
//should be called for every section/canvas void Draw_RandomShape(SKCanvas skCanvas, object sender) { for (int i = 0; i < 5; i++) { sectionalLineList.Add(skLineList[i]); } var donePoints = new List <SKPoint[]>(); skLineList = skLineList.Distinct().ToList(); bool firstDone = false; int senderIndex = 1; foreach (var elem in sectionalLineList) { if (!donePoints.Contains(elem)) { if ((elem[1].Y - elem[0].Y) > 0 && (elem[1].X - elem[0].X) > 0 && !firstDone) { //0 -> 1 var firstLineElem = new SKPoint[] { new SKPoint(elem[0].X - 5, elem[0].Y), new SKPoint(elem[1].X, elem[1].Y + 5) }; var secondLineElem = new SKPoint[] { new SKPoint(elem[0].X + 5, elem[0].Y), new SKPoint(elem[1].X, elem[1].Y - 5) }; streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, firstLineElem[1]); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, secondLineElem[1]); scorePath.MoveTo(elem[0]); scorePath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, elem[1]); firstDone = true; traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(elem[0]); collectedPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, elem[1]); Console.WriteLine(traversedScore + "0-1"); } } else if ((elem[1].Y - elem[0].Y) > 0 && (elem[1].X - elem[0].X) > 0 && firstDone) { //2 -> 3 var firstLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y + 5), new SKPoint(elem[1].X - 5, elem[1].Y) }; var secondLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y - 5), new SKPoint(elem[1].X + 5, elem[1].Y) }; streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, firstLineElem[1]); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, secondLineElem[1]); scorePath.MoveTo(elem[0]); scorePath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); firstDone = false; traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(elem[0]); collectedPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); Console.WriteLine(traversedScore + "2-3"); } } if ((elem[1].Y - elem[0].Y) < 0 && (elem[1].X - elem[0].X) > 0) { //1 -> 2 var firstLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y - 5), new SKPoint(elem[1].X, elem[1].Y - 5) }; var secondLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y + 5), new SKPoint(elem[1].X, elem[1].Y + 5) }; var midpoint1 = new SKPoint((firstLineElem[0].X + firstLineElem[1].X) / 2, ((firstLineElem[0].Y + firstLineElem[1].Y) / 2)); var midpoint2 = new SKPoint((secondLineElem[0].X + secondLineElem[1].X) / 2, ((secondLineElem[0].Y + secondLineElem[1].Y) / 2)); var midlinemidpoint = new SKPoint((elem[0].X + elem[1].X) / 2, (elem[0].Y + elem[1].Y) / 2); streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, midpoint1); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, midpoint2); scorePath.MoveTo(elem[0]); scorePath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, midlinemidpoint); streetPath.MoveTo(midpoint1); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, firstLineElem[1]); streetPath.MoveTo(midpoint2); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, secondLineElem[1]); scorePath.MoveTo(midlinemidpoint); scorePath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(elem[0]); collectedPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, midlinemidpoint); collectedPath.MoveTo(midlinemidpoint); collectedPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); Console.WriteLine(traversedScore + "1-2 1"); } } if ((elem[1].Y - elem[0].Y) > 0 && (elem[1].X - elem[0].X) < 0) { //3 -> 4 var firstLineElem = new SKPoint[] { new SKPoint(elem[0].X - 5, elem[0].Y), new SKPoint(elem[1].X, elem[1].Y - 5) }; var secondLineElem = new SKPoint[] { new SKPoint(elem[0].X + 5, elem[0].Y), new SKPoint(elem[1].X, elem[1].Y + 5) }; streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, firstLineElem[1]); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, secondLineElem[1]); scorePath.MoveTo(elem[0]); scorePath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); //secondDone = true; traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(elem[0]); collectedPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.Clockwise, elem[1]); Console.WriteLine(traversedScore + "3-4"); } } if ((elem[1].Y - elem[0].Y) < 0 && (elem[1].X - elem[0].X) < 0) { //4 -> 5 var firstLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y - 5), new SKPoint(elem[1].X, elem[1].Y - 5) }; var secondLineElem = new SKPoint[] { new SKPoint(elem[0].X, elem[0].Y + 5), new SKPoint(elem[1].X, elem[1].Y + 5) }; var midpoint1 = new SKPoint((firstLineElem[0].X + firstLineElem[1].X) / 2, ((firstLineElem[0].Y + firstLineElem[1].Y) / 2)); var midpoint2 = new SKPoint((secondLineElem[0].X + secondLineElem[1].X) / 2, ((secondLineElem[0].Y + secondLineElem[1].Y) / 2)); var midlinemidpoint = new SKPoint((elem[0].X + elem[1].X) / 2, (elem[0].Y + elem[1].Y) / 2); streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, midpoint1); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, midpoint2); scorePath.MoveTo(elem[0]); scorePath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, midlinemidpoint); streetPath.MoveTo(midpoint1); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, firstLineElem[1]); streetPath.MoveTo(midpoint2); streetPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, secondLineElem[1]); scorePath.MoveTo(midlinemidpoint); scorePath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, elem[1]); traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(elem[0]); collectedPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.Clockwise, midlinemidpoint); collectedPath.MoveTo(midlinemidpoint); collectedPath.ArcTo(new SKPoint(70, 70), 55, SKPathArcSize.Small, SKPathDirection.CounterClockwise, elem[1]); Console.WriteLine(traversedScore + "4-5 1"); } try { fivetosix(senderIndex); senderIndex++; } catch { } } donePoints.Add(elem); } donePoints.Add(elem); } void fivetosix(int index) { var thisLine = new SKPoint[] { new SKPoint(lastPoints[index - 1].X, lastPoints[index - 1].Y), new SKPoint(firstPoints[index].X, firstPoints[index].Y) }; if (!donePoints.Contains(thisLine)) { var firstLineElem = new SKPoint[] { new SKPoint(lastPoints[index - 1].X, lastPoints[index - 1].Y - 5), new SKPoint(firstPoints[index].X - 5, firstPoints[index].Y) }; var secondLineElem = new SKPoint[] { new SKPoint(lastPoints[index - 1].X, lastPoints[index - 1].Y + 5), new SKPoint(firstPoints[index].X + 5, firstPoints[index].Y) }; //5->6 streetPath.MoveTo(firstLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, firstLineElem[1]); streetPath.MoveTo(secondLineElem[0]); streetPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, secondLineElem[1]); scorePath.MoveTo(thisLine[0]); scorePath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, thisLine[1]); traversedScore += segmentScore; if (traversedScore <= currentScore) { collectedPath.MoveTo(thisLine[0]); collectedPath.ArcTo(new SKPoint(100, 100), 45, SKPathArcSize.Small, SKPathDirection.CounterClockwise, thisLine[1]); Console.WriteLine(traversedScore + "5-6"); } donePoints.Add(thisLine); } } if (sender == SkCanvasView) { skCanvas.DrawPath(collectedPath, collectedStroke); skCanvas.DrawPath(clipperPath, clipStroke); } else { skCanvas.DrawPath(scorePath, scoreStroke); skCanvas.DrawPath(streetPath, streetStroke); } }
private void canvas_PaintSurface(object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { SKImageInfo info = e.Info; SKSurface surface = e.Surface; SKCanvas canvas = surface.Canvas; SKPaint strokePaint = GetPaintColor(SKPaintStyle.Stroke, null, 10, SKStrokeCap.Square); SKPaint dotPaint = GetPaintColor(SKPaintStyle.Fill, "#DE0469"); SKPaint hrPaint = GetPaintColor(SKPaintStyle.Stroke, "#262626", 4, SKStrokeCap.Square); SKPaint minPaint = GetPaintColor(SKPaintStyle.Stroke, "#DE0469", 2, SKStrokeCap.Square); SKPaint bgPaint = GetPaintColor(SKPaintStyle.Fill, "#FFFFFF"); canvas.Clear(); SKRect arcRect = new SKRect(10, 10, info.Width - 10, info.Height - 10); SKRect bgRect = new SKRect(25, 25, info.Width - 25, info.Height - 25); canvas.DrawOval(bgRect, bgPaint); strokePaint.Shader = SKShader.CreateLinearGradient( new SKPoint(arcRect.Left, arcRect.Top), new SKPoint(arcRect.Right, arcRect.Bottom), new SKColor[] { SKColor.Parse("#DE0469"), SKColors.Transparent }, new float[] { 0, 1 }, SKShaderTileMode.Repeat); path.ArcTo(arcRect, 45, arcLength, true); canvas.DrawPath(path, strokePaint); canvas.Translate(info.Width / 2, info.Height / 2); canvas.Scale(info.Width / 200f); canvas.Save(); canvas.RotateDegrees(240); canvas.DrawCircle(0, -75, 2, dotPaint); canvas.Restore(); DateTime dateTime = DateTime.Now; //Draw hour hand canvas.Save(); canvas.RotateDegrees(30 * dateTime.Hour + dateTime.Minute / 2f); canvas.DrawLine(0, 5, 0, -60, hrPaint); canvas.Restore(); //Draw minute hand canvas.Save(); canvas.RotateDegrees(6 * dateTime.Minute + dateTime.Second / 10f); canvas.DrawLine(0, 10, 0, -90, minPaint); canvas.Restore(); canvas.DrawCircle(0, 0, 5, dotPaint); secondsTxt.Text = dateTime.Second.ToString("00"); timeTxt.Text = dateTime.ToString("hh:mm"); periodTxt.Text = dateTime.Hour >= 12 ? "PM" : "AM"; var alarmDiff = alarmDate - dateTime; alarmTxt.Text = $"{alarmDiff.Hours}h {alarmDiff.Minutes}m until next alarm"; }
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 sectorCenterRadius = (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); }
protected override void OnPaintSurface(SKPaintSurfaceEventArgs e) { e.Surface.Canvas.Clear(); m_deviceScale = (float)(e.Info.Width / Width); SKPaint paint = new SKPaint() { Color = IndicatorForeground.ToSKColor(), Style = SKPaintStyle.Fill, }; Easing ease = Easing.SinOut; using (SKPath path = new SKPath()) { double startAngle = 0; double endAngle = 0; if (m_animationProcess >= 0 && m_animationProcess <= 0.5) { endAngle = ease.Ease(m_animationProcess * 2) * 270; startAngle = -10; } if (m_animationProcess > 0.5 && m_animationProcess <= 1) { endAngle = ease.Ease(1) * 270; startAngle = ease.Ease((m_animationProcess - 0.5) * 2) * 250; } else if (m_animationProcess > 1 && m_animationProcess <= 1.5) { endAngle = 270; startAngle = 250; } else if (m_animationProcess > 1.5 && m_animationProcess <= 2) { endAngle = 270 + (ease.Ease((m_animationProcess - 1.5) * 2) * 270); startAngle = 250; } else if (m_animationProcess > 2 && m_animationProcess <= 2.5) { endAngle = 270 + 270; startAngle = 250 + (ease.Ease((m_animationProcess - 2) * 2) * 270); } else if (m_animationProcess > 2.5 && m_animationProcess <= 3) { endAngle = 270 + 270; startAngle = 250 + 270; } else if (m_animationProcess > 3 && m_animationProcess <= 3.5) { endAngle = 270 + 270 + (ease.Ease((m_animationProcess - 3) * 2) * 270); startAngle = 250 + 270; } else if (m_animationProcess > 3.5 && m_animationProcess <= 4) { endAngle = 270 + 270 + 270; startAngle = 250 + 270 + (ease.Ease((m_animationProcess - 3.5) * 2) * 270); } else if (m_animationProcess > 4 && m_animationProcess <= 4.5) { endAngle = 270 + 270 + 270; startAngle = 250 + 270 + 270; } else if (m_animationProcess > 4.5 && m_animationProcess <= 5) { endAngle = 270 + 270 + 270 + (ease.Ease((m_animationProcess - 4.5) * 2) * 270); startAngle = 250 + 270 + 270; } else if (m_animationProcess > 5 && m_animationProcess <= 5.5) { endAngle = 270 + 270 + 270 + 270; startAngle = 250 + 270 + 270 + (ease.Ease((m_animationProcess - 5) * 2) * 270); } else if (m_animationProcess > 5.5 && m_animationProcess <= 6) { endAngle = 270 + 270 + 270 + 270; startAngle = 250 + 270 + 270 + 270; } startAngle += (m_animationProcess / 2) * 360; endAngle += (m_animationProcess / 2) * 360; float yOffset = (float)((Width - IndicatorSize.Width) / 2) * m_deviceScale; float xOffset = (float)((Height - IndicatorSize.Height) / 2) * m_deviceScale; float skIndicatorThickness = (float)IndicatorThickness * m_deviceScale; SKSize skIndicatorSize = new SKSize((float)IndicatorSize.Width * m_deviceScale, (float)IndicatorSize.Height * m_deviceScale); SKRect indicatorOuterBounds = new SKRect(); indicatorOuterBounds.Location = new SKPoint(xOffset, yOffset); indicatorOuterBounds.Size = new SKSize(skIndicatorSize.Width, skIndicatorSize.Height); SKRect indicatorInternalBounds = new SKRect(); indicatorInternalBounds.Location = new SKPoint(xOffset + skIndicatorThickness, yOffset + skIndicatorThickness); indicatorInternalBounds.Size = new SKSize((float)Math.Max(1, skIndicatorSize.Width - (skIndicatorThickness * 2)), (float)Math.Max(1, skIndicatorSize.Height - (skIndicatorThickness * 2))); path.ArcTo(indicatorOuterBounds, (float)startAngle, (float)(endAngle - startAngle), false); path.ArcTo(indicatorInternalBounds, (float)endAngle, (float)-(endAngle - startAngle), false); e.Surface.Canvas.DrawPath(path, paint); } }
private void DrawValueIndicator(SKCanvas canvas, int width, int height) { if (IndicatorValue < Minimum || IndicatorValue > Maximum) { return; } float indicatorPosition = (height - guageWidth * 2) * (1f - (IndicatorValue - Minimum) / (Maximum - Minimum)) + guageWidth; float verticalMargin = guageWidth / 2 + regularStrokeWidth / 2; //Draw Indicator Line var start = new SKPoint(IndicatorDirection == "Right" ? guageWidth + 10 : width - guageWidth - 10, indicatorPosition); var end = new SKPoint(IndicatorDirection == "Right" ? guageWidth + 40 : width - guageWidth - 40, indicatorPosition); canvas.DrawLine(start, end, indicatorStrokePaint); //Draw Value Label using (var textPaint = new SKPaint()) { textPaint.TextSize = (Device.RuntimePlatform == Device.Android) ? 36 : 20; textPaint.IsAntialias = true; textPaint.Color = strokeColor; textPaint.IsStroke = false; var indicatorText = IndicatorValue.ToString("0.0") + (!String.IsNullOrEmpty(IndicatorValueUnit) ? " " + IndicatorValueUnit : ""); if (IndicatorDirection == "Right") { canvas.DrawText(indicatorText, guageWidth + 40 + 10, indicatorPosition + 14, textPaint); } else { float textWidth = textPaint.MeasureText(indicatorText); canvas.DrawText(indicatorText, width - guageWidth - 40 - 10 - textWidth, indicatorPosition + 14, textPaint); } } //Fill the guage using (SKPath containerPath = new SKPath()) { switch (IndicatorDirection) { case "Right": containerPath.MoveTo(regularStrokeWidth / 2, indicatorPosition); containerPath.LineTo(guageWidth + regularStrokeWidth / 2, indicatorPosition); containerPath.LineTo(guageWidth + regularStrokeWidth / 2, height - verticalMargin); containerPath.ArcTo(guageWidth / 2, guageWidth / 2, 0, SKPathArcSize.Large, SKPathDirection.Clockwise, regularStrokeWidth / 2, height - verticalMargin); containerPath.Close(); break; case "Left": containerPath.MoveTo(width - guageWidth - regularStrokeWidth / 2, indicatorPosition); containerPath.LineTo(width - regularStrokeWidth / 2, indicatorPosition); containerPath.LineTo(width - regularStrokeWidth / 2, height - verticalMargin); containerPath.ArcTo(guageWidth / 2, guageWidth / 2, 0, SKPathArcSize.Large, SKPathDirection.Clockwise, width - guageWidth - regularStrokeWidth / 2, height - verticalMargin); containerPath.Close(); break; } canvas.DrawPath(containerPath, fillPaint); } }
public static void ArcWithCenterTo(this SKPath path, float x, float y, float radius, float startDegrees, float sweepDegrees) { var rect = new SKRect(x - radius, y - radius, x + radius, y + radius); path.ArcTo(rect, startDegrees, sweepDegrees, false); }
private void DrawChart(SKPaintSurfaceEventArgs args) { if (args == null) { return; } SKImageInfo info = args.Info; SKSurface surface = args.Surface; SKCanvas canvas = surface.Canvas; canvas.Clear(); decimal totalValues = 0; foreach (ChartEntry item in chartData) { totalValues += item.Value; } var center = new SKPoint(info.Width / 2, info.Height / 2); float explodeOffset = 0; float radius = Math.Min(info.Width / 2, info.Height / 2) - (2 * explodeOffset); var rect = new SKRect(center.X - radius, center.Y - radius, center.X + radius, center.Y + radius); rect.Inflate(-8, -8); float startAngle = 0; foreach (ChartEntry item in chartData) { double sweepAngle = (double)(360 * item.Value / totalValues); using (var path = new SKPath()) using (var fillPaint = new SKPaint()) using (var outlinePaint = new SKPaint()) { fillPaint.IsAntialias = true; outlinePaint.IsAntialias = true; path.MoveTo(center); path.ArcTo(rect, startAngle, (float)sweepAngle, false); path.Close(); fillPaint.Style = SKPaintStyle.Fill; fillPaint.Color = item.Color; outlinePaint.Style = SKPaintStyle.Stroke; outlinePaint.StrokeWidth = 4; outlinePaint.Color = MyColors.Darker(item.Color, 0.7f); // Calculate "explode" transform float angle = startAngle + (0.5f * (float)sweepAngle); float x = explodeOffset * (float)Math.Cos(Math.PI * angle / 180); float y = explodeOffset * (float)Math.Sin(Math.PI * angle / 180); _ = canvas.Save(); canvas.Translate(x, y); // Fill and stroke the path canvas.DrawPath(path, fillPaint); //canvas.DrawPath(path, outlinePaint); canvas.Restore(); } startAngle += (float)sweepAngle; } }
SKBitmap CreateChainLinkTile(int tileSize) { tileBitmap = new SKBitmap(tileSize, tileSize); float wireThickness = tileSize / 12f; using (SKCanvas canvas = new SKCanvas(tileBitmap)) using (SKPaint paint = new SKPaint()) { canvas.Clear(); paint.Style = SKPaintStyle.Stroke; paint.StrokeWidth = wireThickness; paint.IsAntialias = true; // Draw straight wires first paint.Shader = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(0, tileSize), new SKColor[] { SKColors.Silver, SKColors.Black }, new float[] { 0.4f, 0.6f }, SKShaderTileMode.Clamp); canvas.DrawLine(0, tileSize / 2, tileSize / 2, tileSize / 2 - wireThickness / 2, paint); canvas.DrawLine(tileSize, tileSize / 2, tileSize / 2, tileSize / 2 + wireThickness / 2, paint); // Draw curved wires using (SKPath path = new SKPath()) { path.MoveTo(tileSize / 2, 0); path.LineTo(tileSize / 2 - wireThickness / 2, tileSize / 2); path.ArcTo(wireThickness / 2, wireThickness / 2, 0, SKPathArcSize.Small, SKPathDirection.CounterClockwise, tileSize / 2, tileSize / 2 + wireThickness / 2); paint.Shader = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(0, tileSize), new SKColor[] { SKColors.Silver, SKColors.Black }, null, SKShaderTileMode.Clamp); canvas.DrawPath(path, paint); path.Reset(); path.MoveTo(tileSize / 2, tileSize); path.LineTo(tileSize / 2 + wireThickness / 2, tileSize / 2); path.ArcTo(wireThickness / 2, wireThickness / 2, 0, SKPathArcSize.Small, SKPathDirection.CounterClockwise, tileSize / 2, tileSize / 2 - wireThickness / 2); paint.Shader = SKShader.CreateLinearGradient(new SKPoint(0, 0), new SKPoint(0, tileSize), new SKColor[] { SKColors.White, SKColors.Silver }, null, SKShaderTileMode.Clamp); canvas.DrawPath(path, paint); } return(tileBitmap); } }
/// <summary> /// Update path /// </summary> private static (SKPath, SKPoint) CreateCalloutPath(CalloutStyle callout, double contentWidth, double contentHeight) { var strokeWidth = callout.StrokeWidth < 1 ? 1 : callout.StrokeWidth; var paddingLeft = callout.Padding.Left < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Left; var paddingTop = callout.Padding.Top < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Top; var paddingRight = callout.Padding.Right < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Right; var paddingBottom = callout.Padding.Bottom < callout.RectRadius * 0.5 ? callout.RectRadius * 0.5 : callout.Padding.Bottom; var width = (float)contentWidth + (float)paddingLeft + (float)paddingRight; var height = (float)contentHeight + (float)paddingTop + (float)paddingBottom; var halfWidth = width * callout.ArrowPosition; var halfHeight = height * callout.ArrowPosition; var bottom = height + callout.ShadowWidth + strokeWidth * 2; var left = callout.ShadowWidth + strokeWidth; var top = callout.ShadowWidth + strokeWidth; var right = width + callout.ShadowWidth + strokeWidth * 2; var start = new SKPoint(); var center = new SKPoint(); var end = new SKPoint(); // Check, if we are to near at corners if (halfWidth - callout.ArrowWidth * 0.5f - left < callout.RectRadius) { halfWidth = callout.ArrowWidth * 0.5f + left + callout.RectRadius; } else if (halfWidth + callout.ArrowWidth * 0.5f > width - callout.RectRadius) { halfWidth = width - callout.ArrowWidth * 0.5f - callout.RectRadius; } if (halfHeight - callout.ArrowWidth * 0.5f - top < callout.RectRadius) { halfHeight = callout.ArrowWidth * 0.5f + top + callout.RectRadius; } else if (halfHeight + callout.ArrowWidth * 0.5f > height - callout.RectRadius) { halfHeight = height - callout.ArrowWidth * 0.5f - callout.RectRadius; } switch (callout.ArrowAlignment) { case ArrowAlignment.Bottom: start = new SKPoint(halfWidth + callout.ArrowWidth * 0.5f, bottom); center = new SKPoint(halfWidth, bottom + callout.ArrowHeight); end = new SKPoint(halfWidth - callout.ArrowWidth * 0.5f, bottom); break; case ArrowAlignment.Top: top += callout.ArrowHeight; bottom += callout.ArrowHeight; start = new SKPoint(halfWidth - callout.ArrowWidth * 0.5f, top); center = new SKPoint(halfWidth, top - callout.ArrowHeight); end = new SKPoint(halfWidth + callout.ArrowWidth * 0.5f, top); break; case ArrowAlignment.Left: left += callout.ArrowHeight; right += callout.ArrowHeight; start = new SKPoint(left, halfHeight + callout.ArrowWidth * 0.5f); center = new SKPoint(left - callout.ArrowHeight, halfHeight); end = new SKPoint(left, halfHeight - callout.ArrowWidth * 0.5f); break; case ArrowAlignment.Right: start = new SKPoint(right, halfHeight - callout.ArrowWidth * 0.5f); center = new SKPoint(right + callout.ArrowHeight, halfHeight); end = new SKPoint(right, halfHeight + callout.ArrowWidth * 0.5f); break; } // Create path var path = new SKPath(); // Move to start point at left/top path.MoveTo(left + callout.RectRadius, top); // Top horizontal line if (callout.ArrowAlignment == ArrowAlignment.Top) { DrawArrow(path, start, center, end); } // Top right arc path.ArcTo(new SKRect(right - callout.RectRadius, top, right, top + callout.RectRadius), 270, 90, false); // Right vertical line if (callout.ArrowAlignment == ArrowAlignment.Right) { DrawArrow(path, start, center, end); } // Bottom right arc path.ArcTo(new SKRect(right - callout.RectRadius, bottom - callout.RectRadius, right, bottom), 0, 90, false); // Bottom horizontal line if (callout.ArrowAlignment == ArrowAlignment.Bottom) { DrawArrow(path, start, center, end); } // Bottom left arc path.ArcTo(new SKRect(left, bottom - callout.RectRadius, left + callout.RectRadius, bottom), 90, 90, false); // Left vertical line if (callout.ArrowAlignment == ArrowAlignment.Left) { DrawArrow(path, start, center, end); } // Top left arc path.ArcTo(new SKRect(left, top, left + callout.RectRadius, top + callout.RectRadius), 180, 90, false); path.Close(); return(path, center); }
void SKCanvasView_PaintSurface(System.Object sender, SkiaSharp.Views.Forms.SKPaintSurfaceEventArgs e) { SKPaint arcColor = new SKPaint { Color = ArcColor.ToSKColor(), StrokeWidth = 2, Style = SKPaintStyle.StrokeAndFill }; var w = e.Info.Width; var h = e.Info.Height; var canvas = e.Surface.Canvas; canvas.Clear(); var h1 = h / 3.33f; float xDelta = w / 165; float yDelta = h / 6; var h2 = h1 + yDelta; var p1 = new SKPoint(0, h1); var p2 = new SKPoint(xDelta, h2); var p3 = new SKPoint(w / 3 - xDelta, h2); var p4 = new SKPoint(w / 3, h1); var p5 = new SKPoint(2 * w / 3, h1); var p6 = new SKPoint(2 * w / 3 + xDelta, h2); var p7 = new SKPoint(w - xDelta, h2); var p8 = new SKPoint(w, h1); var e1Xr = (p3.X - p2.X) / 2; var e2Xr = (p5.X - p4.X) / 2; var e3Xr = (p7.X - p6.X) / 2; float e1Yr = h / 2.5f; float e2Yr = h1; using (var path = new SKPath()) { path.MoveTo(0, 0); path.LineTo(p1); path.LineTo(p2); path.ArcTo(e1Xr, e1Yr, 0, SKPathArcSize.Large, SKPathDirection.CounterClockwise, p3.X, p3.Y); path.LineTo(p4); path.ArcTo(e2Xr, e2Yr, 0, SKPathArcSize.Large, SKPathDirection.Clockwise, p5.X, p5.Y); path.LineTo(p6); path.ArcTo(e3Xr, e1Yr, 0, SKPathArcSize.Large, SKPathDirection.CounterClockwise, p7.X, p7.Y); path.LineTo(p8); path.LineTo(w, 0); canvas.DrawPath(path, arcColor); } }