|
|
@@ -11,8 +11,18 @@ struct ContentView: View {
|
|
|
@State private var animateGradient = false
|
|
|
@State private var appeared = false
|
|
|
@State private var glowPulse = false
|
|
|
+ @State private var currentNameIndex = 0
|
|
|
|
|
|
- private let text = "Hello Faiz"
|
|
|
+ // Add more names here later — the button cycles through them in order.
|
|
|
+ private let names = ["Faiz", "Huzaifa"]
|
|
|
+
|
|
|
+ private var displayText: String {
|
|
|
+ "Hello \(names[currentNameIndex])"
|
|
|
+ }
|
|
|
+
|
|
|
+ private var nextName: String {
|
|
|
+ names[(currentNameIndex + 1) % names.count]
|
|
|
+ }
|
|
|
private let vibrantColors: [Color] = [
|
|
|
Color(red: 1.0, green: 0.2, blue: 0.4),
|
|
|
Color(red: 1.0, green: 0.55, blue: 0.0),
|
|
|
@@ -37,32 +47,68 @@ struct ContentView: View {
|
|
|
.ignoresSafeArea()
|
|
|
.animation(.easeInOut(duration: 4).repeatForever(autoreverses: true), value: animateGradient)
|
|
|
|
|
|
- HStack(spacing: 0) {
|
|
|
- ForEach(Array(text.enumerated()), id: \.offset) { index, character in
|
|
|
- Text(String(character == " " ? "\u{00A0}" : character))
|
|
|
- .font(.system(size: 72, weight: .black, design: .rounded))
|
|
|
- .bold()
|
|
|
- .foregroundStyle(vibrantColors[index % vibrantColors.count])
|
|
|
- .shadow(
|
|
|
- color: vibrantColors[index % vibrantColors.count].opacity(glowPulse ? 0.85 : 0.35),
|
|
|
- radius: glowPulse ? 20 : 10
|
|
|
- )
|
|
|
- .scaleEffect(appeared ? 1.0 : 0.1)
|
|
|
- .opacity(appeared ? 1.0 : 0.0)
|
|
|
- .rotationEffect(.degrees(appeared ? 0 : -30))
|
|
|
- .offset(y: animateGradient ? -8 : 8)
|
|
|
- .animation(
|
|
|
- .spring(response: 0.7, dampingFraction: 0.55)
|
|
|
- .delay(Double(index) * 0.07),
|
|
|
- value: appeared
|
|
|
+ VStack(spacing: 36) {
|
|
|
+ HStack(spacing: 0) {
|
|
|
+ ForEach(Array(displayText.enumerated()), id: \.offset) { index, character in
|
|
|
+ Text(String(character == " " ? "\u{00A0}" : character))
|
|
|
+ .font(.system(size: 72, weight: .black, design: .rounded))
|
|
|
+ .bold()
|
|
|
+ .foregroundStyle(vibrantColors[index % vibrantColors.count])
|
|
|
+ .shadow(
|
|
|
+ color: vibrantColors[index % vibrantColors.count].opacity(glowPulse ? 0.85 : 0.35),
|
|
|
+ radius: glowPulse ? 20 : 10
|
|
|
+ )
|
|
|
+ .scaleEffect(appeared ? 1.0 : 0.1)
|
|
|
+ .opacity(appeared ? 1.0 : 0.0)
|
|
|
+ .rotationEffect(.degrees(appeared ? 0 : -30))
|
|
|
+ .offset(y: animateGradient ? -8 : 8)
|
|
|
+ .animation(
|
|
|
+ .spring(response: 0.7, dampingFraction: 0.55)
|
|
|
+ .delay(Double(index) * 0.07),
|
|
|
+ value: appeared
|
|
|
+ )
|
|
|
+ .animation(
|
|
|
+ .easeInOut(duration: 0.6)
|
|
|
+ .repeatForever(autoreverses: true)
|
|
|
+ .delay(Double(index) * 0.1),
|
|
|
+ value: animateGradient
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .id(displayText)
|
|
|
+
|
|
|
+ Button(action: cycleGreeting) {
|
|
|
+ Text("Say Hello to \(nextName)")
|
|
|
+ .font(.system(size: 18, weight: .semibold, design: .rounded))
|
|
|
+ .foregroundStyle(
|
|
|
+ LinearGradient(
|
|
|
+ colors: [vibrantColors[0], vibrantColors[4], vibrantColors[6]],
|
|
|
+ startPoint: .leading,
|
|
|
+ endPoint: .trailing
|
|
|
+ )
|
|
|
)
|
|
|
- .animation(
|
|
|
- .easeInOut(duration: 0.6)
|
|
|
- .repeatForever(autoreverses: true)
|
|
|
- .delay(Double(index) * 0.1),
|
|
|
- value: animateGradient
|
|
|
+ .padding(.horizontal, 24)
|
|
|
+ .padding(.vertical, 12)
|
|
|
+ .background(
|
|
|
+ Capsule()
|
|
|
+ .fill(Color.white.opacity(0.08))
|
|
|
+ .overlay(
|
|
|
+ Capsule()
|
|
|
+ .stroke(
|
|
|
+ LinearGradient(
|
|
|
+ colors: vibrantColors.prefix(3).map { $0.opacity(0.8) },
|
|
|
+ startPoint: .leading,
|
|
|
+ endPoint: .trailing
|
|
|
+ ),
|
|
|
+ lineWidth: 2
|
|
|
+ )
|
|
|
+ )
|
|
|
)
|
|
|
}
|
|
|
+ .buttonStyle(.plain)
|
|
|
+ .opacity(appeared ? 1.0 : 0.0)
|
|
|
+ .scaleEffect(appeared ? 1.0 : 0.8)
|
|
|
+ .animation(.spring(response: 0.7, dampingFraction: 0.55).delay(0.5), value: appeared)
|
|
|
}
|
|
|
.padding()
|
|
|
}
|
|
|
@@ -77,6 +123,14 @@ struct ContentView: View {
|
|
|
appeared = true
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ private func cycleGreeting() {
|
|
|
+ appeared = false
|
|
|
+ currentNameIndex = (currentNameIndex + 1) % names.count
|
|
|
+ withAnimation(.spring(response: 0.7, dampingFraction: 0.55)) {
|
|
|
+ appeared = true
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
#Preview {
|