[英]How can I create an animation color change from center of a view in SwiftUI?
如何從 SwiftUI 的視圖中心創建 animation 顏色變化? (請看下面的gif)?
到目前為止,我已經嘗試將 animation 修改器添加到視圖中(請參見下面的代碼),但不太確定如何使 animation 從屏幕中心開始並流到屏幕的外邊緣。
import SwiftUI
struct ContentView: View {
@State var color = Color.red
var body: some View {
VStack {
Button(action: {
color = .green
}, label: {
Text("change background color")
})
}
.frame(maxWidth: .infinity)
.frame(maxHeight: .infinity)
.background(color)
.animation(.default)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
這樣做可能有更優雅的方式,但它有效。
struct AnimatedBackground: View {
@State var circleColor = Color.red
@State var height:CGFloat = 0
@State var backgroundColor: Color = .clear
@State var animation: Animation? = .default
var body: some View {
ZStack{
backgroundColor.ignoresSafeArea()
Circle()
.foregroundColor(circleColor)
.scaleEffect(CGSize(width: height, height: height))
VStack {
Button(action: {
animation = .default
circleColor = [Color.red, Color.orange, Color.green, Color.black, Color.gray, Color.white].randomElement()!
}, label: {
Text("change background color")
})
}
}.animation(animation)
.onChange(of: circleColor, perform: { value in
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true, block: {timer in
height += 0.2
if height >= 3{
animation = nil
backgroundColor = circleColor
height = 0
timer.invalidate()
}
})
})
}
}
您可以在ZStack
中使用兩個Circle
並為最上面的圓圈的縮放效果值設置動畫。
struct ContentView: View {
private let colors: [Color] = [.red, .yellow, .blue, .pink, .orange]
private let maxScaleEffect: CGFloat = 4.0
private let minScaleEffect: CGFloat = 0
private let animationDuration = 0.6
private let animationDelay = 0.1
@State private var shouldTransition = true
@State private var colorIndex = 0
var body: some View {
ZStack {
Circle()
.fill(previousColor)
.scaleEffect(maxScaleEffect)
Circle()
.fill(transitioningColor)
.scaleEffect(shouldTransition ? maxScaleEffect : minScaleEffect)
Button("Change color") {
shouldTransition = false
colorIndex += 1
// Removing DispatchQueue here will cause the first transition not to work
DispatchQueue.main.asyncAfter(deadline: .now() + animationDelay) {
withAnimation(.easeInOut(duration: animationDuration)) {
shouldTransition = true
}
}
}
.foregroundColor(.primary)
}
}
private var previousColor: Color {
colors[colorIndex%colors.count]
}
private var transitioningColor: Color {
colors[(colorIndex+1)%colors.count]
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.