最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

swift - Want to change (Via Animation) MeshGradient and background Colour once the user selects a colour - Stack Overflow

programmeradmin0浏览0评论

I have created a background using mesh gradient and animation. I want it animate only when a variable value (colour selected by user) changes to the new state and colour. The reason I am not using the switch statement with different points and colours is that it instantly changes to the next state, I want it to animate to next position. So that it looks like when a user selected a colour the background changed and moved to a different state. I tried a few solutions available online but nothing seems to work.

struct AnimatedMeshGradient: View {
    @State var appear = false
    @State var appear2 = false
    var matrix1: [[Double]] = []
    let colour = "red"
    var body: some View {
        ZStack {

            MeshGradient(
                width: 3,
                height: 3,
                points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
                         [0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
                         [0.0, 1.0], appear ? [1.5, 1.0] : [0.8, 0.8], [1.0, 1.0]
                        ],
                colors: [
                    .purple, .purple, .white,
                    .purple, .white, .purple,
                    .purple, .purple, .purple
                ])
            .onAppear() {
                withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
                    appear.toggle()
                }
            }

        }
    }
}

#Preview {
    AnimatedMeshGradient()
        .ignoresSafeArea()
}

Currently with this code it is animating back and forth to two positions that I want but I want it to only change when a variable value is changed. Very similar to selecting a colour and it changing the background to the newly selected colour.

I have created a background using mesh gradient and animation. I want it animate only when a variable value (colour selected by user) changes to the new state and colour. The reason I am not using the switch statement with different points and colours is that it instantly changes to the next state, I want it to animate to next position. So that it looks like when a user selected a colour the background changed and moved to a different state. I tried a few solutions available online but nothing seems to work.

struct AnimatedMeshGradient: View {
    @State var appear = false
    @State var appear2 = false
    var matrix1: [[Double]] = []
    let colour = "red"
    var body: some View {
        ZStack {

            MeshGradient(
                width: 3,
                height: 3,
                points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
                         [0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
                         [0.0, 1.0], appear ? [1.5, 1.0] : [0.8, 0.8], [1.0, 1.0]
                        ],
                colors: [
                    .purple, .purple, .white,
                    .purple, .white, .purple,
                    .purple, .purple, .purple
                ])
            .onAppear() {
                withAnimation(.easeInOut(duration: 5).repeatForever(autoreverses: true)) {
                    appear.toggle()
                }
            }

        }
    }
}

#Preview {
    AnimatedMeshGradient()
        .ignoresSafeArea()
}

Currently with this code it is animating back and forth to two positions that I want but I want it to only change when a variable value is changed. Very similar to selecting a colour and it changing the background to the newly selected colour.

Share Improve this question edited Jan 29 at 9:59 Benzy Neez 23.9k3 gold badges15 silver badges45 bronze badges asked Jan 29 at 7:21 Gurpreet Singh BhatiaGurpreet Singh Bhatia 12 bronze badges 1
  • Your example code shows the gradient moving between two positions, always purple. The properties appear2 and colour are not being used. What is it you actually want to see? In particular, is it moving correctly, but not changing color correctly? If so, why not make the color dependent on the appear flag too? It would be good if you could provide an actual example of how it is not working correctly when a value changes. – Benzy Neez Commented Jan 29 at 9:42
Add a comment  | 

1 Answer 1

Reset to default 0

Your example code shows the gradient moving between two positions, always purple. The properties appear2, matrix1 and colour are not being used.

Would I be right in thinking that you only want to see the gradient moving when the color is also changing? This change will be triggered by the user.

If you are only using two different colors then you could derive the color from the flag being toggled. Something like:

private var colour: Color {
    appear ? .blue : .purple
}
MeshGradient(
    width: 3,
    height: 3,
    points: // ... as before,
    colors: [
        colour, colour, .white,
        colour, .white, colour,
        colour, colour, colour
    ])
.onTapGesture {
    withAnimation(.easeInOut(duration: 5)) {
        appear.toggle()
    }
}

A more elaborate solution would be to allow the color for the gradient to be passed in as a parameter. Then, every time the color changes, the gradient should switch position. An .onChange callback can be used to detect the change and perform the switch.

Btw, you may have noticed that the animation was blinking before it repeated. This was being caused by the white area briefly disappearing and then appearing again at the end/start of an animation. You can prevent it from happening by changing one of the matrix parameters from 1.0 to 0.99:

struct AnimatedMeshGradient: View {
    @State var appear = false
    // @State var appear2 = false
    // var matrix1: [[Double]] = []
    let colour: Color

    var body: some View {
        MeshGradient(
            width: 3,
            height: 3,
            points: [[0.0, 0.0], appear ? [1.0, 0.0] : [0.5, 0.0], [1.0, 0.0],
                     [0.0, 0.5], appear ? [0.8, 0.2] : [0.1, 0.5], [1.0, -0.5],
                     [0.0, 1.0], appear ? [1.5, 0.99] : [0.8, 0.8], [1.0, 1.0] // 

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论