You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

216 lines
9.2 KiB

import SwiftUI
struct LaunchScreenView: View {
@State private var isAnimating = false
@State private var iconScale: CGFloat = 0.8
@State private var textOpacity: Double = 0.0
@State private var backgroundOpacity: Double = 0.0
var body: some View {
ZStack {
// -
LinearGradient(
gradient: Gradient(colors: [
Color(red: 0.05, green: 0.1, blue: 0.25),
Color(red: 0.15, green: 0.25, blue: 0.5),
Color(red: 0.25, green: 0.35, blue: 0.7)
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
.ignoresSafeArea()
.opacity(backgroundOpacity)
//
ForEach(0..<20) { index in
Circle()
.fill(Color.white.opacity(0.1))
.frame(width: CGFloat.random(in: 2...6))
.position(
x: CGFloat.random(in: 0...UIScreen.main.bounds.width),
y: CGFloat.random(in: 0...UIScreen.main.bounds.height)
)
.scaleEffect(isAnimating ? 1.5 : 0.5)
.opacity(isAnimating ? 0.3 : 0.0)
.animation(
.easeInOut(duration: Double.random(in: 2...4))
.repeatForever(autoreverses: true)
.delay(Double(index) * 0.1),
value: isAnimating
)
}
VStack(spacing: 40) {
Spacer()
//
VStack(spacing: 25) {
//
ZStack {
//
Circle()
.fill(
RadialGradient(
gradient: Gradient(colors: [
Color.white.opacity(0.4),
Color.white.opacity(0.1),
Color.clear
]),
center: .center,
startRadius: 30,
endRadius: 100
)
)
.frame(width: 180, height: 180)
.scaleEffect(isAnimating ? 1.3 : 0.8)
.opacity(isAnimating ? 0.7 : 0.0)
.animation(.easeInOut(duration: 2.5).repeatForever(autoreverses: true), value: isAnimating)
//
RoundedRectangle(cornerRadius: 35)
.fill(
LinearGradient(
gradient: Gradient(colors: [
Color.white.opacity(0.95),
Color.white.opacity(0.8)
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.frame(width: 140, height: 140)
.shadow(color: .black.opacity(0.4), radius: 25, x: 0, y: 15)
.scaleEffect(iconScale)
.animation(.spring(response: 1.0, dampingFraction: 0.7), value: iconScale)
// - 使
Image(systemName: "qrcode.viewfinder")
.font(.system(size: 60, weight: .medium))
.foregroundStyle(
LinearGradient(
gradient: Gradient(colors: [
Color.blue,
Color.purple
]),
startPoint: .topLeading,
endPoint: .bottomTrailing
)
)
.frame(width: 90, height: 90)
.background(
RoundedRectangle(cornerRadius: 20)
.fill(Color.white.opacity(0.9))
)
.clipShape(RoundedRectangle(cornerRadius: 20))
.shadow(color: .black.opacity(0.2), radius: 10, x: 0, y: 5)
.scaleEffect(isAnimating ? 1.1 : 1.0)
.animation(.easeInOut(duration: 2.0).repeatForever(autoreverses: true), value: isAnimating)
} // ZStack
//
VStack(spacing: 15) {
Text("MyQrCode")
.font(.system(size: 42, weight: .bold, design: .rounded))
.foregroundColor(.white)
.shadow(color: .black.opacity(0.4), radius: 3, x: 0, y: 2)
Text("QR Code Scanner & Generator")
.font(.system(size: 20, weight: .medium))
.foregroundColor(.white.opacity(0.9))
.multilineTextAlignment(.center)
.shadow(color: .black.opacity(0.3), radius: 2, x: 0, y: 1)
Text("Professional QR Code Solution")
.font(.system(size: 16, weight: .regular))
.foregroundColor(.white.opacity(0.7))
.multilineTextAlignment(.center)
.shadow(color: .black.opacity(0.2), radius: 1, x: 0, y: 1)
}
.opacity(textOpacity)
}
Spacer()
//
VStack(spacing: 20) {
//
RoundedRectangle(cornerRadius: 3)
.fill(Color.white.opacity(0.2))
.frame(width: 250, height: 6)
.overlay(
RoundedRectangle(cornerRadius: 3)
.fill(
LinearGradient(
gradient: Gradient(colors: [
Color.blue,
Color.purple
]),
startPoint: .leading,
endPoint: .trailing
)
)
.frame(width: 250 * (isAnimating ? 1.0 : 0.0), height: 6)
.animation(.easeInOut(duration: 2.5), value: isAnimating)
)
//
Text("Initializing...")
.font(.system(size: 16, weight: .medium))
.foregroundColor(.white.opacity(0.8))
.opacity(textOpacity)
//
HStack(spacing: 15) {
ForEach(0..<3) { index in
Circle()
.fill(Color.white)
.frame(width: 12, height: 12)
.scaleEffect(isAnimating ? 1.3 : 0.8)
.opacity(isAnimating ? 1.0 : 0.4)
.animation(
.easeInOut(duration: 1.0)
.repeatForever(autoreverses: true)
.delay(Double(index) * 0.25),
value: isAnimating
)
}
}
}
.opacity(textOpacity)
Spacer()
}
.padding(.horizontal, 40)
}
.onAppear {
startAnimations()
}
}
private func startAnimations() {
//
withAnimation(.easeIn(duration: 1.0)) {
backgroundOpacity = 1.0
}
//
withAnimation(.spring(response: 1.0, dampingFraction: 0.7).delay(0.2)) {
iconScale = 1.0
}
//
withAnimation(.easeIn(duration: 1.0).delay(0.5)) {
textOpacity = 1.0
}
//
withAnimation(.easeIn(duration: 0.1).delay(0.8)) {
isAnimating = true
}
}
}
#Preview {
LaunchScreenView()
}