我使用CAKeyframeAnimation沿着CGPath爲箭頭設置動畫。除了當atan2
'從0翻轉'到2π或反之亦然時,箭頭沿着路徑。在這種情況下,箭頭在繼續之前完成360°旋轉。如何避免旋轉動畫在2π邊界處跳動?
是否有任何方法來計算我的CAKeyframeAnimation的值,使箭頭總是旋轉最小的數量,以得到它的去向?
let turnAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
turnAnimation.duration = 5
var values = [CGFloat]()
for i in 0..<points.count - 1 {
let point1 = points[i]
let point2 = points[i + 1]
let delta = point2 - point1
let value = atan2(delta.y, delta.x)
values.append(value)
}
turnAnimation.values = values
turnAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
turnAnimation.repeatCount = Float.greatestFiniteMagnitude
arrowPointLayer.transform = CATransform3DMakeRotation(values.first!, 0, 0, 1)
arrowPointLayer.add(turnAnimation, forKey: "rotateArrow")
編輯:更新基礎上的答案,但依然沒有完全工作:
let turnAnimation = CAKeyframeAnimation(keyPath: "transform.rotation")
turnAnimation.duration = 5
var rawValues = [CGFloat]()
var values = [CGFloat]()
for i in 0..<points.count - 1 {
let point1 = points[i]
let point2 = points[i + 1]
let delta = point2 - point1
let rawValue = atan2(delta.y, delta.x)
var value: CGFloat
if i == 0 {
value = 0 // we will apply this value from rawValues
} else {
let lastValue = rawValues.last!
value = rawValue - lastValue
}
if value < 0 {
value = .pi * 2 + value
}
rawValues.append(rawValue)
values.append(value)
}
for (i, p) in values.enumerated() {
print("\(rawValues[i]): \(p)")
}
turnAnimation.values = values
turnAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
turnAnimation.repeatCount = Float.greatestFiniteMagnitude
turnAnimation.isAdditive = true
arrowPointLayer.transform = CATransform3DMakeRotation(rawValues.first!, 0, 0, 1)
arrowPointLayer.add(turnAnimation, forKey: "rotateArrow")
嗨,再次 - 我突然發現,問題可能是使用''transform.rotation''作爲關鍵路徑。蘋果建議不要那樣做。 – matt
真的嗎?相反,只是「旋轉」? – buildsucceeded
只是變換。您可以使用值函數來指定z旋轉。 – matt