使用SwiftUI制作气泡动画

eoigrqb6  于 2022-12-26  发布在  Swift
关注(0)|答案(1)|浏览(264)

我想为孩子们做一个迷你游戏,让字母字符漂浮在气泡内,所以我使用了文本与覆盖图像,它的工作,但问题是,当我点击气泡时,我不知道如何使它消失的动画,并使文本停止在当前位置

struct ExtractedView: View {
    @State var BubbleAnimate = false
    @State var AlphbetArray: [String] = ["A", "B","C","D","E","F","G"]
    @State var randomNumber = Int.random(in: 0...6)
    
    var body: some View {
        Button {
            BubbleAnimate = true
            print("Hi")
        } label: {
            Text("Test Me")
        }
        .offset(x:100)

        Text(AlphbetArray[randomNumber])
                    .font(.system(size: 120))
                    .fontWeight(.bold)
                    .foregroundColor(.purple)
                    .padding()
                    .overlay {
                        
                        Image("bubble").resizable().frame(width: 130.0, height: 130.0).scaledToFit()
                    }
                    .animation(.linear(duration: 5).repeatForever(autoreverses: false), value: BubbleAnimate)
                .offset(y:BubbleAnimate ? -300 : 300)
                .onTapGesture {
                    print("Hello")
                    BubbleAnimate.toggle()

                    // I tried toggle but it won't work probably 
                }
    }
}

这就是我怎样才能使气泡消失的动画,并使字母停留1秒的时间,使更多的动画,如缩放等结果...

oknwwptz

oknwwptz1#

有几点考虑:

  • 字母永远不会停在特定的地方,因为它只有两个位置:偏移量300或偏移量-300。要使其在某个位置停止,偏移量必须具有中间值。解决方案:使用每 * n * 毫秒修改偏移的定时器。
  • 气泡始终显示。要使其消失,必须有一个条件和一个特定变量来触发其可见性。解决方案:创建一个有条件地显示气泡的变量,并使用.transition()修改器设置其动画。
  • 变量必须以小写字母开头。只要使用约定,它会使代码更容易理解。

下面是代码:

// Don't use binary values for the offset, use absolute values
@State private var bubbleOffset = 0.0

@State private var alphabetArray: [String] = ["A", "B","C","D","E","F","G"]
@State private var randomNumber = Int.random(in: 0...6)

// Trigger the visibility of the bubble separately from the animation
@State private var showBubble = false

let maxOffset =  300.0
let minOffset = -300.0

// Use a timer to change the offset
let timer = Timer.publish(every: 0.01, on: .main, in: .common).autoconnect()

var body: some View {
    
    VStack {
        Button {
            
            // The button starts the animation; in this case,
            // the animation happens only when the bubble is
            // visible, but it does not have to be like that
            showBubble = true
            print("Hi")
        } label: {
            Text("Test Me")
        }
        .offset(x:100)
        
            Text(alphabetArray[randomNumber])
                .font(.system(size: 120))
                .fontWeight(.bold)
                .foregroundColor(.purple)
                .padding()
                .overlay {
                    
                    // Show the bubble conditionally
                    if showBubble {
                        Image(systemName: "bubble.left").resizable().frame(width: 130.0, height: 130.0).scaledToFit()
                        
                            // This transition will animate the disappearance of the bubble
                            .transition(.opacity)
                    }
                    
                }
        
                // Absolute offset
                .offset(y: bubbleOffset)
                .onTapGesture {
                    withAnimation {
                        print("Hello")
                        
                        // Trigger the disappearance of the bubble
                        showBubble = false
                    }
                }
        
                .onReceive(timer) { _ in

                    // In this case,
                    // the animation happens only when the bubble is
                    // visible, but it does not have to be like that
                    if showBubble {
                        
                        // Change the offset at every emission of a new time
                        bubbleOffset -= 1
                        
                        // Handle out-of-bounds
                        if bubbleOffset < minOffset {
                            bubbleOffset = maxOffset
                        }
                    }
                }
    }
}

相关问题