对于大于 PI 的值,CAKeyFrameAnimation 不是线性的
CAKeyFrameAnimation not Linear for values greater than PI
我无法理解为什么动画没有按预期运行。
我正在做的是:
创建一个带圆弧的 UIBezierPath
以沿此路径移动标签并为路径描边设置动画。
//Start Point is -.pi /2 to let the Arc start at the top.
//self.progress = Value between 0.0 and 1.0
let path : UIBezierPath = UIBezierPath.init(arcCenter: CGPoint.init(x: self.bounds.width * 0.5, y: self.bounds.height * 0.5),
radius: self.bounds.width * 0.5, startAngle: -.pi / 2, endAngle: (2 * self.progress * .pi) - (.pi / 2), clockwise: true)
return path
将此路径添加到 CAShapeLayer
circlePathLayer.frame = bounds
circlePathLayer.path = self.path.cgPath
circlePathLayer.strokeStart = 0
circlePathLayer.strokeEnd = 1
使用 CABasicAnimation
为 strokeEnd 属性 设置动画
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.repeatCount = HUGE
animation.fromValue = 0.0
animation.toValue = 1.0
animation.duration = self.animationDuration
animation.isRemovedOnCompletion = false
animation.fillMode = kCAFillModeBoth
使用 CAKeyFrameAnimation
为标签的位置 属性 设置动画
let animationScore = CAKeyframeAnimation(keyPath: "position")
//some things I tried to fix
//animationScore.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.250, 0.250, 0.750, 0.750)]
//animationScore.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear)
animationScore.path = self.path.cgPath
animationScore.duration = self.animationDuration
animationScore.isRemovedOnCompletion = false
animationScore.fillMode = kCAFillModeBoth
animationScore.repeatCount = HUGE
将我的动画添加到图层和标签
self.circlePathLayer.add(animation, forKey: nil)
self.scoreLabel.layer.add(animationScore, forKey: nil)
我的问题: 对于大于 0.75 的 ProgressValues,我的标签没有以线性速度移动。大于 0.75 的值表示我的弧度大于 PI。
对于小于 0.75 的值,我的动画效果很好,label 和 strokeend 具有相同的速度并且彼此重叠。
动图:
请忽略此 gif 中标签中的 100%,我的进度值为 0.76。
你看到我的标签在四分之三圈后变慢了。
我希望有人能帮助我。
非常感谢
关键帧动画引入了不必要的复杂化。简单地围绕中心旋转标签,持续时间与形状图层的描边动画相同:
(很抱歉我的动画是从底部开始的,不是顶部,但是我写代码的时候没有看你的问题,现在懒得改了!)
那么,这是怎么做到的?这是三个动画,都具有相同的持续时间:
形状层的strokeEnd
,喜欢你的动画。
一个"arm"运行穿过圆心,标签作为子图层在一端(这样标签就出现在圆的半径处) .手臂做旋转变换动画
标签做一个反方向的旋转变换动画。如果没有,它将与其上层一起旋转。 (想想摩天轮是如何工作的;你的椅子在扶手的末端,但它相对于地球保持直立。)
这是完整的动画代码:
let anim = CABasicAnimation(keyPath: "transform.rotation.z")
anim.fromValue = 0
anim.toValue = 5
anim.duration = 10
self.arm.layer.add(anim, forKey:nil)
let anim2 = CABasicAnimation(keyPath: "transform.rotation.z")
anim2.fromValue = 0
anim2.toValue = -5
anim2.duration = 10
self.lab.layer.add(anim2, forKey:nil)
let anim3 = CABasicAnimation(keyPath: "strokeEnd")
anim3.fromValue = 0
anim3.toValue = 1
anim3.duration = 10
self.shape.add(anim3, forKey:nil)
我无法理解为什么动画没有按预期运行。 我正在做的是:
创建一个带圆弧的
UIBezierPath
以沿此路径移动标签并为路径描边设置动画。//Start Point is -.pi /2 to let the Arc start at the top. //self.progress = Value between 0.0 and 1.0 let path : UIBezierPath = UIBezierPath.init(arcCenter: CGPoint.init(x: self.bounds.width * 0.5, y: self.bounds.height * 0.5), radius: self.bounds.width * 0.5, startAngle: -.pi / 2, endAngle: (2 * self.progress * .pi) - (.pi / 2), clockwise: true) return path
将此路径添加到
CAShapeLayer
circlePathLayer.frame = bounds circlePathLayer.path = self.path.cgPath circlePathLayer.strokeStart = 0 circlePathLayer.strokeEnd = 1
使用
为 strokeEnd 属性 设置动画CABasicAnimation
let animation = CABasicAnimation(keyPath: "strokeEnd") animation.repeatCount = HUGE animation.fromValue = 0.0 animation.toValue = 1.0 animation.duration = self.animationDuration animation.isRemovedOnCompletion = false animation.fillMode = kCAFillModeBoth
使用
为标签的位置 属性 设置动画CAKeyFrameAnimation
let animationScore = CAKeyframeAnimation(keyPath: "position") //some things I tried to fix //animationScore.timingFunctions = [CAMediaTimingFunction(controlPoints: 0.250, 0.250, 0.750, 0.750)] //animationScore.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionLinear) animationScore.path = self.path.cgPath animationScore.duration = self.animationDuration animationScore.isRemovedOnCompletion = false animationScore.fillMode = kCAFillModeBoth animationScore.repeatCount = HUGE
将我的动画添加到图层和标签
self.circlePathLayer.add(animation, forKey: nil) self.scoreLabel.layer.add(animationScore, forKey: nil)
我的问题: 对于大于 0.75 的 ProgressValues,我的标签没有以线性速度移动。大于 0.75 的值表示我的弧度大于 PI。 对于小于 0.75 的值,我的动画效果很好,label 和 strokeend 具有相同的速度并且彼此重叠。
动图:
请忽略此 gif 中标签中的 100%,我的进度值为 0.76。
你看到我的标签在四分之三圈后变慢了。
我希望有人能帮助我。 非常感谢
关键帧动画引入了不必要的复杂化。简单地围绕中心旋转标签,持续时间与形状图层的描边动画相同:
(很抱歉我的动画是从底部开始的,不是顶部,但是我写代码的时候没有看你的问题,现在懒得改了!)
那么,这是怎么做到的?这是三个动画,都具有相同的持续时间:
形状层的
strokeEnd
,喜欢你的动画。一个"arm"运行穿过圆心,标签作为子图层在一端(这样标签就出现在圆的半径处) .手臂做旋转变换动画
标签做一个反方向的旋转变换动画。如果没有,它将与其上层一起旋转。 (想想摩天轮是如何工作的;你的椅子在扶手的末端,但它相对于地球保持直立。)
这是完整的动画代码:
let anim = CABasicAnimation(keyPath: "transform.rotation.z")
anim.fromValue = 0
anim.toValue = 5
anim.duration = 10
self.arm.layer.add(anim, forKey:nil)
let anim2 = CABasicAnimation(keyPath: "transform.rotation.z")
anim2.fromValue = 0
anim2.toValue = -5
anim2.duration = 10
self.lab.layer.add(anim2, forKey:nil)
let anim3 = CABasicAnimation(keyPath: "strokeEnd")
anim3.fromValue = 0
anim3.toValue = 1
anim3.duration = 10
self.shape.add(anim3, forKey:nil)