feat: 暂定样式
This commit is contained in:
parent
4153f0470a
commit
5b83ace879
10
wake/Assets/Svg/BlindBoxBg.svg
Normal file
10
wake/Assets/Svg/BlindBoxBg.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<svg width="358" height="549" viewBox="0 0 358 549" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M358 531V18C358 8.05887 349.941 0 340 0H252.517C246.504 0 240.981 3.31723 238.157 8.62569C235.332 13.9342 229.809 17.2514 223.796 17.2514H124.079C118.428 17.2514 113.335 13.8467 111.174 8.62569C109.013 3.40468 103.919 0 98.2688 0H18C8.05887 0 0 8.05889 0 18V531C0 540.941 8.05887 549 18 549H340C349.941 549 358 540.941 358 531Z" fill="#FFB645"/>
|
||||
<path d="M339 461.5V72C339 62.0589 330.941 54 321 54H96.5552C87.5728 54 79.9652 60.6222 78.7271 69.5189L76.5056 85.4811C75.2675 94.3778 67.6599 101 58.6775 101H37C27.0589 101 19 109.059 19 119V500C19 509.941 27.0589 518 37 518H248.463C254.425 518 260 515.048 263.351 510.117L278.8 487.383C282.151 482.452 287.726 479.5 293.688 479.5H321C330.941 479.5 339 471.441 339 461.5Z" fill="white"/>
|
||||
<path d="M46.2666 88.0056C47.2481 88.0087 48.0853 87.2989 48.2426 86.3304L51.6466 65.3641C51.8439 64.1487 50.9059 63.0431 49.6742 63.0393L44.3504 63.0228C43.3875 63.0198 42.5607 63.7033 42.383 64.6493L38.4445 85.614C38.2135 86.8437 39.1565 87.9835 40.4083 87.9874L46.2666 88.0056Z" fill="black"/>
|
||||
<path d="M32.9979 88.0048C33.971 88.0078 34.8036 87.31 34.9702 86.3516L38.616 65.3861C38.8285 64.1641 37.8882 63.0431 36.6474 63.0392L30.6621 63.0206C29.7089 63.0177 28.8875 63.6878 28.6996 64.6219L24.4812 85.5857C24.2323 86.8226 25.1778 87.9805 26.4401 87.9844L32.9979 88.0048Z" fill="black"/>
|
||||
<path d="M59.9979 88.0048C60.971 88.0078 61.8036 87.31 61.9702 86.3516L65.616 65.3861C65.8285 64.1641 64.8882 63.0431 63.6474 63.0392L57.6621 63.0206C56.7089 63.0177 55.8875 63.6878 55.6996 64.6219L51.4812 85.5857C51.2323 86.8226 52.1778 87.9805 53.4401 87.9844L59.9979 88.0048Z" fill="black"/>
|
||||
<path d="M308.289 518.006C309.271 518.009 310.108 517.299 310.265 516.33L313.669 495.364C313.866 494.149 312.928 493.043 311.697 493.039L306.373 493.023C305.41 493.02 304.583 493.703 304.405 494.649L300.467 515.614C300.236 516.844 301.179 517.984 302.431 517.987L308.289 518.006Z" fill="black"/>
|
||||
<path d="M294.998 518.005C295.971 518.008 296.804 517.31 296.97 516.352L300.616 495.386C300.828 494.164 299.888 493.043 298.647 493.039L292.662 493.021C291.709 493.018 290.888 493.688 290.7 494.622L286.481 515.586C286.232 516.823 287.178 517.98 288.44 517.984L294.998 518.005Z" fill="black"/>
|
||||
<path d="M322.044 518.005C323.017 518.008 323.849 517.31 324.016 516.352L327.662 495.386C327.874 494.164 326.934 493.043 325.693 493.039L319.708 493.021C318.755 493.018 317.933 493.688 317.745 494.622L313.527 515.586C313.278 516.823 314.224 517.98 315.486 517.984L322.044 518.005Z" fill="black"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.6 KiB |
19
wake/Assets/Svg/LoadingNpng.svg
Normal file
19
wake/Assets/Svg/LoadingNpng.svg
Normal file
@ -0,0 +1,19 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
||||
<!-- 定义动画 -->
|
||||
<style>
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); }
|
||||
}
|
||||
.spinner {
|
||||
animation: spin 1s linear infinite;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!-- 圆形加载动画 -->
|
||||
<g class="spinner">
|
||||
<circle cx="50" cy="50" r="40" fill="none" stroke="#3498db" stroke-width="8" stroke-dasharray="251.2" stroke-dashoffset="0"/>
|
||||
<circle cx="50" cy="50" r="20" fill="#3498db"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 588 B |
@ -3,7 +3,7 @@ import Foundation
|
||||
/// API 配置信息
|
||||
public enum APIConfig {
|
||||
/// API 基础 URL
|
||||
public static let baseURL = "https://api-dev.memorywake.com:31274/api/v1"
|
||||
public static let baseURL = "https://api.memorywake.com/api/v1"
|
||||
|
||||
/// 认证 token - 从 Keychain 中获取
|
||||
public static var authToken: String {
|
||||
|
||||
38
wake/View/Blind/Apng.swift
Normal file
38
wake/View/Blind/Apng.swift
Normal file
@ -0,0 +1,38 @@
|
||||
import SwiftUI
|
||||
import UIKit
|
||||
|
||||
// 包装UIImageView以支持APNG动画
|
||||
struct APNGView: UIViewRepresentable {
|
||||
let imageName: String
|
||||
@Binding var isAnimating: Bool
|
||||
|
||||
func makeUIView(context: Context) -> UIImageView {
|
||||
let imageView = UIImageView()
|
||||
|
||||
// 从资源加载APNG
|
||||
if let image = UIImage(named: imageName) {
|
||||
imageView.image = image
|
||||
// 启用动画
|
||||
imageView.animationImages = image.images
|
||||
// 设置动画时长(根据实际帧数调整)
|
||||
imageView.animationDuration = image.duration
|
||||
// 根据isAnimating状态决定是否开始动画
|
||||
if isAnimating {
|
||||
imageView.startAnimating()
|
||||
}
|
||||
}
|
||||
|
||||
return imageView
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UIImageView, context: Context) {
|
||||
// 根据isAnimating状态控制动画
|
||||
if isAnimating {
|
||||
if !uiView.isAnimating {
|
||||
uiView.startAnimating()
|
||||
}
|
||||
} else {
|
||||
uiView.stopAnimating()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,8 +4,9 @@ import AVKit
|
||||
|
||||
// MARK: - Constants
|
||||
private enum MediaURLs {
|
||||
static let videoURL = "https://minio-dev.memorywake.com:31274/memo/users/7363409620351717377/files/7366438998098710529/65273FCE-963F-4AA9-B0EB-C5C4ACE76655.mov?x-amz-signature=aa9e1f9c4a3682d1b74fdc090bc49be6870dbaa14e00c5add6483a529667f0f2&x-amz-signedheaders=host&x-amz-date=20250827T120711Z&x-amz-expires=360000&x-amz-algorithm=AWS4-HMAC-SHA256&x-amz-credential=minio%2F20250827%2Fus-east-1%2Fs3%2Faws4_request"
|
||||
static let videoURL = "https://cdn.memorywake.com/users/7363409620351717377/files/7366657553935241216/39C069E1-7C3E-4261-8486-12058F855B38.mov"
|
||||
static let imageURL = "https://cdn.fairclip.cn/files/7343228671693557760/20250604-164000.jpg"
|
||||
static let VideoBlindURL = "https://cdn.memorywake.com/users/7363409620351717377/files/7366658779259211776/AD970D28-9D1E-4817-A245-F11967441B8F.mp4"
|
||||
}
|
||||
|
||||
extension Notification.Name {
|
||||
@ -73,6 +74,7 @@ struct BlindBoxView: View {
|
||||
@State private var scale: CGFloat = 0.1
|
||||
@State private var videoPlayer: AVPlayer?
|
||||
@State private var showControls = false
|
||||
@State private var isAnimating = true
|
||||
@State private var aspectRatio: CGFloat = 1.0
|
||||
@State private var isPortrait: Bool = false
|
||||
@State private var displayImage: UIImage?
|
||||
@ -132,6 +134,23 @@ struct BlindBoxView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Computed Properties
|
||||
private var scaledWidth: CGFloat {
|
||||
if isPortrait {
|
||||
return UIScreen.main.bounds.height * scale * 1/aspectRatio
|
||||
} else {
|
||||
return UIScreen.main.bounds.width * scale
|
||||
}
|
||||
}
|
||||
|
||||
private var scaledHeight: CGFloat {
|
||||
if isPortrait {
|
||||
return UIScreen.main.bounds.height * scale
|
||||
} else {
|
||||
return UIScreen.main.bounds.width * scale * 1/aspectRatio
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Color.themeTextWhiteSecondary.ignoresSafeArea()
|
||||
@ -139,20 +158,14 @@ struct BlindBoxView: View {
|
||||
if showScalingOverlay {
|
||||
ZStack {
|
||||
VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialLight))
|
||||
.opacity(0.3)
|
||||
.edgesIgnoringSafeArea(.all)
|
||||
|
||||
Group {
|
||||
if mediaType == .video, let player = videoPlayer {
|
||||
// Video Player
|
||||
AVPlayerController(player: $videoPlayer)
|
||||
.frame(
|
||||
width: isPortrait ?
|
||||
UIScreen.main.bounds.height * scale * 1/aspectRatio :
|
||||
UIScreen.main.bounds.width * scale,
|
||||
height: isPortrait ?
|
||||
UIScreen.main.bounds.height * scale :
|
||||
UIScreen.main.bounds.width * scale * 1/aspectRatio
|
||||
)
|
||||
.frame(width: scaledWidth, height: scaledHeight)
|
||||
.opacity(scale == 1 ? 1 : 0.7)
|
||||
.onAppear { player.play() }
|
||||
|
||||
@ -161,14 +174,7 @@ struct BlindBoxView: View {
|
||||
Image(uiImage: image)
|
||||
.resizable()
|
||||
.scaledToFit()
|
||||
.frame(
|
||||
width: isPortrait ?
|
||||
UIScreen.main.bounds.height * scale * 1/aspectRatio :
|
||||
UIScreen.main.bounds.width * scale,
|
||||
height: isPortrait ?
|
||||
UIScreen.main.bounds.height * scale :
|
||||
UIScreen.main.bounds.width * scale * 1/aspectRatio
|
||||
)
|
||||
.frame(width: scaledWidth, height: scaledHeight)
|
||||
.opacity(scale == 1 ? 1 : 0.7)
|
||||
}
|
||||
}
|
||||
@ -248,7 +254,7 @@ struct BlindBoxView: View {
|
||||
ZStack {
|
||||
// 1. 背景SVG
|
||||
if !showScalingOverlay {
|
||||
SVGImage(svgName: "BlindBg")
|
||||
SVGImage(svgName: "BlindBoxBg")
|
||||
.frame(
|
||||
width: UIScreen.main.bounds.width * 1.8,
|
||||
height: UIScreen.main.bounds.height * 0.85
|
||||
@ -260,12 +266,21 @@ struct BlindBoxView: View {
|
||||
}
|
||||
|
||||
if !showScalingOverlay {
|
||||
LottieView(name: "data", loopMode: .loop)
|
||||
.frame(width: 200, height: 200)
|
||||
.position(x: UIScreen.main.bounds.width / 2,
|
||||
y: UIScreen.main.bounds.height * 0.325)
|
||||
.opacity(showScalingOverlay ? 0 : 1)
|
||||
.animation(.easeOut(duration: 0.5), value: showScalingOverlay)
|
||||
VStack(spacing: 20) {
|
||||
let player = AVPlayer(url: URL(string: MediaURLs.VideoBlindURL)!)
|
||||
VideoPlayer(player: player)
|
||||
.background(TransparentVideoPlayer())
|
||||
.frame(width: 300, height: 300)
|
||||
.onAppear {
|
||||
player.play()
|
||||
player.isMuted = true
|
||||
}
|
||||
.onDisappear {
|
||||
player.pause()
|
||||
}
|
||||
}
|
||||
.compositingGroup()
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
@ -298,3 +313,14 @@ struct BlindBoxView: View {
|
||||
#Preview {
|
||||
BlindBoxView(mediaType: .video)
|
||||
}
|
||||
|
||||
struct TransparentVideoPlayer: UIViewRepresentable {
|
||||
func makeUIView(context: Context) -> UIView {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .clear
|
||||
view.isOpaque = false
|
||||
return view
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: UIView, context: Context) {}
|
||||
}
|
||||
|
||||
@ -141,6 +141,7 @@ struct UserInfo: View {
|
||||
|
||||
// Continue Button
|
||||
Button(action: {
|
||||
Router.shared.navigate(to: .blindBox(mediaType: .image))
|
||||
if showUsername {
|
||||
let parameters: [String: Any] = [
|
||||
"username": userName,
|
||||
|
||||
@ -52,10 +52,10 @@ struct WakeApp: App {
|
||||
.environmentObject(authState)
|
||||
} else {
|
||||
// 未登录:显示登录界面
|
||||
LoginView()
|
||||
.environmentObject(authState)
|
||||
// UserInfo()
|
||||
// LoginView()
|
||||
// .environmentObject(authState)
|
||||
UserInfo()
|
||||
.environmentObject(authState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user