From 9b76b341f29e02e98479b740388000592fd84d2e Mon Sep 17 00:00:00 2001 From: jinyaqiu Date: Wed, 27 Aug 2025 18:20:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=B7=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- wake/View/Blind/BlindBox.swift | 85 ++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 14 deletions(-) diff --git a/wake/View/Blind/BlindBox.swift b/wake/View/Blind/BlindBox.swift index 811998f..40aaf16 100644 --- a/wake/View/Blind/BlindBox.swift +++ b/wake/View/Blind/BlindBox.swift @@ -7,6 +7,37 @@ extension Notification.Name { } // MARK: - 主视图 +struct VisualEffectView: UIViewRepresentable { + var effect: UIVisualEffect? + + func makeUIView(context: Context) -> UIVisualEffectView { + let view = UIVisualEffectView(effect: nil) + + // Use a simpler approach without animator + let blurEffect = UIBlurEffect(style: .systemUltraThinMaterialLight) + + // Create a custom blur effect with reduced intensity + let blurView = UIVisualEffectView(effect: blurEffect) + blurView.alpha = 0.3 // Reduce intensity + + // Add a white background with low opacity for better frosted effect + let backgroundView = UIView() + backgroundView.backgroundColor = UIColor.white.withAlphaComponent(0.1) + backgroundView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + view.contentView.addSubview(backgroundView) + view.contentView.addSubview(blurView) + blurView.frame = view.bounds + blurView.autoresizingMask = [.flexibleWidth, .flexibleHeight] + + return view + } + + func updateUIView(_ uiView: UIVisualEffectView, context: Context) { + // No need to update the effect + } +} + struct BlindBoxView: View { @State private var showLottieAnimation = true // 控制Lottie动画显示 @State private var showScalingOverlay = false @@ -14,6 +45,8 @@ struct BlindBoxView: View { @State private var mediaToShow: MediaType? @State private var videoPlayer: AVPlayer? @State private var showControls = false // Add this line for controlling visibility + @State private var aspectRatio: CGFloat = 1.0 + @State private var isPortraitVideo: Bool = false private func startScalingAnimation() { // Start from 10% size @@ -27,12 +60,26 @@ struct BlindBoxView: View { } private func loadVideo() { - // Replace with your actual video URL - if let url = URL(string: "https://cdn.fairclip.cn/files/7342843896868769793/飞书20250617-144935.mp4") { - let player = AVPlayer(url: url) - player.isMuted = true // Mute the video - self.videoPlayer = player + guard let url = URL(string: "https://cdn.fairclip.cn/files/7329556154558844929/doubao-seedance-1-0-lite-i2v-2100199406-02174750234303300000000000000000000ffffac15403eacd2fe.mp4") else { return } + + let asset = AVAsset(url: url) + let playerItem = AVPlayerItem(asset: asset) + let player = AVPlayer(playerItem: playerItem) + + // 获取视频轨道以确定宽高比 + let videoTracks = asset.tracks(withMediaType: .video) + if let videoTrack = videoTracks.first { + let size = videoTrack.naturalSize.applying(videoTrack.preferredTransform) + let width = abs(size.width) + let height = abs(size.height) + + // 计算宽高比 + aspectRatio = width / height + isPortraitVideo = height > width } + + player.isMuted = true + self.videoPlayer = player } var body: some View { @@ -69,7 +116,7 @@ struct BlindBoxView: View { .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) + .animation(.easeOut(duration: 1.5), value: showScalingOverlay) } if !showScalingOverlay { @@ -86,9 +133,9 @@ struct BlindBoxView: View { maxHeight: UIScreen.main.bounds.height * 0.65 ) .opacity(showScalingOverlay ? 0 : 1) - .animation(.easeOut(duration: 0.5), value: showScalingOverlay) + .animation(.easeOut(duration: 1.5), value: showScalingOverlay) .offset(y: showScalingOverlay ? -100 : 0) - .animation(.easeInOut(duration: 0.5), value: showScalingOverlay) + .animation(.easeInOut(duration: 1.5), value: showScalingOverlay) } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.themeTextWhiteSecondary) @@ -98,18 +145,28 @@ struct BlindBoxView: View { // Scaling Overlay if showScalingOverlay { ZStack { + // Frosted glass background with custom transparency + VisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterialLight)) + .edgesIgnoringSafeArea(.all) + // Video Player if let player = videoPlayer { ZStack(alignment: .topLeading) { VideoPlayer(player: player) .aspectRatio(contentMode: .fill) - .frame(width: UIScreen.main.bounds.width * scale, - height: UIScreen.main.bounds.height * scale) + .frame( + width: isPortraitVideo ? + UIScreen.main.bounds.height * scale * 1/aspectRatio : + UIScreen.main.bounds.width * scale, + height: isPortraitVideo ? + UIScreen.main.bounds.height * scale : + UIScreen.main.bounds.width * scale * 1/aspectRatio + ) .clipped() .opacity(scale == 1 ? 1 : 0.7) - .contentShape(Rectangle()) // Make entire area tappable + .contentShape(Rectangle()) .onTapGesture { - withAnimation(.easeInOut(duration: 0.3)) { + withAnimation(.easeInOut(duration: 0.1)) { showControls.toggle() } } @@ -158,10 +215,10 @@ struct BlindBoxView: View { } } .frame(maxWidth: .infinity, maxHeight: .infinity) - .animation(.easeInOut(duration: 3.0), value: scale) + .animation(.easeInOut(duration: 1.0), value: scale) .ignoresSafeArea() .onTapGesture { - withAnimation(.easeInOut(duration: 0.3)) { + withAnimation(.easeInOut(duration: 0.1)) { showControls.toggle() } }