Welkin's Secret Garden

Imitation of Zhihu Daily's Launch Animation

First show the effect as usual.

This animation is brief, thus is easy to implement. It includes simply two points.

1. Draw the Animation Motion Trail with UIBezierPath

1
2
3
4
5
6
7
8
let logoPath = UIBezierPath(arcCenter: centerPoint, radius: frame.width / 3, startAngle: CGFloat(M_PI_2), endAngle: 0, clockwise: true)

let logoLayer = CAShapeLayer()
logoLayer.fillColor = UIColor(red: 5 / 255.0, green: 178 / 255.0, blue: 238 / 255.0, alpha: 1).cgColor
logoLayer.strokeColor = UIColor.white.cgColor
logoLayer.lineWidth = frame.width / 10;
logoLayer.path = logoPath.cgPath
layer.addSublayer(logoLayer)

strokeColor : The color of the path, that is, the motion trail’s color.

fillColor : The color of the layer that wrapped by path. In this case, it is the middle part of the circle. So the color out of the circle need to be set with superView.backgroundColor.

1
backgroundColor = UIColor(red: 5 / 255.0, green: 178 / 255.0, blue: 238 / 255.0, alpha: 1)

Move it! With the help of Core Animation, it is easy to modify the trail from 0% to 100%.

1
2
3
4
5
let pathAnimation = CABasicAnimation(keyPath: "strokeEnd")
pathAnimation.fromValue = 0
pathAnimation.toValue = 1
pathAnimation.duration = 1
logoLayer.add(pathAnimation, forKey: "pathAnimation")

The first step is finished.

What is missing? Oh, the border of the trail shoud be arc. Why not add a litter ball to each side of the trail.

2. Place Balls to Trail’s Edge

Place two balls:

1
2
3
4
5
6
7
8
9
10
11
let beginPointView = UIView()
beginPointView.backgroundColor = UIColor.white
beginPointView.bounds = CGRect(x: 0, y: 0, width: logoLayer.lineWidth, height: logoLayer.lineWidth)
beginPointView.center = CGPoint(x: frame.width / 2, y: frame.width / 2 + frame.width / 3)
beginPointView.layer.cornerRadius = beginPointView.bounds.width / 2;
addSubview(beginPointView)

let endPointView = UIView(frame: beginPointView.frame)
endPointView.backgroundColor = UIColor.white
endPointView.layer.cornerRadius = endPointView.bounds.width / 2;
addSubview(endPointView)

Move them on the track like step 1:

1
2
3
4
5
6
let pointAnimation = CAKeyframeAnimation(keyPath: "position")
pointAnimation.duration = 1
pointAnimation.isRemovedOnCompletion = false
pointAnimation.fillMode = kCAFillModeForwards
pointAnimation.path = logoPath.cgPath
endPointView.layer.add(pointAnimation, forKey: "pointAnimation")

Setting the path property of CAKeyframeAnimation and it will ignore the key frame of the animation and move on the path with constant speed automatically

To show what is actually done at this step.

Well, simply combine the two steps and it is what we need.