简体   繁体   English

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

[英]How can I create an animation color change from center of a view in SwiftUI?

How can I create an animation color change from center of a view in SwiftUI?如何从 SwiftUI 的视图中心创建 animation 颜色变化? (please see the below gif)? (请看下面的gif)?

在此处输入图像描述

So far I have tried adding an animation modifier to the view (please see the below code), but am not quite sure how to make the animation start at the center of the screen and flow to the outer edges of the screen.到目前为止,我已经尝试将 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()
    }
} 

There is probably more elegant way of doing this but it works.这样做可能有更优雅的方式,但它有效。

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()
                    
                }
            })
        })
    }
    
}

You can use two Circle s in a ZStack and animate the scale effect value of the top most circle.您可以在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