Пример #1
0
 public /*interface ChartPainter*/ void DrawCourseRange(List <KChartEntry> list, int seriesIndex, SKColor color, Swipe pinchPan)
 {
     if (list.Count == 1)
     {
         DrawCircle(list[0].Ypoint[seriesIndex], pinchPan % 8, FillPaint(color));
     }
     if (list.Count > 1)
     {
         canvas.SetFillColor(CG.Color(color));
         var         path       = new CGPath();
         KChartEntry entry0     = list[0];
         SKPoint     meanPoint0 = entry0.Ypoint[seriesIndex];
         float       range0     = entry0.YpointRange[seriesIndex];
         path.MoveToPoint(CG.Point(pinchPan % new SKPoint(meanPoint0.X, meanPoint0.Y + range0)));
         path.AddLineToPoint(CG.Point(pinchPan % new SKPoint(meanPoint0.X, meanPoint0.Y - range0)));
         for (int i = 0; i < list.Count; i++)
         {
             KChartEntry entry     = list[i];
             SKPoint     meanPoint = entry.Ypoint[seriesIndex];
             float       range     = entry.YpointRange[seriesIndex];
             path.AddLineToPoint(CG.Point(pinchPan % new SKPoint(meanPoint.X, meanPoint.Y - range)));
         }
         for (int i = list.Count - 1; i >= 0; i--)
         {
             KChartEntry entry     = list[i];
             SKPoint     meanPoint = entry.Ypoint[seriesIndex];
             float       range     = entry.YpointRange[seriesIndex];
             path.AddLineToPoint(CG.Point(pinchPan % new SKPoint(meanPoint.X, meanPoint.Y + range)));
         }
         path.CloseSubpath();
         canvas.AddPath(path);
         canvas.FillPath();
     }
 }
Пример #2
0
 public static void DrawPolygon(CGContext canvas, List <SKPoint> points, SKPaint paint)
 {
     if (points.Count > 1)
     {
         var path = new CGPath();
         path.MoveToPoint(CG.Point(points[0]));
         for (int i = 0; i < points.Count; i++)
         {
             path.AddLineToPoint(CG.Point(points[i]));
         }
         PaintPath(canvas, path, paint);
     }
 }
Пример #3
0
 private static CGPath AddBeziers(CGPath path, SKPoint[] controlPoints)
 {
     path.MoveToPoint(CG.Point(controlPoints[0]));
     for (int i = 0; i < controlPoints.Length - 2; i += 4)
     {
         if (i + 3 > controlPoints.Length - 1)
         {
             var cp = CG.Point(controlPoints[i + 1]); var p = CG.Point(controlPoints[i + 2]);
             path.AddQuadCurveToPoint(cp.X, cp.Y, p.X, p.Y);
         }
         else
         {
             path.AddCurveToPoint(CG.Point(controlPoints[i + 1]), CG.Point(controlPoints[i + 2]), CG.Point(controlPoints[i + 3]));
         }
     }
     return(path);
 }
Пример #4
0
 public /*interface ChartPainter*/ void DrawCourseFill(List <KChartEntry> list, int seriesIndex, float bottom, SKColor color, Swipe pinchPan)
 {
     if (list.Count > 1)
     {
         canvas.SetFillColor(CG.Color(color));
         var path = new CGPath();
         path.MoveToPoint(CG.Point(pinchPan % new SKPoint(list[0].Ypoint[seriesIndex].X, bottom)));
         path.AddLineToPoint(CG.Point(pinchPan % list[0].Ypoint[seriesIndex]));
         for (int i = 0; i < list.Count; i++)
         {
             path.AddLineToPoint(CG.Point(pinchPan % list[i].Ypoint[seriesIndex]));
         }
         path.AddLineToPoint(CG.Point(pinchPan % new SKPoint(list[list.Count - 1].Ypoint[seriesIndex].X, bottom)));
         path.CloseSubpath();
         canvas.AddPath(path);
         canvas.FillPath();
     }
 }
Пример #5
0
 public /*interface ChartPainter*/ void DrawCourse(List <KChartEntry> list, int seriesIndex, float pointSize, SKColor color, Swipe pinchPan)
 {
     if (list.Count == 1)
     {
         DrawCircle(list[0].Ypoint[seriesIndex], pinchPan % 8, FillPaint(color));
     }
     if (list.Count > 1)
     {
         canvas.SetStrokeColor(CG.Color(color));
         canvas.SetLineWidth(pointSize);
         var path = new CGPath();
         path.MoveToPoint(CG.Point(pinchPan % list[0].Ypoint[seriesIndex]));
         for (int i = 0; i < list.Count; i++)
         {
             path.AddLineToPoint(CG.Point(pinchPan % list[i].Ypoint[seriesIndex]));
         }
         canvas.AddPath(path);
         canvas.StrokePath();
     }
 }
Пример #6
0
        public void DrawPad(CGContext canvas, SKPoint center, float radius, SKPaint strokePaint, float strokePaintStrokeWidth, SKPaint fillPaint, SKPaint holePaint, SKPaint strokeAccentPaint, float strokeAccentPaintStrokeWidth, SKPaint holeAccentPaint, Swipe swipe)
        {
            float step       = radius / 7.0f;
            float holeRadius = radius / 7.0f;
            float orthShift  = (strokePaintStrokeWidth + strokeAccentPaintStrokeWidth) / 2.0f;
            float diagShift  = orthShift / 1.41f;

            var path = new CGPath();

            path.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y - radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y - radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 1 * step, center.Y - radius + 2 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius - 1 * step, center.Y - radius + 4 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 1 * step, center.Y - radius + 6 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius - 1 * step, center.Y - radius + 8 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 1 * step, center.Y - radius + 10 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius - 1 * step, center.Y - radius + 12 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y - radius + 13 * step)));

            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y + radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 1 * step, center.Y + radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 2 * step, center.Y + radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 4 * step, center.Y + radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 6 * step, center.Y + radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 8 * step, center.Y + radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 10 * step, center.Y + radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 12 * step, center.Y + radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + 13 * step, center.Y + radius)));

            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y + radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y + radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 1 * step, center.Y + radius - 2 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + 1 * step, center.Y + radius - 4 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 1 * step, center.Y + radius - 6 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + 1 * step, center.Y + radius - 8 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 1 * step, center.Y + radius - 10 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + 1 * step, center.Y + radius - 12 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y + radius - 13 * step)));

            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y - radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 1 * step, center.Y - radius)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 2 * step, center.Y - radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 4 * step, center.Y - radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 6 * step, center.Y - radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 8 * step, center.Y - radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 10 * step, center.Y - radius + 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 12 * step, center.Y - radius - 1 * step)));
            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius - 13 * step, center.Y - radius)));

            path.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y - radius)));
            path.CloseSubpath();

            var accPathLft = new CGPath();

            accPathLft.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius + orthShift, center.Y - radius + orthShift)));
            accPathLft.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + orthShift, center.Y - radius + orthShift + 1 * step)));
            accPathLft.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift + 1 * step, center.Y - radius + diagShift + 2 * step)));
            accPathLft.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift - 1 * step, center.Y - radius + diagShift + 4 * step)));
            accPathLft.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift + 1 * step, center.Y - radius + diagShift + 6 * step)));
            accPathLft.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift - 1 * step, center.Y - radius + diagShift + 8 * step)));
            accPathLft.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift + 1 * step, center.Y - radius + diagShift + 10 * step)));
            accPathLft.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + diagShift - 1 * step, center.Y - radius + diagShift + 12 * step)));
            accPathLft.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - radius + orthShift, center.Y - radius + 13 * step)));
            accPathLft.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X - radius + orthShift, center.Y - radius + 14 * step)));

            var accPathTop = new CGPath();

            accPathTop.MoveToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y - radius + orthShift)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift / 2 - 1 * step, center.Y - radius + orthShift)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 2 * step, center.Y - radius + diagShift + 1 * step)));
            accPathTop.MoveToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 4 * step, center.Y - radius + diagShift - 1 * step)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 6 * step, center.Y - radius + diagShift + 1 * step)));
            accPathTop.MoveToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 8 * step, center.Y - radius + diagShift - 1 * step)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 10 * step, center.Y - radius + diagShift + 1 * step)));
            accPathTop.MoveToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift - 12 * step, center.Y - radius + diagShift - 1 * step)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + diagShift / 2 - 13 * step, center.Y - radius + orthShift)));
            accPathTop.AddLineToPoint(CG.Point(swipe % new SKPoint(center.X + radius + orthShift - 14 * step, center.Y - radius + orthShift)));

            canvas.AddPath(path);
            canvas.SetFillColor(CG.Color(fillPaint.Color));
            canvas.FillPath();

            canvas.AddPath(accPathLft);
            canvas.SetStrokeColor(CG.Color(strokeAccentPaint.Color));
            canvas.SetLineWidth(strokeAccentPaint.StrokeWidth);
            canvas.SetLineJoin(CG.LineJoin(strokeAccentPaint.StrokeJoin));
            canvas.SetLineCap(CG.LineCap(strokeAccentPaint.StrokeCap));
            canvas.StrokePath();

            canvas.AddPath(accPathTop);
            canvas.SetStrokeColor(CG.Color(strokeAccentPaint.Color));
            canvas.SetLineWidth(strokeAccentPaint.StrokeWidth);
            canvas.SetLineJoin(CG.LineJoin(strokeAccentPaint.StrokeJoin));
            canvas.SetLineCap(CG.LineCap(strokeAccentPaint.StrokeCap));
            canvas.StrokePath();

            canvas.AddPath(path);
            canvas.SetStrokeColor(CG.Color(strokePaint.Color));
            canvas.SetLineWidth(strokePaint.StrokeWidth);
            canvas.SetLineJoin(CG.LineJoin(strokePaint.StrokeJoin));
            canvas.SetLineCap(CG.LineCap(strokePaint.StrokeCap));
            canvas.StrokePath();

            canvas.AddEllipseInRect(CG.RectFromCircle(swipe % new SKPoint(center.X + diagShift / 2, center.Y + diagShift / 2), swipe % (holeRadius + diagShift / 2)));
            canvas.SetFillColor(CG.Color(holeAccentPaint.Color));
            canvas.FillPath();
            canvas.AddEllipseInRect(CG.RectFromCircle(swipe % center, swipe % holeRadius));
            canvas.SetFillColor(CG.Color(holePaint.Color));
            canvas.FillPath();
        }
Пример #7
0
        public void DrawDropletPulledVer(CGContext canvas, string label, bool biggie, SKPoint c1, SKPoint c2, KDeviceHandler.Direction dir, float r, float r1, float neckX, float r2, float textStrokeWidth, SKPaint fillPaint, float strokeWidth, float accentStrokeWidth, Swipe swipe)
        {
            float ratio = ((r1 + r2) / 2) / r;

            //strokeWidth = strokeWidth * ratio;
            textStrokeWidth   = textStrokeWidth * ratio;
            accentStrokeWidth = accentStrokeWidth * ratio;

            float lr = r1 - (strokeWidth + accentStrokeWidth) / 2.0f;
            float dr = r2 - (strokeWidth + accentStrokeWidth) / 2.0f;

            // place the neck in an Y-position proportional to the rate between r1 and r2, with m1+r1Y to the top leading to c1.Y, and m2+r2Y to the bot leading to c2.Y
            float m1 = (2 * r - (r1 + r2)) / (1 + r2 / r1);
            float m2 = m1 * r2 / r1;
            // position of the neck
            float nY = c1.Y + r1 + m1;
            float nX = c1.X;
            // Control points: a1*2 is on a line from nY,nX-neckX to c1.Y,c.X-r1 where it intersects c1.Y+r1; we divide it by 2 to make the curve smoother
            float a1 = (m1 * (r1 - neckX) / (r1 + m1)) / 2;
            float a2 = (m2 * (r2 - neckX) / (r2 + m2)) / 2;

            var path = new CGPath();

            path.MoveToPoint(CG.Point(swipe % new SKPoint(c1.X - r1, c1.Y)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c1.X - r1, c1.Y + 0.5f * r1)), CG.Point(swipe % new SKPoint(nX - (neckX + a1), c1.Y + r1)), CG.Point(swipe % new SKPoint(nX - neckX, nY)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(nX - (neckX + a2), c2.Y - r2)), CG.Point(swipe % new SKPoint(c2.X - r2, c2.Y - 0.5f * r2)), CG.Point(swipe % new SKPoint(c2.X - r2, c2.Y)));

            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c2.X - r2, c2.Y + 0.75f * r2)), CG.Point(swipe % new SKPoint(c2.X - 0.75f * r2, c2.Y + r2)), CG.Point(swipe % new SKPoint(c2.X, c2.Y + r2)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c2.X + 0.75f * r2, c2.Y + r2)), CG.Point(swipe % new SKPoint(c2.X + r2, c2.Y + 0.75f * r2)), CG.Point(swipe % new SKPoint(c2.X + r2, c2.Y)));

            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c2.X + r2, c2.Y - 0.5f * r2)), CG.Point(swipe % new SKPoint(nX + (neckX + a2), c2.Y - r2)), CG.Point(swipe % new SKPoint(nX + neckX, nY)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(nX + (neckX + a1), c1.Y + r1)), CG.Point(swipe % new SKPoint(c1.X + r1, c1.Y + 0.5f * r1)), CG.Point(swipe % new SKPoint(c1.X + r1, c1.Y)));

            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c1.X + r1, c1.Y - 0.75f * r1)), CG.Point(swipe % new SKPoint(c1.X + 0.75f * r1, c1.Y - r1)), CG.Point(swipe % new SKPoint(c1.X, c1.Y - r1)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(c1.X - 0.75f * r1, c1.Y - r1)), CG.Point(swipe % new SKPoint(c1.X - r1, c1.Y - 0.75f * r1)), CG.Point(swipe % new SKPoint(c1.X - r1, c1.Y)));
            path.CloseSubpath();

            var darkPath = new CGPath();

            darkPath.MoveToPoint(CG.Point(swipe % new SKPoint(c2.X, c2.Y + dr)));
            darkPath.AddCurveToPoint(CG.Point(swipe % new SKPoint(c2.X + 0.75f * dr, c2.Y + dr)), CG.Point(swipe % new SKPoint(c2.X + dr, c2.Y + 0.75f * dr)), CG.Point(swipe % new SKPoint(c2.X + dr, c2.Y)));

            var lightPath = new CGPath();

            lightPath.MoveToPoint(CG.Point(swipe % new SKPoint(c1.X, c1.Y - lr)));
            lightPath.AddCurveToPoint(CG.Point(swipe % new SKPoint(c1.X - 0.75f * lr, c1.Y - lr)), CG.Point(swipe % new SKPoint(c1.X - lr, c1.Y - 0.75f * lr)), CG.Point(swipe % new SKPoint(c1.X - lr, c1.Y)));

            using (var strokePaint = new SKPaint {
                Style = SKPaintStyle.Stroke, Color = new SKColor(0, 0, 0, 191), StrokeWidth = swipe % strokeWidth, IsAntialias = true
            })
                using (var accentLightPaint = new SKPaint {
                    Style = SKPaintStyle.Stroke, Color = new SKColor(255, 255, 255, 191), StrokeWidth = swipe % accentStrokeWidth, StrokeCap = SKStrokeCap.Round, IsAntialias = true
                })
                    using (var accentDarkPaint = new SKPaint {
                        Style = SKPaintStyle.Stroke, Color = new SKColor(0, 0, 0, 95), StrokeWidth = swipe % accentStrokeWidth, StrokeCap = SKStrokeCap.Round, IsAntialias = true
                    })
                    {
                        canvas.AddPath(path);
                        canvas.SetFillColor(CG.Color(fillPaint.Color));
                        canvas.FillPath();

                        canvas.AddPath(darkPath);
                        canvas.SetStrokeColor(CG.Color(accentDarkPaint.Color));
                        canvas.SetLineWidth(accentDarkPaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(accentDarkPaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(accentDarkPaint.StrokeCap));
                        canvas.StrokePath();

                        canvas.AddPath(lightPath);
                        canvas.SetStrokeColor(CG.Color(accentLightPaint.Color));
                        canvas.SetLineWidth(accentLightPaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(accentLightPaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(accentLightPaint.StrokeCap));
                        canvas.StrokePath();

                        canvas.AddPath(path);
                        canvas.SetStrokeColor(CG.Color(strokePaint.Color));
                        canvas.SetLineWidth(strokePaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(strokePaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(strokePaint.StrokeCap));
                        canvas.StrokePath();
                    }

            float   rYtext = (r1 == r2) ? ((dir == KDeviceHandler.Direction.Top) ? r1 : r2) : (r1 > r2) ? r1 : r2;
            SKPoint cText  = (r1 == r2) ? ((dir == KDeviceHandler.Direction.Top) ? c1 : c2) : (r1 > r2) ? c1 : c2;

            DrawDropletLabel(canvas, label, cText, rYtext, textStrokeWidth, biggie, swipe);
        }
Пример #8
0
        public void DrawDroplet(CGContext canvas, string label, bool biggie, SKPoint center, float padRadius, float radius, float textStrokeWidth, SKPaint fillPaint, float strokeWidth, float accentStrokeWidth, Swipe swipe)
        {
            float ratio = radius / padRadius;

            //strokeWidth = strokeWidth * ratio;
            textStrokeWidth   = textStrokeWidth * ratio;
            accentStrokeWidth = accentStrokeWidth * ratio;

            float pull         = 0.75f;
            float accentRadius = radius - (strokeWidth + accentStrokeWidth) / 2.0f;

            var path = new CGPath();

            path.MoveToPoint(CG.Point(swipe % new SKPoint(center.X, center.Y - radius)));
            // The parameters to CGPath.AddCurveToPoint are in the same order as in SKPath.CubicTo (despite what the Apple docs seem to say).
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X + pull * radius, center.Y - radius)), CG.Point(swipe % new SKPoint(center.X + radius, center.Y - pull * radius)), CG.Point(swipe % new SKPoint(center.X + radius, center.Y)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X + radius, center.Y + pull * radius)), CG.Point(swipe % new SKPoint(center.X + pull * radius, center.Y + radius)), CG.Point(swipe % new SKPoint(center.X, center.Y + radius)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X - pull * radius, center.Y + radius)), CG.Point(swipe % new SKPoint(center.X - radius, center.Y + pull * radius)), CG.Point(swipe % new SKPoint(center.X - radius, center.Y)));
            path.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X - radius, center.Y - pull * radius)), CG.Point(swipe % new SKPoint(center.X - pull * radius, center.Y - radius)), CG.Point(swipe % new SKPoint(center.X, center.Y - radius)));
            path.CloseSubpath();

            var darkPath = new CGPath();

            darkPath.MoveToPoint(CG.Point(swipe % new SKPoint(center.X + accentRadius, center.Y)));
            darkPath.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X + accentRadius, center.Y + pull * accentRadius)), CG.Point(swipe % new SKPoint(center.X + pull * accentRadius, center.Y + accentRadius)), CG.Point(swipe % new SKPoint(center.X, center.Y + accentRadius)));

            var lightPath = new CGPath();

            lightPath.MoveToPoint(CG.Point(swipe % new SKPoint(center.X - accentRadius, center.Y)));
            lightPath.AddCurveToPoint(CG.Point(swipe % new SKPoint(center.X - accentRadius, center.Y - pull * accentRadius)), CG.Point(swipe % new SKPoint(center.X - pull * accentRadius, center.Y - accentRadius)), CG.Point(swipe % new SKPoint(center.X, center.Y - accentRadius)));

            using (var strokePaint = new SKPaint {
                Style = SKPaintStyle.Stroke, Color = new SKColor(0, 0, 0, 191), StrokeWidth = swipe % strokeWidth, IsAntialias = true
            })
                using (var accentLightPaint = new SKPaint {
                    Style = SKPaintStyle.Stroke, Color = new SKColor(255, 255, 255, 191), StrokeWidth = swipe % accentStrokeWidth, StrokeCap = SKStrokeCap.Round, IsAntialias = true
                })
                    using (var accentDarkPaint = new SKPaint {
                        Style = SKPaintStyle.Stroke, Color = new SKColor(0, 0, 0, 95), StrokeWidth = swipe % accentStrokeWidth, StrokeCap = SKStrokeCap.Round, IsAntialias = true
                    })
                    {
                        canvas.AddPath(path);
                        canvas.SetFillColor(CG.Color(fillPaint.Color));
                        canvas.FillPath();

                        canvas.AddPath(darkPath);
                        canvas.SetStrokeColor(CG.Color(accentDarkPaint.Color));
                        canvas.SetLineWidth(accentDarkPaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(accentDarkPaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(accentDarkPaint.StrokeCap));
                        canvas.StrokePath();

                        canvas.AddPath(lightPath);
                        canvas.SetStrokeColor(CG.Color(accentLightPaint.Color));
                        canvas.SetLineWidth(accentLightPaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(accentLightPaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(accentLightPaint.StrokeCap));
                        canvas.StrokePath();

                        canvas.AddPath(path);
                        canvas.SetStrokeColor(CG.Color(strokePaint.Color));
                        canvas.SetLineWidth(strokePaint.StrokeWidth);
                        canvas.SetLineJoin(CG.LineJoin(strokePaint.StrokeJoin));
                        canvas.SetLineCap(CG.LineCap(strokePaint.StrokeCap));
                        canvas.StrokePath();
                    }

            DrawDropletLabel(canvas, label, center, radius, textStrokeWidth, biggie, swipe);
        }