diff --git a/wake.xcodeproj/project.pbxproj b/wake.xcodeproj/project.pbxproj
index 746286c..6b1cc28 100644
--- a/wake.xcodeproj/project.pbxproj
+++ b/wake.xcodeproj/project.pbxproj
@@ -8,6 +8,7 @@
/* Begin PBXBuildFile section */
AB8773632E4E04400071CB53 /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = AB8773622E4E040E0071CB53 /* .gitignore */; };
+ ABC150C12E5DB39A00A1F970 /* Lottie in Frameworks */ = {isa = PBXBuildFile; productRef = ABC150C02E5DB39A00A1F970 /* Lottie */; };
ABE8998E2E533A7100CD7BA6 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = ABE8998D2E533A7100CD7BA6 /* Alamofire */; };
/* End PBXBuildFile section */
@@ -57,6 +58,7 @@
buildActionMask = 2147483647;
files = (
ABE8998E2E533A7100CD7BA6 /* Alamofire in Frameworks */,
+ ABC150C12E5DB39A00A1F970 /* Lottie in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -111,6 +113,7 @@
name = wake;
packageProductDependencies = (
ABE8998D2E533A7100CD7BA6 /* Alamofire */,
+ ABC150C02E5DB39A00A1F970 /* Lottie */,
);
productName = wake;
productReference = ABB4E2082E4B75D900660198 /* wake.app */;
@@ -142,6 +145,7 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
ABE8998C2E533A7100CD7BA6 /* XCRemoteSwiftPackageReference "Alamofire" */,
+ ABC150BF2E5DB39A00A1F970 /* XCRemoteSwiftPackageReference "lottie-spm" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = ABB4E2092E4B75D900660198 /* Products */;
@@ -382,6 +386,14 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
+ ABC150BF2E5DB39A00A1F970 /* XCRemoteSwiftPackageReference "lottie-spm" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/airbnb/lottie-spm.git";
+ requirement = {
+ kind = upToNextMajorVersion;
+ minimumVersion = 4.5.2;
+ };
+ };
ABE8998C2E533A7100CD7BA6 /* XCRemoteSwiftPackageReference "Alamofire" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/Alamofire/Alamofire.git";
@@ -393,6 +405,11 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
+ ABC150C02E5DB39A00A1F970 /* Lottie */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = ABC150BF2E5DB39A00A1F970 /* XCRemoteSwiftPackageReference "lottie-spm" */;
+ productName = Lottie;
+ };
ABE8998D2E533A7100CD7BA6 /* Alamofire */ = {
isa = XCSwiftPackageProductDependency;
package = ABE8998C2E533A7100CD7BA6 /* XCRemoteSwiftPackageReference "Alamofire" */;
diff --git a/wake.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/wake.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
index 8c6ea58..c7f1eae 100644
--- a/wake.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/wake.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -1,5 +1,5 @@
{
- "originHash" : "e8f130fe30ac6cdc940ef06ee1e8535e9f46ffee6aeead1722b9525562f6ce08",
+ "originHash" : "0e95cd18402f001189cea942918f7d0c4c8b04175c6c482029650c892d28d55a",
"pins" : [
{
"identity" : "alamofire",
@@ -9,6 +9,15 @@
"revision" : "513364f870f6bfc468f9d2ff0a95caccc10044c5",
"version" : "5.10.2"
}
+ },
+ {
+ "identity" : "lottie-spm",
+ "kind" : "remoteSourceControl",
+ "location" : "https://github.com/airbnb/lottie-spm.git",
+ "state" : {
+ "revision" : "04f2fd18cc9404a0a0917265a449002674f24ec9",
+ "version" : "4.5.2"
+ }
}
],
"version" : 3
diff --git a/wake/Assets/Svg/Light1.svg b/wake/Assets/Svg/Light1.svg
new file mode 100644
index 0000000..5cdf5f1
--- /dev/null
+++ b/wake/Assets/Svg/Light1.svg
@@ -0,0 +1,45 @@
+
diff --git a/wake/Assets/Svg/Light2.svg b/wake/Assets/Svg/Light2.svg
new file mode 100644
index 0000000..defe932
--- /dev/null
+++ b/wake/Assets/Svg/Light2.svg
@@ -0,0 +1,48 @@
+
diff --git a/wake/Assets/Svg/Light3.svg b/wake/Assets/Svg/Light3.svg
new file mode 100644
index 0000000..b243664
--- /dev/null
+++ b/wake/Assets/Svg/Light3.svg
@@ -0,0 +1,45 @@
+
diff --git a/wake/ContentView.swift b/wake/ContentView.swift
index f52d3e5..a2e4978 100644
--- a/wake/ContentView.swift
+++ b/wake/ContentView.swift
@@ -19,6 +19,9 @@ struct ContentView: View {
@State private var showSettings = false // 控制设置页面显示
@State private var contentOffset: CGFloat = 0 // 内容偏移量
@State private var showLogin = false
+ @State private var animateGradient = false
+
+ let timer = Timer.publish(every: 0.02, on: .main, in: .common).autoconnect()
// 获取模型上下文
@Environment(\.modelContext) private var modelContext
@@ -98,21 +101,22 @@ struct ContentView: View {
.padding(.horizontal)
// 盲盒
// 添加SVG背景图片
- GeometryReader { geometry in
- Color.clear.overlay(
- SVGImage(svgName: "BlindBg")
- .frame(
- width: UIScreen.main.bounds.width * 1.8,
- height: geometry.size.height
- )
- .position(x: geometry.size.width / 2, y: geometry.size.height / 2),
- alignment: .center
- )
+ ZStack {
+ // 背景SVG - 保持原位置不变
+ // SVGImage(svgName: "BlindBg")
+ // .frame(
+ // width: UIScreen.main.bounds.width * 1.8,
+ // height: UIScreen.main.bounds.height * 0.65
+ // )
+ // .position(x: UIScreen.main.bounds.width / 2, y: UIScreen.main.bounds.height * 0.325)
+ // AE 动画 通过lottie实现
+
}
.frame(
maxWidth: .infinity,
maxHeight: UIScreen.main.bounds.height * 0.65
)
+ .clipped()
// 打开
Button(action: showUserProfile) {
Text("Go to Buy")
diff --git a/wake/View/Blind/Card.swift b/wake/View/Blind/Card.swift
new file mode 100644
index 0000000..f5f8e41
--- /dev/null
+++ b/wake/View/Blind/Card.swift
@@ -0,0 +1,84 @@
+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背景大小)
+ }
+
+ // 卡片中心位置(固定,确保摆正居中)
+ private var centerPosition: CGPoint {
+ CGPoint(x: screenWidth / 2, y: squareSize * 0.325)
+ }
+
+ var body: some View {
+ ZStack {
+ // 底部背景(正方形)
+ SVGImage(svgName: "BlindBg")
+ .frame(width: squareSize, height: squareSize)
+ .position(centerPosition)
+
+ // 当前显示的光束卡片(摆正状态)
+ SVGImage(svgName: "Light\(currentLight)")
+ .frame(width: imageSize, height: imageSize)
+ .position(centerPosition)
+ .opacity(currentOpacity)
+
+ // 下一张待显示的光束卡片(提前加载,摆正状态)
+ SVGImage(svgName: "Light\(nextLight)")
+ .frame(width: imageSize, height: imageSize)
+ .position(centerPosition)
+ .opacity(nextOpacity)
+ }
+ .onAppear {
+ startLoopAnimation()
+ }
+ }
+
+ // 计算下一张卡片序号(基于当前索引循环)
+ private var nextLight: Int {
+ let nextIdx = (sequenceIndex + 1) % baseSequence.count
+ return baseSequence[nextIdx]
+ }
+
+ // 启动循环切换动画
+ private func startLoopAnimation() {
+ // 每1.2秒切换一次(可调整速度)
+ Timer.scheduledTimer(withTimeInterval: 1.2, repeats: true) { _ in
+ // 0.5秒淡入淡出过渡(丝滑无卡顿)
+ withAnimation(Animation.easeInOut(duration: 0.5)) {
+ currentOpacity = 0.0
+ nextOpacity = 1.0
+ }
+
+ // 动画完成后更新状态(确保顺序无偏差)
+ DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
+ currentLight = nextLight
+ sequenceIndex = (sequenceIndex + 1) % baseSequence.count
+ currentOpacity = 1.0
+ nextOpacity = 0.0
+ }
+ }
+ }
+}
+
+// 预览
+struct CustomLightSequenceAnimation_Previews: PreviewProvider {
+ static var previews: some View {
+ CustomLightSequenceAnimation()
+ }
+}
\ No newline at end of file