繁体   English   中英

如何从 SwiftUI 的视图中心创建 animation 颜色变化?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM