diff --git a/Wpf_AiSportsMicrospace/App.xaml b/Wpf_AiSportsMicrospace/App.xaml index bb7194e..726f59f 100644 --- a/Wpf_AiSportsMicrospace/App.xaml +++ b/Wpf_AiSportsMicrospace/App.xaml @@ -1,8 +1,8 @@  + xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.Views" + StartupUri="Views/Main.xaml"> diff --git a/Wpf_AiSportsMicrospace/Common/Utils.cs b/Wpf_AiSportsMicrospace/Common/Utils.cs new file mode 100644 index 0000000..f316c35 --- /dev/null +++ b/Wpf_AiSportsMicrospace/Common/Utils.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Media; + +namespace Wpf_AiSportsMicrospace.Common +{ + public static class Utils + { + private static MediaPlayer _bgPlayer; + public static void PlayBackgroundMusic(string musicFileName) + { + string projectRoot = Path.Combine(AppContext.BaseDirectory, @"..\..\.."); + string musicPath = Path.Combine(projectRoot, "Resources", "Music", musicFileName); + + if (_bgPlayer == null) + { + _bgPlayer = new MediaPlayer(); + _bgPlayer.Volume = 0.5; + _bgPlayer.MediaEnded += (s, e) => + { + _bgPlayer.Position = TimeSpan.Zero; // 循环播放 + _bgPlayer.Play(); + }; + } + else + { + _bgPlayer.Stop(); + } + + _bgPlayer.Open(new Uri(musicPath, UriKind.Absolute)); + _bgPlayer.Play(); + } + public static void StopBackgroundMusic() + { + if (_bgPlayer != null) + { + _bgPlayer.Stop(); + //_bgPlayer.Close(); // 如果想释放资源,可以取消注释 + } + } + } +} diff --git a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs index 8ea9af2..ca668aa 100644 --- a/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs +++ b/Wpf_AiSportsMicrospace/MyUserControl/CoverFlowControl1.xaml.cs @@ -1,4 +1,4 @@ -using _3DTools; + using System; using System.Collections.Generic; using System.Collections.ObjectModel; diff --git a/Wpf_AiSportsMicrospace/Resources/Music/homeprojectselected.mp3 b/Wpf_AiSportsMicrospace/Resources/Music/homeprojectselected.mp3 new file mode 100644 index 0000000..65b067b Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Music/homeprojectselected.mp3 differ diff --git a/Wpf_AiSportsMicrospace/Resources/Music/musicjumprope.mp3 b/Wpf_AiSportsMicrospace/Resources/Music/musicjumprope.mp3 new file mode 100644 index 0000000..2b40a48 Binary files /dev/null and b/Wpf_AiSportsMicrospace/Resources/Music/musicjumprope.mp3 differ diff --git a/Wpf_AiSportsMicrospace/Home.xaml b/Wpf_AiSportsMicrospace/Views/Home.xaml similarity index 85% rename from Wpf_AiSportsMicrospace/Home.xaml rename to Wpf_AiSportsMicrospace/Views/Home.xaml index bf34f7d..5fba204 100644 --- a/Wpf_AiSportsMicrospace/Home.xaml +++ b/Wpf_AiSportsMicrospace/Views/Home.xaml @@ -1,9 +1,8 @@ - - + xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl" Loaded="Window_Loaded"> + @@ -28,4 +27,4 @@ Padding="0,100" /> - + diff --git a/Wpf_AiSportsMicrospace/Home.xaml.cs b/Wpf_AiSportsMicrospace/Views/Home.xaml.cs similarity index 92% rename from Wpf_AiSportsMicrospace/Home.xaml.cs rename to Wpf_AiSportsMicrospace/Views/Home.xaml.cs index 220d7ee..8578877 100644 --- a/Wpf_AiSportsMicrospace/Home.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/Home.xaml.cs @@ -30,7 +30,7 @@ namespace Wpf_AiSportsMicrospace /// /// Home.xaml 的交互逻辑 /// - public partial class Home : Window + public partial class Home : UserControl { private IHumanPredictor _humanPredictor; private WebcamClient _webcamClient; @@ -56,7 +56,7 @@ namespace Wpf_AiSportsMicrospace //coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "4.jpg"))); //coverFlow.Images.Add(new Uri(Path.Combine(albumPath, "5.jpg"))); - coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(albumPath, "home_test.png")) , ProgressColor1 = "#215bc7" , ProgressColor2 = "#fc640e" }); + coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(albumPath, "home_test.png")), ProgressColor1 = "#215bc7", ProgressColor2 = "#fc640e" }); coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(albumPath, "home_play.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#fd8212" }); coverFlow.Images.Add(new CoverFlowItem { ImageUri = new Uri(Path.Combine(albumPath, "home_history.png")), ProgressColor1 = "#e73d42", ProgressColor2 = "#215bc7" }); @@ -77,9 +77,11 @@ namespace Wpf_AiSportsMicrospace _webcamClient.StartExtract(); StartFrameProcessing(); + + Utils.PlayBackgroundMusic("homeprojectselected.mp3"); + //coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted; } - private void CoverFlow_ProgressCompleted(CoverFlowItem item) { // 停止抽帧线程/释放资源 @@ -100,7 +102,6 @@ namespace Wpf_AiSportsMicrospace // 根据图片跳转新窗口 string uri = item.ImageUri.ToString(); - Window newWindow = null; //if (uri.EndsWith("1.jpg")) // newWindow = new GroupJumpRope(); @@ -108,16 +109,13 @@ namespace Wpf_AiSportsMicrospace // newWindow = new GroupJumpRope(); //else if (uri.EndsWith("3.jpg")) // newWindow = new GroupJumpRope(); + // 找到主窗口,切换内容到 GroupJumpRopePage - newWindow = new GroupJumpRope(); - - if (newWindow != null) + var mainWin = Application.Current.MainWindow as Main; + if (mainWin != null) { - Dispatcher.BeginInvoke(() => - { - newWindow.Show(); // 先显示新窗口 - this.Close(); // 再关闭当前窗口 - }); + Utils.PlayBackgroundMusic("musicjumprope.mp3"); + mainWin.SwitchPage(new GroupJumpRope(), true); } } @@ -209,5 +207,9 @@ namespace Wpf_AiSportsMicrospace } } + public void Dispose() + { + throw new NotImplementedException(); + } } } diff --git a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml index 26ba7e6..5778430 100644 --- a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml +++ b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml @@ -1,12 +1,22 @@ - - - + mc:Ignorable="d"> + + + + + + + - + diff --git a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs index e26ef5a..84cbb01 100644 --- a/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs +++ b/Wpf_AiSportsMicrospace/Views/JumpRope/GroupJumpRope.xaml.cs @@ -11,13 +11,14 @@ using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; +using Wpf_AiSportsMicrospace.Common; namespace Wpf_AiSportsMicrospace.Views { /// /// GroupJumpRope.xaml 的交互逻辑 /// - public partial class GroupJumpRope : Window + public partial class GroupJumpRope : UserControl { public GroupJumpRope() { diff --git a/Wpf_AiSportsMicrospace/Views/Main.xaml b/Wpf_AiSportsMicrospace/Views/Main.xaml new file mode 100644 index 0000000..64bcb66 --- /dev/null +++ b/Wpf_AiSportsMicrospace/Views/Main.xaml @@ -0,0 +1,12 @@ + + + + + + diff --git a/Wpf_AiSportsMicrospace/Views/Main.xaml.cs b/Wpf_AiSportsMicrospace/Views/Main.xaml.cs new file mode 100644 index 0000000..0ead876 --- /dev/null +++ b/Wpf_AiSportsMicrospace/Views/Main.xaml.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Animation; +using System.Windows.Media.Imaging; +using System.Windows.Media.Media3D; + +namespace Wpf_AiSportsMicrospace.Views +{ + /// + /// Main.xaml 的交互逻辑 + /// + public partial class Main : Window + { + public Main() + { + InitializeComponent(); + + // 默认显示首页 + MainContent.Content = new Home(); + } + public void SwitchPage(UserControl newPage, bool fromRight) + { + if (MainContent.Content == newPage) return; + + var oldPage = MainContent.Content as UserControl; + + if (oldPage != null) + { + // 旧页面动画 + var oldTransformGroup = new TransformGroup(); + var oldScale = new ScaleTransform(1, 1); + var oldSkew = new SkewTransform(0, 0); + var oldTranslate = new TranslateTransform(0, 0); + oldTransformGroup.Children.Add(oldScale); + oldTransformGroup.Children.Add(oldSkew); + oldTransformGroup.Children.Add(oldTranslate); + oldPage.RenderTransformOrigin = new Point(fromRight ? 1 : 0, 0.5); // 左右翻页中心 + oldPage.RenderTransform = oldTransformGroup; + + var scaleAnim = new DoubleAnimation(1, 0.7, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + var skewAnim = new DoubleAnimation(0, fromRight ? 45 : -45, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + var fadeAnim = new DoubleAnimation(1, 0.2, TimeSpan.FromMilliseconds(600)); + var translateAnim = new DoubleAnimation(0, fromRight ? -ActualWidth : ActualWidth, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + + oldScale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnim); + oldScale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnim); + oldSkew.BeginAnimation(SkewTransform.AngleYProperty, skewAnim); + oldTranslate.BeginAnimation(TranslateTransform.XProperty, translateAnim); + oldPage.BeginAnimation(OpacityProperty, fadeAnim); + + fadeAnim.Completed += (s, e) => + { + MainContent.Content = newPage; + AnimateNewPageEnhanced(newPage, fromRight); + }; + } + else + { + MainContent.Content = newPage; + AnimateNewPageEnhanced(newPage, fromRight); + } + } + + private void AnimateNewPageEnhanced(UserControl newPage, bool fromRight) + { + var transformGroup = new TransformGroup(); + var scale = new ScaleTransform(0.7, 0.7); + var skew = new SkewTransform(fromRight ? -45 : 45, 0); + var translate = new TranslateTransform(fromRight ? ActualWidth : -ActualWidth, 0); + transformGroup.Children.Add(scale); + transformGroup.Children.Add(skew); + transformGroup.Children.Add(translate); + newPage.RenderTransformOrigin = new Point(fromRight ? 0 : 1, 0.5); + newPage.RenderTransform = transformGroup; + + // 动画 + var scaleAnim = new DoubleAnimation(0.7, 1, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + var skewAnim = new DoubleAnimation(fromRight ? -45 : 45, 0, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + var fadeAnim = new DoubleAnimation(0.2, 1, TimeSpan.FromMilliseconds(600)); + var translateAnim = new DoubleAnimation(fromRight ? ActualWidth : -ActualWidth, 0, TimeSpan.FromMilliseconds(600)) { EasingFunction = new CubicEase { EasingMode = EasingMode.EaseInOut } }; + + scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnim); + scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnim); + skew.BeginAnimation(SkewTransform.AngleYProperty, skewAnim); + translate.BeginAnimation(TranslateTransform.XProperty, translateAnim); + newPage.BeginAnimation(OpacityProperty, fadeAnim); + } + } +} \ No newline at end of file diff --git a/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj b/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj index 7fc3af0..0770e6f 100644 --- a/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj +++ b/Wpf_AiSportsMicrospace/Wpf_AiSportsMicrospace.csproj @@ -32,10 +32,11 @@ + + - @@ -142,6 +143,12 @@ Always + + Always + + + Always +