Example #1
0
        public override void LayoutSublayers()
        {
            base.LayoutSublayers();

            CGRect r = Bounds;

            FadeLayer.Bounds   = r;
            FadeLayer.Position = new CGPoint(r.GetMidX(), r.GetMidY());
        }
Example #2
0
        public void DrawArc(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle)
        {
            SetOffset(false);
            StartDrawing();

            var rect = new CGRect(x, y, width, height);

            pen.Apply(this);
            var yscale  = rect.Height / rect.Width;
            var centerY = rect.GetMidY();
            var centerX = rect.GetMidX();

            Control.ConcatCTM(new CGAffineTransform(1.0f, 0, 0, yscale, 0, centerY - centerY * yscale));
            Control.AddArc(centerX, centerY, rect.Width / 2, CGConversions.DegreesToRadians(startAngle), CGConversions.DegreesToRadians(startAngle + sweepAngle), sweepAngle < 0);
            Control.StrokePath();
            EndDrawing();
        }
        /// <summary>
        /// Tells the layer to update its layout.
        /// </summary>
        public override void LayoutSublayers()
        {
            base.LayoutSublayers();

            CGRect r = Bounds;

            if (_contentLayer != null)
            {
                _contentLayer.AnchorPoint = new CGPoint(0.5f, 0.5f);
                _contentLayer.Bounds      = r;
                _contentLayer.Position    = new CGPoint(r.GetMidX(), r.GetMidY());
            }
            if (_maskLayer != null)
            {
                UpdateMaskLayout();
            }
        }
        public void DrawArc(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle)
        {
            SetOffset(true);
            StartDrawing();

            var rect = new CGRect(x, y, width, height);

            pen.Apply(this);
            var yscale  = rect.Height / rect.Width;
            var centerY = rect.GetMidY();
            var centerX = rect.GetMidX();

            Control.SaveState();             // save so the drawing of the pen isn't affected by the transform
            Control.ConcatCTM(new CGAffineTransform(1.0f, 0, 0, yscale, 0, centerY - centerY * yscale));
            Control.AddArc(centerX, centerY, rect.Width / 2, CGConversions.DegreesToRadians(startAngle), CGConversions.DegreesToRadians(startAngle + sweepAngle), sweepAngle < 0);
            Control.RestoreState();
            pen.Finish(this);
            EndDrawing();
        }
        public void FillPie(Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle)
        {
            SetOffset(true);
            StartDrawing();

            var rect = new CGRect(x, y, width, height);

            Control.SaveState();             // save so the drawing of the brush isn't affected by the transform
            var yscale  = rect.Height / rect.Width;
            var centerY = rect.GetMidY();
            var centerX = rect.GetMidX();

            Control.ConcatCTM(new CGAffineTransform(1.0f, 0, 0, yscale, 0, centerY - centerY * yscale));
            Control.MoveTo(centerX, centerY);
            Control.AddArc(centerX, centerY, rect.Width / 2, CGConversions.DegreesToRadians(startAngle), CGConversions.DegreesToRadians(startAngle + sweepAngle), sweepAngle < 0);
            Control.AddLineToPoint(centerX, centerY);
            Control.ClosePath();
            Control.RestoreState();
            brush.Draw(this, false, FillMode.Winding);
            EndDrawing();
        }
        //utility for drawing rectangle shape
        public void DrawRectShapeInContext(CGContext ctx, CGRect rect)
        {
            ctx.SetFillColor(UIColor.FromRGBA(95.0f / 255.0f, 104.0f / 255.0f, 114.0f / 255.0f, 1.0f).CGColor);
            ctx.SetStrokeColor(UIColor.FromRGBA(95.0f / 255.0f, 104.0f / 255.0f, 114.0f / 255.0f, 1.0f).CGColor);
            ctx.StrokeRect(rect);
            ctx.FillRect(rect);

            // Add rounded rect over plain rect with 4 pixel below the origin y, so that it will visible only the bottom rounded corners
            CGRect cornerRect = new CGRect(rect.X, rect.Y + 4, rect.Width, rect.Height);
            nfloat radius = 4;
            nfloat minx = cornerRect.GetMinX(), midx = cornerRect.GetMidX(), maxx = cornerRect.GetMaxX();
            nfloat miny = cornerRect.GetMinY(), midy = cornerRect.GetMidY(), maxy = cornerRect.GetMaxY();

            ctx.SaveState();
            ctx.MoveTo(minx, miny);
            ctx.AddArcToPoint(minx, miny, midx, miny, radius);
            ctx.AddArcToPoint(maxx, miny, maxx, midy, radius);
            ctx.AddArcToPoint(maxx, maxy, midx, maxy, radius);
            ctx.AddArcToPoint(minx, maxy, minx, midy, radius);
            ctx.ClosePath();
            ctx.DrawPath(CGPathDrawingMode.FillStroke);
            ctx.RestoreState();
        }
Example #7
0
		public void FillPie(Brush brush, float x, float y, float width, float height, float startAngle, float sweepAngle)
		{
			SetOffset(true);
			StartDrawing();

			var rect = new CGRect(x, y, width, height);
			Control.SaveState();
			var yscale = rect.Height / rect.Width;
			var centerY = rect.GetMidY();
			var centerX = rect.GetMidX();
			Control.ConcatCTM(new CGAffineTransform(1.0f, 0, 0, yscale, 0, centerY - centerY * yscale));
			Control.MoveTo(centerX, centerY);
			Control.AddArc(centerX, centerY, rect.Width / 2, CGConversions.DegreesToRadians(startAngle), CGConversions.DegreesToRadians(startAngle + sweepAngle), sweepAngle < 0);
			Control.AddLineToPoint(centerX, centerY);
			Control.ClosePath();
			Control.RestoreState();
			Control.Clip();
			brush.Draw(this, rect.ToEto());
			EndDrawing();
		}
Example #8
0
		public void DrawArc(Pen pen, float x, float y, float width, float height, float startAngle, float sweepAngle)
		{
			SetOffset(false);
			StartDrawing();

			var rect = new CGRect(x, y, width, height);
			pen.Apply(this);
			var yscale = rect.Height / rect.Width;
			var centerY = rect.GetMidY();
			var centerX = rect.GetMidX();
			Control.ConcatCTM(new CGAffineTransform(1.0f, 0, 0, yscale, 0, centerY - centerY * yscale));
			Control.AddArc(centerX, centerY, rect.Width / 2, CGConversions.DegreesToRadians(startAngle), CGConversions.DegreesToRadians(startAngle + sweepAngle), sweepAngle < 0);
			Control.StrokePath();
			EndDrawing();
		}
        private void CreateLayers(UIImage image)
        {
            if (image == null)
                return;

            Layer.Sublayers = new CALayer[0];

            var imageFrame = new CGRect(
                Frame.Width / 2f - Frame.Width / 4f,
                Frame.Height / 2f - Frame.Height / 4f,
                Frame.Width / 2f,
                Frame.Height / 2f);
            var imgCenterPoint = new CGPoint(imageFrame.GetMidX(), imageFrame.GetMidY());
            var lineFrame = new CGRect(
                imageFrame.X - imageFrame.Width / 4f,
                imageFrame.Y - imageFrame.Height / 4f,
                imageFrame.Width * 1.5f,
                imageFrame.Height * 1.5f);

            //===============
            // circle layer
            //===============
            circleShape = new CAShapeLayer();
            circleShape.Bounds = imageFrame;
            circleShape.Position = imgCenterPoint;
            circleShape.Path = UIBezierPath.FromOval(imageFrame).CGPath;
            circleShape.FillColor = circleColor.CGColor;
            circleShape.Transform = CATransform3D.MakeScale(0.0f, 0.0f, 1.0f);
            Layer.AddSublayer(circleShape);

            circleMaskShape = new CAShapeLayer();
            circleMaskShape.Bounds = imageFrame;
            circleMaskShape.Position = imgCenterPoint;
            circleMaskShape.FillRule = CAShapeLayer.FillRuleEvenOdd;
            circleShape.Mask = circleMaskShape;

            var maskPath = UIBezierPath.FromRect(imageFrame);
            maskPath.AddArc(imgCenterPoint, 0.1f, 0.0f, fPI * 2f, true);
            circleMaskShape.Path = maskPath.CGPath;

            //===============
            // line layer
            //===============
            lineShapes = new CAShapeLayer[5];
            for (int i = 0; i < 5; i++)
            {
                var line = new CAShapeLayer();
                line.Bounds = lineFrame;
                line.Position = imgCenterPoint;
                line.MasksToBounds = true;
                line.Actions = NSDictionary.FromObjectsAndKeys(
                    new[] { NSNull.Null, NSNull.Null },
                    new[] { (NSString)"strokeStart", (NSString)"strokeEnd" });
                line.StrokeColor = linesColor.CGColor;
                line.LineWidth = 1.25f;
                line.MiterLimit = 1.25f;
                var path = new CGPath();
                path.MoveToPoint(lineFrame.GetMidX(), lineFrame.GetMidY());
                path.AddLineToPoint(lineFrame.X + lineFrame.Width / 2f, lineFrame.Y);
                line.Path = path;
                line.LineCap = CAShapeLayer.CapRound;
                line.LineJoin = CAShapeLayer.JoinRound;
                line.StrokeStart = 0.0f;
                line.StrokeEnd = 0.0f;
                line.Opacity = 0.0f;
                line.Transform = CATransform3D.MakeRotation(fPI / 5f * (i * 2f + 1f), 0.0f, 0.0f, 1.0f);
                Layer.AddSublayer(line);
                lineShapes[i] = line;
            }

            //===============
            // image layer
            //===============
            imageShape = new CAShapeLayer();
            imageShape.Bounds = imageFrame;
            imageShape.Position = imgCenterPoint;
            imageShape.Path = UIBezierPath.FromRect(imageFrame).CGPath;
            imageShape.FillColor = Checked ? Color.CGColor : SkeletonColor.CGColor;
            imageShape.Actions = NSDictionary.FromObjectAndKey(NSNull.Null, (NSString)"fillColor");
            Layer.AddSublayer(imageShape);

            imageShape.Mask = new CALayer();
            imageShape.Mask.Contents = image.CGImage;
            imageShape.Mask.Bounds = imageFrame;
            imageShape.Mask.Position = imgCenterPoint;

            //==============================
            // circle transform animation
            //==============================
            circleTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f,  0.0f,  1.0f)),    //  0/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.5f,  0.5f,  1.0f)),    //  1/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.0f,  1.0f,  1.0f)),    //  2/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f,  1.2f,  1.0f)),    //  3/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.3f,  1.3f,  1.0f)),    //  4/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.37f, 1.37f, 1.0f)),    //  5/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f,  1.4f,  1.0f)),    //  6/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f,  1.4f,  1.0f))     // 10/10
            };
            circleTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/10
                NSNumber.FromDouble(0.1),    //  1/10
                NSNumber.FromDouble(0.2),    //  2/10
                NSNumber.FromDouble(0.3),    //  3/10
                NSNumber.FromDouble(0.4),    //  4/10
                NSNumber.FromDouble(0.5),    //  5/10
                NSNumber.FromDouble(0.6),    //  6/10
                NSNumber.FromDouble(1.0)     // 10/10
            };

            circleMaskTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.Identity),                                                                 //  0/10
                NSValue.FromCATransform3D(CATransform3D.Identity),                                                                 //  2/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 1.25f,  imageFrame.Height * 1.25f,  1.0f)),   //  3/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 2.688f, imageFrame.Height * 2.688f, 1.0f)),   //  4/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 3.923f, imageFrame.Height * 3.923f, 1.0f)),   //  5/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.375f, imageFrame.Height * 4.375f, 1.0f)),   //  6/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.731f, imageFrame.Height * 4.731f, 1.0f)),   //  7/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f,   imageFrame.Height * 5.0f,   1.0f)),   //  9/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f,   imageFrame.Height * 5.0f,   1.0f))    // 10/10
            };
            circleMaskTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/10
                NSNumber.FromDouble(0.2),    //  2/10
                NSNumber.FromDouble(0.3),    //  3/10
                NSNumber.FromDouble(0.4),    //  4/10
                NSNumber.FromDouble(0.5),    //  5/10
                NSNumber.FromDouble(0.6),    //  6/10
                NSNumber.FromDouble(0.7),    //  7/10
                NSNumber.FromDouble(0.9),    //  9/10
                NSNumber.FromDouble(1.0)     // 10/10
            };

            //==============================
            // line stroke animation
            //==============================
            lineStrokeStart.Values = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.0),    //  1/18
                NSNumber.FromDouble(0.18),   //  2/18
                NSNumber.FromDouble(0.2),    //  3/18
                NSNumber.FromDouble(0.26),   //  4/18
                NSNumber.FromDouble(0.32),   //  5/18
                NSNumber.FromDouble(0.4),    //  6/18
                NSNumber.FromDouble(0.6),    //  7/18
                NSNumber.FromDouble(0.71),   //  8/18
                NSNumber.FromDouble(0.89),   // 17/18
                NSNumber.FromDouble(0.92)    // 18/18
            };
            lineStrokeStart.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.056),  //  1/18
                NSNumber.FromDouble(0.111),  //  2/18
                NSNumber.FromDouble(0.167),  //  3/18
                NSNumber.FromDouble(0.222),  //  4/18
                NSNumber.FromDouble(0.278),  //  5/18
                NSNumber.FromDouble(0.333),  //  6/18
                NSNumber.FromDouble(0.389),  //  7/18
                NSNumber.FromDouble(0.444),  //  8/18
                NSNumber.FromDouble(0.944),  // 17/18
                NSNumber.FromDouble(1.0),    // 18/18
            };

            lineStrokeEnd.Values = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.0),    //  1/18
                NSNumber.FromDouble(0.32),   //  2/18
                NSNumber.FromDouble(0.48),   //  3/18
                NSNumber.FromDouble(0.64),   //  4/18
                NSNumber.FromDouble(0.68),   //  5/18
                NSNumber.FromDouble(0.92),   // 17/18
                NSNumber.FromDouble(0.92)    // 18/18
            };
            lineStrokeEnd.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.056),  //  1/18
                NSNumber.FromDouble(0.111),  //  2/18
                NSNumber.FromDouble(0.167),  //  3/18
                NSNumber.FromDouble(0.222),  //  4/18
                NSNumber.FromDouble(0.278),  //  5/18
                NSNumber.FromDouble(0.944),  // 17/18
                NSNumber.FromDouble(1.0),    // 18/18
            };

            lineOpacity.Values = new[]
            {
                NSNumber.FromDouble(1.0),    //  0/30
                NSNumber.FromDouble(1.0),    // 12/30
                NSNumber.FromDouble(0.0)     // 17/30
            };
            lineOpacity.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/30
                NSNumber.FromDouble(0.4),    // 12/30
                NSNumber.FromDouble(0.567)   // 17/30
            };

            //==============================
            // image transform animation
            //==============================
            imageTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f,   0.0f,   1.0f)),  //  0/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f,   0.0f,   1.0f)),  //  3/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f,   1.2f,   1.0f)),  //  9/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.25f,  1.25f,  1.0f)),  // 10/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f,   1.2f,   1.0f)),  // 11/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f,   0.9f,   1.0f)),  // 14/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)),  // 15/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)),  // 16/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f,   0.9f,   1.0f)),  // 17/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)),  // 20/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.025f, 1.025f, 1.0f)),  // 21/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)),  // 22/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f,  0.96f,  1.0f)),  // 25/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.95f,  0.95f,  1.0f)),  // 26/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f,  0.96f,  1.0f)),  // 27/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.99f,  0.99f,  1.0f)),  // 29/30
                NSValue.FromCATransform3D(CATransform3D.Identity)                          // 30/30
            };
            imageTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/30
                NSNumber.FromDouble(0.1),    //  3/30
                NSNumber.FromDouble(0.3),    //  9/30
                NSNumber.FromDouble(0.333),  // 10/30
                NSNumber.FromDouble(0.367),  // 11/30
                NSNumber.FromDouble(0.467),  // 14/30
                NSNumber.FromDouble(0.5),    // 15/30
                NSNumber.FromDouble(0.533),  // 16/30
                NSNumber.FromDouble(0.567),  // 17/30
                NSNumber.FromDouble(0.667),  // 20/30
                NSNumber.FromDouble(0.7),    // 21/30
                NSNumber.FromDouble(0.733),  // 22/30
                NSNumber.FromDouble(0.833),  // 25/30
                NSNumber.FromDouble(0.867),  // 26/30
                NSNumber.FromDouble(0.9),    // 27/30
                NSNumber.FromDouble(0.967),  // 29/30
                NSNumber.FromDouble(1.0)     // 30/30
            };

            // re-set the durations
            Duration = duration;
        }
Example #10
0
        private void CreateLayers(UIImage image)
        {
            if (image == null)
            {
                return;
            }

            Layer.Sublayers = new CALayer[0];

            var imageFrame = new CGRect(
                Frame.Width / 2f - Frame.Width / 4f,
                Frame.Height / 2f - Frame.Height / 4f,
                Frame.Width / 2f,
                Frame.Height / 2f);
            var imgCenterPoint = new CGPoint(imageFrame.GetMidX(), imageFrame.GetMidY());
            var lineFrame      = new CGRect(
                imageFrame.X - imageFrame.Width / 4f,
                imageFrame.Y - imageFrame.Height / 4f,
                imageFrame.Width * 1.5f,
                imageFrame.Height * 1.5f);

            //===============
            // circle layer
            //===============
            circleShape           = new CAShapeLayer();
            circleShape.Bounds    = imageFrame;
            circleShape.Position  = imgCenterPoint;
            circleShape.Path      = UIBezierPath.FromOval(imageFrame).CGPath;
            circleShape.FillColor = circleColor.CGColor;
            circleShape.Transform = CATransform3D.MakeScale(0.0f, 0.0f, 1.0f);
            Layer.AddSublayer(circleShape);

            circleMaskShape          = new CAShapeLayer();
            circleMaskShape.Bounds   = imageFrame;
            circleMaskShape.Position = imgCenterPoint;
            circleMaskShape.FillRule = CAShapeLayer.FillRuleEvenOdd;
            circleShape.Mask         = circleMaskShape;

            var maskPath = UIBezierPath.FromRect(imageFrame);

            maskPath.AddArc(imgCenterPoint, 0.1f, 0.0f, fPI * 2f, true);
            circleMaskShape.Path = maskPath.CGPath;

            //===============
            // line layer
            //===============
            lineShapes = new CAShapeLayer[5];
            for (int i = 0; i < 5; i++)
            {
                var line = new CAShapeLayer();
                line.Bounds        = lineFrame;
                line.Position      = imgCenterPoint;
                line.MasksToBounds = true;
                line.Actions       = NSDictionary.FromObjectsAndKeys(
                    new[] { NSNull.Null, NSNull.Null },
                    new[] { (NSString)"strokeStart", (NSString)"strokeEnd" });
                line.StrokeColor = linesColor.CGColor;
                line.LineWidth   = 1.25f;
                line.MiterLimit  = 1.25f;
                var path = new CGPath();
                path.MoveToPoint(lineFrame.GetMidX(), lineFrame.GetMidY());
                path.AddLineToPoint(lineFrame.X + lineFrame.Width / 2f, lineFrame.Y);
                line.Path        = path;
                line.LineCap     = CAShapeLayer.CapRound;
                line.LineJoin    = CAShapeLayer.JoinRound;
                line.StrokeStart = 0.0f;
                line.StrokeEnd   = 0.0f;
                line.Opacity     = 0.0f;
                line.Transform   = CATransform3D.MakeRotation(fPI / 5f * (i * 2f + 1f), 0.0f, 0.0f, 1.0f);
                Layer.AddSublayer(line);
                lineShapes[i] = line;
            }

            //===============
            // image layer
            //===============
            imageShape           = new CAShapeLayer();
            imageShape.Bounds    = imageFrame;
            imageShape.Position  = imgCenterPoint;
            imageShape.Path      = UIBezierPath.FromRect(imageFrame).CGPath;
            imageShape.FillColor = Checked ? Color.CGColor : SkeletonColor.CGColor;
            imageShape.Actions   = NSDictionary.FromObjectAndKey(NSNull.Null, (NSString)"fillColor");
            Layer.AddSublayer(imageShape);

            imageShape.Mask          = new CALayer();
            imageShape.Mask.Contents = image.CGImage;
            imageShape.Mask.Bounds   = imageFrame;
            imageShape.Mask.Position = imgCenterPoint;

            //==============================
            // circle transform animation
            //==============================
            circleTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)),      //  0/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.5f, 0.5f, 1.0f)),      //  1/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.0f, 1.0f, 1.0f)),      //  2/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)),      //  3/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.3f, 1.3f, 1.0f)),      //  4/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.37f, 1.37f, 1.0f)),    //  5/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f, 1.4f, 1.0f)),      //  6/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.4f, 1.4f, 1.0f))       // 10/10
            };
            circleTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/10
                NSNumber.FromDouble(0.1),    //  1/10
                NSNumber.FromDouble(0.2),    //  2/10
                NSNumber.FromDouble(0.3),    //  3/10
                NSNumber.FromDouble(0.4),    //  4/10
                NSNumber.FromDouble(0.5),    //  5/10
                NSNumber.FromDouble(0.6),    //  6/10
                NSNumber.FromDouble(1.0)     // 10/10
            };

            circleMaskTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.Identity),                                                                 //  0/10
                NSValue.FromCATransform3D(CATransform3D.Identity),                                                                 //  2/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 1.25f, imageFrame.Height * 1.25f, 1.0f)),     //  3/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 2.688f, imageFrame.Height * 2.688f, 1.0f)),   //  4/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 3.923f, imageFrame.Height * 3.923f, 1.0f)),   //  5/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.375f, imageFrame.Height * 4.375f, 1.0f)),   //  6/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 4.731f, imageFrame.Height * 4.731f, 1.0f)),   //  7/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f, imageFrame.Height * 5.0f, 1.0f)),       //  9/10
                NSValue.FromCATransform3D(CATransform3D.MakeScale(imageFrame.Width * 5.0f, imageFrame.Height * 5.0f, 1.0f))        // 10/10
            };
            circleMaskTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/10
                NSNumber.FromDouble(0.2),    //  2/10
                NSNumber.FromDouble(0.3),    //  3/10
                NSNumber.FromDouble(0.4),    //  4/10
                NSNumber.FromDouble(0.5),    //  5/10
                NSNumber.FromDouble(0.6),    //  6/10
                NSNumber.FromDouble(0.7),    //  7/10
                NSNumber.FromDouble(0.9),    //  9/10
                NSNumber.FromDouble(1.0)     // 10/10
            };

            //==============================
            // line stroke animation
            //==============================
            lineStrokeStart.Values = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.0),    //  1/18
                NSNumber.FromDouble(0.18),   //  2/18
                NSNumber.FromDouble(0.2),    //  3/18
                NSNumber.FromDouble(0.26),   //  4/18
                NSNumber.FromDouble(0.32),   //  5/18
                NSNumber.FromDouble(0.4),    //  6/18
                NSNumber.FromDouble(0.6),    //  7/18
                NSNumber.FromDouble(0.71),   //  8/18
                NSNumber.FromDouble(0.89),   // 17/18
                NSNumber.FromDouble(0.92)    // 18/18
            };
            lineStrokeStart.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.056),  //  1/18
                NSNumber.FromDouble(0.111),  //  2/18
                NSNumber.FromDouble(0.167),  //  3/18
                NSNumber.FromDouble(0.222),  //  4/18
                NSNumber.FromDouble(0.278),  //  5/18
                NSNumber.FromDouble(0.333),  //  6/18
                NSNumber.FromDouble(0.389),  //  7/18
                NSNumber.FromDouble(0.444),  //  8/18
                NSNumber.FromDouble(0.944),  // 17/18
                NSNumber.FromDouble(1.0),    // 18/18
            };

            lineStrokeEnd.Values = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.0),    //  1/18
                NSNumber.FromDouble(0.32),   //  2/18
                NSNumber.FromDouble(0.48),   //  3/18
                NSNumber.FromDouble(0.64),   //  4/18
                NSNumber.FromDouble(0.68),   //  5/18
                NSNumber.FromDouble(0.92),   // 17/18
                NSNumber.FromDouble(0.92)    // 18/18
            };
            lineStrokeEnd.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/18
                NSNumber.FromDouble(0.056),  //  1/18
                NSNumber.FromDouble(0.111),  //  2/18
                NSNumber.FromDouble(0.167),  //  3/18
                NSNumber.FromDouble(0.222),  //  4/18
                NSNumber.FromDouble(0.278),  //  5/18
                NSNumber.FromDouble(0.944),  // 17/18
                NSNumber.FromDouble(1.0),    // 18/18
            };

            lineOpacity.Values = new[]
            {
                NSNumber.FromDouble(1.0),    //  0/30
                NSNumber.FromDouble(1.0),    // 12/30
                NSNumber.FromDouble(0.0)     // 17/30
            };
            lineOpacity.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/30
                NSNumber.FromDouble(0.4),    // 12/30
                NSNumber.FromDouble(0.567)   // 17/30
            };

            //==============================
            // image transform animation
            //==============================
            imageTransform.Values = new[]
            {
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)),      //  0/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.0f, 0.0f, 1.0f)),      //  3/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)),      //  9/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.25f, 1.25f, 1.0f)),    // 10/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.2f, 1.2f, 1.0f)),      // 11/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f, 0.9f, 1.0f)),      // 14/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)),  // 15/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.875f, 0.875f, 1.0f)),  // 16/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.9f, 0.9f, 1.0f)),      // 17/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)),  // 20/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.025f, 1.025f, 1.0f)),  // 21/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(1.013f, 1.013f, 1.0f)),  // 22/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f, 0.96f, 1.0f)),    // 25/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.95f, 0.95f, 1.0f)),    // 26/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.96f, 0.96f, 1.0f)),    // 27/30
                NSValue.FromCATransform3D(CATransform3D.MakeScale(0.99f, 0.99f, 1.0f)),    // 29/30
                NSValue.FromCATransform3D(CATransform3D.Identity)                          // 30/30
            };
            imageTransform.KeyTimes = new[]
            {
                NSNumber.FromDouble(0.0),    //  0/30
                NSNumber.FromDouble(0.1),    //  3/30
                NSNumber.FromDouble(0.3),    //  9/30
                NSNumber.FromDouble(0.333),  // 10/30
                NSNumber.FromDouble(0.367),  // 11/30
                NSNumber.FromDouble(0.467),  // 14/30
                NSNumber.FromDouble(0.5),    // 15/30
                NSNumber.FromDouble(0.533),  // 16/30
                NSNumber.FromDouble(0.567),  // 17/30
                NSNumber.FromDouble(0.667),  // 20/30
                NSNumber.FromDouble(0.7),    // 21/30
                NSNumber.FromDouble(0.733),  // 22/30
                NSNumber.FromDouble(0.833),  // 25/30
                NSNumber.FromDouble(0.867),  // 26/30
                NSNumber.FromDouble(0.9),    // 27/30
                NSNumber.FromDouble(0.967),  // 29/30
                NSNumber.FromDouble(1.0)     // 30/30
            };

            // re-set the durations
            Duration = duration;
        }