circle 动画
如果你还记得小学几何知识,就应该了解勾股定理。 a^2 + b^2 = c^2

a 和 b 可以视为矩形的 高度 和 宽度 ,我们能够根据它们求得 c ,即覆盖整个矩形所需的圆的半径。我们以此为基础构建圆的 path,并使用 progress 变量随时间对它进行变换。
func circle(rect: CGRect) -> Path {
let a: CGFloat = rect.height / 2.0
let b: CGFloat = rect.width / 2.0
let c = pow(pow(a, 2) + pow(b, 2), 0.5) // a^2 + b^2 = c^2 --> Solved for 'c'
// c = radius of final circle
let radius = c * progress
// Build Circle Path
var path = Path()
path.addArc(center: CGPoint(x: rect.midX, y: rect.midY), radius: radius, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 360), clockwise: true)
return path
}
angle 动画
这个动画知识点有点多。你需要使用切线计算角度的斜率,然后根据这个斜率创建一条直线。在矩形上移动这条直线时,根据它来绘制一个直角三角形。参见下图,各种彩色的线表示该线随时间移动时,覆盖整个矩形的状态。

方法如下:
func angle(rect: CGRect, angle: Angle) -> Path {
var cAngle = Angle(degrees: angle.degrees.truncatingRemainder(dividingBy: 90))
// Return Path Using Other Animations (topToBottom, leftToRight, etc) if angle is 0, 90, 180, 270
if angle.degrees == 0 || cAngle.degrees == 0 { return leftToRight(rect: rect)}
else if angle.degrees == 90 || cAngle.degrees == 90 { return topToBottom(rect: rect)}
else if angle.degrees == 180 || cAngle.degrees == 180 { return rightToLeft(rect: rect)}
else if angle.degrees == 270 || cAngle.degrees == 270 { return bottomToTop(rect: rect)}
// Calculate Slope of Line and inverse slope
let m = CGFloat(tan(cAngle.radians))
let m_1 = pow(m, -1) * -1
let h = rect.height
let w = rect.width
// tan (angle) = slope of line
// y = mx + b ---> b = y - mx ~ 'b' = y intercept
let b = h - (m_1 * w) // b = y - (m * x)
// X and Y coordinate calculation
var x = b * m * progress
var y = b * progress
// Triangle Offset Calculation
let xOffset = (angle.degrees > 90 && angle.degrees < 270) ? rect.width : 0
let yOffset = (angle.degrees > 180 && angle.degrees < 360) ? rect.height : 0
// Modify which side the triangle is drawn from depending on the angle
if angle.degrees > 90 && angle.degrees < 180 { x *= -1 }
else if angle.degrees > 180 && angle.degrees < 270 { x *= -1; y *= -1 }
else if angle.degrees > 270 && angle.degrees < 360 { y *= -1 }
// Build Triangle Path
var path = Path()
path.move(to: CGPoint(x: xOffset, y: yOffset))
path.addLine(to: CGPoint(x: xOffset + x, y: yOffset))
path.addLine(to: CGPoint(x: xOffset, y: yOffset + y))
path.closeSubpath()
return path
}








