简体   繁体   中英

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? (please see the below 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.

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.

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]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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