UIBezierPath 从圆形到圆角正方形的动画
UIBezierPath animation from circle to rounded square
我正在尝试从圆形到带圆角的正方形制作动画。据我了解,对于流畅的动画,两条路径的点数应该相等。所以我写了一个基于多条弧构建圆的函数:
private func circleShape(segmentNumber: Int = 8, radius: CGFloat = 32) -> CGPath {
let center = self.bounds.center
let circlePath = UIBezierPath()
let segmentAngle = CGFloat.pi * CGFloat(2) / CGFloat(segmentNumber)
var currentAngle: CGFloat = 0
for _ in 0 ..< segmentNumber {
let nextAngle = currentAngle + segmentAngle
circlePath.addArc(withCenter: center, radius: radius,
startAngle: currentAngle, endAngle: nextAngle, clockwise: true)
currentAngle = nextAngle
}
circlePath.close()
return circlePath.cgPath
}
我正在用 getPathElementsPointsAndTypes() 检查点数,它与段数不成比例地增加(段数:1,点数:13;sN:2,p:14;sN:3,p:21; SN:4,P:16)。所以我找不到一个 segmentNumber
可以给出与绘制正方形的函数相同的点数 (19):
private func squareShape(size: CGFloat = 44, radius: CGFloat = 8) -> CGPath {
let rect = CGRect(center: self.bounds.center, size: CGSize(width: size, height: size))
let left = CGFloat.pi
let up = CGFloat(1.5) * CGFloat.pi
let down = CGFloat.pi / CGFloat(2)
let right = CGFloat(0.0)
let squarePath = UIBezierPath()
squarePath.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.minY + radius), radius: radius, startAngle: left, endAngle: up, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.maxX - radius, y: rect.minY + radius), radius: radius, startAngle: up, endAngle: right, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.maxX - radius, y: rect.maxY - radius), radius: radius, startAngle: right, endAngle: down, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.maxY - radius), radius: radius, startAngle: down, endAngle: left, clockwise: true)
squarePath.close()
return squarePath.cgPath
}
动画代码:
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 2
animation.toValue = self.circleShape()
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
self.testLayer.add(animation, forKey: "pathAnimation")
结果:
我可以更改什么以使动画与 example 中的动画一样平滑而没有圆角矩形?
你可以有两条路径
func circlePath () -> UIBezierPath {
return UIBezierPath(roundedRect: CGRect(x:0, y:0, width:50, height:50), cornerRadius: 25)
}
func squarePath () -> UIBezierPath {
return UIBezierPath(roundedRect: CGRect(x:0, y:0, width:30, height:30), cornerRadius: 4)
}
我正在尝试从圆形到带圆角的正方形制作动画。据我了解,对于流畅的动画,两条路径的点数应该相等。所以我写了一个基于多条弧构建圆的函数:
private func circleShape(segmentNumber: Int = 8, radius: CGFloat = 32) -> CGPath {
let center = self.bounds.center
let circlePath = UIBezierPath()
let segmentAngle = CGFloat.pi * CGFloat(2) / CGFloat(segmentNumber)
var currentAngle: CGFloat = 0
for _ in 0 ..< segmentNumber {
let nextAngle = currentAngle + segmentAngle
circlePath.addArc(withCenter: center, radius: radius,
startAngle: currentAngle, endAngle: nextAngle, clockwise: true)
currentAngle = nextAngle
}
circlePath.close()
return circlePath.cgPath
}
我正在用 getPathElementsPointsAndTypes() 检查点数,它与段数不成比例地增加(段数:1,点数:13;sN:2,p:14;sN:3,p:21; SN:4,P:16)。所以我找不到一个 segmentNumber
可以给出与绘制正方形的函数相同的点数 (19):
private func squareShape(size: CGFloat = 44, radius: CGFloat = 8) -> CGPath {
let rect = CGRect(center: self.bounds.center, size: CGSize(width: size, height: size))
let left = CGFloat.pi
let up = CGFloat(1.5) * CGFloat.pi
let down = CGFloat.pi / CGFloat(2)
let right = CGFloat(0.0)
let squarePath = UIBezierPath()
squarePath.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.minY + radius), radius: radius, startAngle: left, endAngle: up, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.maxX - radius, y: rect.minY + radius), radius: radius, startAngle: up, endAngle: right, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.maxX - radius, y: rect.maxY - radius), radius: radius, startAngle: right, endAngle: down, clockwise: true)
squarePath.addArc(withCenter: CGPoint(x: rect.minX + radius, y: rect.maxY - radius), radius: radius, startAngle: down, endAngle: left, clockwise: true)
squarePath.close()
return squarePath.cgPath
}
动画代码:
let animation = CABasicAnimation(keyPath: "path")
animation.duration = 2
animation.toValue = self.circleShape()
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
self.testLayer.add(animation, forKey: "pathAnimation")
结果:
我可以更改什么以使动画与 example 中的动画一样平滑而没有圆角矩形?
你可以有两条路径
func circlePath () -> UIBezierPath {
return UIBezierPath(roundedRect: CGRect(x:0, y:0, width:50, height:50), cornerRadius: 25)
}
func squarePath () -> UIBezierPath {
return UIBezierPath(roundedRect: CGRect(x:0, y:0, width:30, height:30), cornerRadius: 4)
}