[英]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.