[英]Make gradient view animation colors swirl in one direction in SwiftUI
所以我有一個線性漸變視圖,我有.animation()
修飾符的顏色動畫。 現在,當我調整漸變的start
和end
並使用.easeInAndOut()
修飾符進行動畫處理時,顏色會來回旋轉。 我希望顏色在一個方向上旋轉,順時針,重復,但它來回旋轉。
struct AnimatedBackground: View {
@State var start = UnitPoint.leading
@State var end = UnitPoint.trailing
let timer = Timer.publish(every: 1, on: .main, in: .default).autoconnect()
let colors: [Color] = [ .blue, .red ]
var body: some View {
LinearGradient(gradient: Gradient(colors: colors), startPoint: start, endPoint: end)
.animation(Animation.easeInOut(duration: 3).repeatForever())
.onReceive(timer, perform: { _ in
self.start = .topLeading
self.end = .bottomTrailing
self.start = .bottom
self.end = .top
self.start = .bottomLeading
self.end = .topTrailing
self.start = .leading
self.end = .trailing
self.start = .topLeading
self.end = .bottomTrailing
self.start = .top
self.end = .bottom
self.start = .bottomLeading
self.end = .topTrailing
self.start = .leading
self.end = .trailing
}).edgesIgnoringSafeArea(.all)
}
}
漸變顏色來回旋轉。 我希望顏色以順時針方向旋轉,平滑且重復。
讓我們調試! 首先,在大量self.start = ...
之前和之后,嘗試添加print
語句。
print("Before: \(start), \(end)")
self.start = .topLeading
self.end = .bottomTrailing
self.start = .bottom
self.end = .top
self.start = .bottomLeading
self.end = .topTrailing
self.start = .leading
self.end = .trailing
self.start = .topLeading
self.end = .bottomTrailing
self.start = .top
self.end = .bottom
self.start = .bottomLeading
self.end = .topTrailing
self.start = .leading
self.end = .trailing
print("After: \(start), \(end)")
您會注意到兩個print
幾乎同時發生。
之前:UnitPoint(x: 0.0, y: 0.5), UnitPoint(x: 1.0, y: 0.5)
之后:UnitPoint(x: 0.0, y: 0.5), UnitPoint(x: 1.0, y: 0.5)
這是因為 Swift 代碼在極短的時間內一行接一行地立即執行。 結果, start
總是變成(x: 0.0, y: 0.5)
( .leading
),而end
總是變成(x: 1.0, y: 0.5)
( .trailing
)。 你的漸變可能根本沒有動畫!
要修復,您應該簡單地獲取start
和end
的當前值,然后手動計算下一個值。
struct AnimatedBackground: View {
@State var start = UnitPoint.leading
@State var end = UnitPoint.trailing
let timer = Timer.publish(every: 1, on: .main, in: .default).autoconnect()
let colors: [Color] = [.blue, .red]
var body: some View {
LinearGradient(gradient: Gradient(colors: colors), startPoint: start, endPoint: end)
.animation(Animation.easeInOut(duration: 3).repeatForever(), value: start) /// don't forget the `value`!
.onReceive(timer) { _ in
self.start = nextPointFrom(self.start)
self.end = nextPointFrom(self.end)
}
.edgesIgnoringSafeArea(.all)
}
/// cycle to the next point
func nextPointFrom(_ currentPoint: UnitPoint) -> UnitPoint {
switch currentPoint {
case .top:
return .topLeading
case .topLeading:
return .leading
case .leading:
return .bottomLeading
case .bottomLeading:
return .bottom
case .bottom:
return .bottomTrailing
case .bottomTrailing:
return .trailing
case .trailing:
return .topTrailing
case .topTrailing:
return .top
default:
print("Unknown point")
return .top
}
}
}
結果:
注意:要獲得更流暢的動畫,請查看rotationEffect
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.