Exemple #1
0
        /// <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);
        }
Exemple #2
0
        /// <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();
        }
Exemple #3
0
        /// <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);
Exemple #5
0
        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");
            }
        }
Exemple #7
0
        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);
        }
Exemple #9
0
        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);
        }
Exemple #10
0
        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);
                }
            }
        }
Exemple #11
0
            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;
            }
Exemple #12
0
        //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);
        }
Exemple #15
0
        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);
            }
        }
Exemple #16
0
        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);
        }
Exemple #18
0
        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);
                }
        }
Exemple #20
0
        /// <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);
        }
Exemple #21
0
        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);
            }
        }