import SwiftUI struct CustomLightSequenceAnimation: View { // 核心循环序列:按"123321123321"规律定义基础单元 private let baseSequence: [Int] = [1, 2, 3, 3, 2, 1, 1, 2, 3, 3, 2, 1] @State private var currentLight: Int = 1 // 当前显示的图片序号 @State private var sequenceIndex: Int = 0 // 当前在序列中的索引 // 淡入淡出透明度控制(确保切换丝滑) @State private var currentOpacity: CGFloat = 1.0 @State private var nextOpacity: CGFloat = 0.0 // 尺寸参数(适配正方形卡片) private let screenWidth = UIScreen.main.bounds.width private let squareSize: CGFloat private let imageSize: CGFloat init() { self.squareSize = screenWidth * 1.8 // 正方形背景尺寸 self.imageSize = squareSize / 3 // 光束卡片尺寸(1/3背景大小) } // MARK: - SwiftUI 背景重绘(方形版本) private struct CardBlindBackground: View { var body: some View { GeometryReader { geo in let w = geo.size.width let h = geo.size.height ZStack { // 主背景卡片(方形) RoundedRectangle(cornerRadius: 28) .fill( LinearGradient( colors: [Color.white, Color.white.opacity(0.96)], startPoint: .topLeading, endPoint: .bottomTrailing ) ) .shadow(color: Color.black.opacity(0.06), radius: 16, x: 0, y: 8) .frame(width: w * 0.88, height: h * 0.88) .position(x: w / 2, y: h / 2) // 左上光斑 Circle() .fill(Color.themePrimary.opacity(0.18)) .blur(radius: 40) .frame(width: min(w, h) * 0.35, height: min(w, h) * 0.35) .position(x: w * 0.25, y: h * 0.25) // 右下光斑 Circle() .fill(Color.orange.opacity(0.14)) .blur(radius: 50) .frame(width: min(w, h) * 0.40, height: min(w, h) * 0.40) .position(x: w * 0.75, y: h * 0.75) // 中央高光描边 RoundedRectangle(cornerRadius: 28) .stroke(Color.white.opacity(0.35), lineWidth: 1) .frame(width: w * 0.88, height: h * 0.88) .position(x: w / 2, y: h / 2) .blendMode(.overlay) .opacity(0.7) } } } } // 卡片中心位置(固定,确保摆正居中) private var centerPosition: CGPoint { CGPoint(x: screenWidth / 2, y: squareSize * 0.325) } var body: some View { ZStack { // 底部背景(正方形,SwiftUI 重绘) CardBlindBackground() .frame(width: squareSize, height: squareSize) .position(centerPosition) } } } // 预览 struct CustomLightSequenceAnimation_Previews: PreviewProvider { static var previews: some View { CustomLightSequenceAnimation() } }