简体   繁体   中英

Created path in SwiftUI doesn't animate

I am new in animating paths in SwiftUI. I tried to find an answer online but I couldn't find any solutions.

Here you have a video of a screen. I would love to have smooth animated background. I hope that you are gonna be able to help me. Link: https://youtu.be/OBePXXxboZ8

Thank you so much for your help.

struct HomeView: View {
@State var index = true
@State var indexBattery = true
@State var batteryAnimationUp = 340
@State var batteryAnimationDown = 260
var body: some View {

    ZStack {
        Back(batteryAnimationUp: batteryAnimationUp, batteryAnimationDown: batteryAnimationDown)
        .offset(x: 0, y: 100)
            .onTapGesture {
                self.indexBattery.toggle()
                withAnimation(.linear(duration: 3)) {
                    if self.indexBattery{
                        self.batteryAnimationUp = 340
                        self.batteryAnimationDown = 260
                    } else {
                        self.batteryAnimationUp = 260
                        self.batteryAnimationDown = 340
                    }
                }
        }
        
        VStack {
            Image("Powered_logo")
                .resizable()
                .frame(width: 150, height: 150)
                
            HStack {
                if self.index {
                    LoginAllView(index: $index)
                        .transition(.moveAndFade)
                } else {
                    RegisterAllView(index: $index)
                        .transition(.moveAndFade)
                }
                
            }
        }
        
    }
}

}

struct Back: View {
var batteryAnimationUp: Int
var batteryAnimationDown: Int
public var animatableData: AnimatablePair<Double, Double>{
    get{ AnimatablePair(Double(batteryAnimationUp), Double(batteryAnimationDown))}
    set{
        self.batteryAnimationUp = Int(newValue.first)
        self.batteryAnimationDown = Int(newValue.second)
    }
}
var body: some View{
    ZStack {
        Path { path in
            path.move(to: CGPoint(x: 0, y: 300))
            path.addQuadCurve(to: CGPoint(x: 100, y: 300), control: CGPoint(x: 50, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 200, y: 300), control: CGPoint(x: 150, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 300, y: 300), control: CGPoint(x: 250, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 400, y: 300), control: CGPoint(x: 350, y: batteryAnimationDown))

            path.addLine(to: CGPoint(x: 400, y: 1000))
            path.addLine(to: CGPoint(x: 0, y: 1000))
            path.closeSubpath()
        }
        .fill(Color("Green2"))
        Path { path in
            path.move(to: CGPoint(x: 0, y: 300))
            path.addQuadCurve(to: CGPoint(x: 100, y: 300), control: CGPoint(x: 50, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 200, y: 300), control: CGPoint(x: 150, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 300, y: 300), control: CGPoint(x: 250, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 400, y: 300), control: CGPoint(x: 350, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 500, y: 300), control: CGPoint(x: 450, y: batteryAnimationUp))

            path.addLine(to: CGPoint(x: 400, y: 1000))
            path.addLine(to: CGPoint(x: 0, y: 1000))
            path.closeSubpath()
        }
        .fill(Color("Color"))
        .offset(x: -50, y: 0)
    }

}

}

I was able to get a smooth animation using an @State variable and an animation toggle which changes the X offset. This is animated smoothly with a linear animation with delay 3 and creates the desired animated effect. I also used a.onAppear to start the animation instantly but this can be changed. It also repeats forever but you can change how often it repeats or if you want it to reverse on completion. The offset varies between 0 and -200 which is the period of the wave.

Video Link here https://youtu.be/e5xY14lj3yc

struct HomeView: View {
  @State var index = true
  @State var indexBattery = true
  @State var batteryAnimation = false
  @State var batteryAnimationUp = 340
  @State var batteryAnimationDown = 260
  var body: some View {

    ZStack {
      Back(batteryAnimationUp: batteryAnimationUp, batteryAnimationDown: batteryAnimationDown, batteryAnimation: self.$batteryAnimation)
        .offset(x: 0, y: 100)
        .onAppear {
          self.batteryAnimation = true
        }
        
    }
  }
}

struct Back: View {
  var batteryAnimationUp: Int
  var batteryAnimationDown: Int
  @Binding var batteryAnimation: Bool
  public var animatableData: AnimatablePair<Double, Double>{
    get{ AnimatablePair(Double(batteryAnimationUp), Double(batteryAnimationDown))}
    set{
        self.batteryAnimationUp = Int(newValue.first)
        self.batteryAnimationDown = Int(newValue.second)
    }
  }
  var body: some View{
    ZStack {
        Path { path in
            path.move(to: CGPoint(x: 0, y: 300))
            path.addQuadCurve(to: CGPoint(x: 100, y: 300), control: CGPoint(x: 50, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 200, y: 300), control: CGPoint(x: 150, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 300, y: 300), control: CGPoint(x: 250, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 400, y: 300), control: CGPoint(x: 350, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 500, y: 300), control: CGPoint(x: 450, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 600, y: 300), control: CGPoint(x: 550, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 700, y: 300), control: CGPoint(x: 650, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 800, y: 300), control: CGPoint(x: 750, y: batteryAnimationDown))

            path.addLine(to: CGPoint(x: 400, y: 1000))
            path.addLine(to: CGPoint(x: 0, y: 1000))
            path.closeSubpath()
        }
        .fill(Color.green)
        .offset(x: self.batteryAnimation ? -300 : -100, y: 0)
        .animation(
          Animation.linear(duration: 3)
            .repeatForever(autoreverses: false)
        )
      
        Path { path in
            path.move(to: CGPoint(x: 0, y: 300))
            path.addQuadCurve(to: CGPoint(x: 100, y: 300), control: CGPoint(x: 50, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 200, y: 300), control: CGPoint(x: 150, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 300, y: 300), control: CGPoint(x: 250, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 400, y: 300), control: CGPoint(x: 350, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 500, y: 300), control: CGPoint(x: 450, y: batteryAnimationUp))
            path.addQuadCurve(to: CGPoint(x: 600, y: 300), control: CGPoint(x: 550, y: batteryAnimationDown))
            path.addQuadCurve(to: CGPoint(x: 700, y: 300), control: CGPoint(x: 650, y: batteryAnimationUp))

            path.addLine(to: CGPoint(x: 400, y: 1000))
            path.addLine(to: CGPoint(x: 0, y: 1000))
            path.closeSubpath()
        }
        
        .fill(Color.blue)
        .offset(x: self.batteryAnimation ? 0 : -200, y: 0)
        .animation(
          Animation.linear(duration: 3)
            .repeatForever(autoreverses: false)
        )
    }

  }
}

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