在两个圆形 UIBezierPaths 之间设置动画时的奇怪行为
Strange behaviour when animating between two circular UIBezierPaths
问题
我正在创建爆炸环效果。我正在使用多个 CAShapeLayer
并为每一层创建一个 UIBezierPath
。初始化视图时,所有层都有一条宽度为 0
的路径。触发动作时,环会动画到更大的路径。
如下面的演示所示,每个图层的右手边的动画效果比每个圆形图层的其余部分慢。
演示
代码
绘制图层:
func draw(inView view: UIView) -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
// size.width defaults to 0
let circlePath = UIBezierPath(arcCenter: view.center, radius: size.width / 2, startAngle: 0, endAngle: CGFloat(360.0).toRadians(), clockwise: true)
shapeLayer.path = circlePath.CGPath
shapeLayer.frame = view.frame
return shapeLayer
}
更新图层
func updateAnimated(updatedOpacity: CGFloat, updatedSize: CGSize, duration: CGFloat) {
let updatePath = UIBezierPath(arcCenter: view.center, radius: updatedSize.width / 2,
startAngle: 0, endAngle: CGFloat(360).toRadians(), clockwise: true)
let pathAnimation = CABasicAnimation(keyPath: "path")
pathAnimation.fromValue = layer.path // the current path (initially with width 0)
pathAnimation.toValue = updatePath.CGPath
let opacityAnimation = CABasicAnimation(keyPath: "opacity")
opacityAnimation.fromValue = self.opacity
opacityAnimation.toValue = updatedOpacity
let animationGroup = CAAnimationGroup()
animationGroup.animations = [pathAnimation, opacityAnimation]
animationGroup.duration = Double(duration)
animationGroup.fillMode = kCAFillModeForwards
animationGroup.removedOnCompletion = false
layer.addAnimation(animationGroup, forKey: "shape_update")
... update variables ...
}
避免从路径宽度 0 开始。从 0 开始缩放非常困难,微小的浮点误差会放大。非常接近零的值在浮点数中不是很连续(嗯……我想这实际上有点像真实的宇宙)。尝试从较大的值开始,看看您可以安全地接近零。
问题
我正在创建爆炸环效果。我正在使用多个 CAShapeLayer
并为每一层创建一个 UIBezierPath
。初始化视图时,所有层都有一条宽度为 0
的路径。触发动作时,环会动画到更大的路径。
如下面的演示所示,每个图层的右手边的动画效果比每个圆形图层的其余部分慢。
演示
代码
绘制图层:
func draw(inView view: UIView) -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
// size.width defaults to 0
let circlePath = UIBezierPath(arcCenter: view.center, radius: size.width / 2, startAngle: 0, endAngle: CGFloat(360.0).toRadians(), clockwise: true)
shapeLayer.path = circlePath.CGPath
shapeLayer.frame = view.frame
return shapeLayer
}
更新图层
func updateAnimated(updatedOpacity: CGFloat, updatedSize: CGSize, duration: CGFloat) {
let updatePath = UIBezierPath(arcCenter: view.center, radius: updatedSize.width / 2,
startAngle: 0, endAngle: CGFloat(360).toRadians(), clockwise: true)
let pathAnimation = CABasicAnimation(keyPath: "path")
pathAnimation.fromValue = layer.path // the current path (initially with width 0)
pathAnimation.toValue = updatePath.CGPath
let opacityAnimation = CABasicAnimation(keyPath: "opacity")
opacityAnimation.fromValue = self.opacity
opacityAnimation.toValue = updatedOpacity
let animationGroup = CAAnimationGroup()
animationGroup.animations = [pathAnimation, opacityAnimation]
animationGroup.duration = Double(duration)
animationGroup.fillMode = kCAFillModeForwards
animationGroup.removedOnCompletion = false
layer.addAnimation(animationGroup, forKey: "shape_update")
... update variables ...
}
避免从路径宽度 0 开始。从 0 开始缩放非常困难,微小的浮点误差会放大。非常接近零的值在浮点数中不是很连续(嗯……我想这实际上有点像真实的宇宙)。尝试从较大的值开始,看看您可以安全地接近零。