update:添加二级导航页

This commit is contained in:
ltx 2025-10-11 14:40:01 +08:00
parent 8c140e9260
commit 1a32fef55c
5 changed files with 224 additions and 56 deletions

View File

@ -192,9 +192,9 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
private void UpdateLayoutWithAnimation(bool instant = false) private void UpdateLayoutWithAnimation(bool instant = false)
{ {
double centerX = ActualWidth / 2; double centerX = ActualWidth / 2;
double spacing = 550; double spacing = 530;
double sideScale = 0.93; double sideScale = 0.98;
double centerScale = 1.43; double centerScale = 1.33;
for (int i = 0; i < ItemsHost.Items.Count; i++) for (int i = 0; i < ItemsHost.Items.Count; i++)
{ {
@ -214,25 +214,25 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
if (i == SelectedIndex) if (i == SelectedIndex)
{ {
targetX = centerX - 75; targetX = centerX - 175;
targetScale = centerScale; targetScale = centerScale;
targetOpacity = 1.0; targetOpacity = 1.0;
} }
else if (i == SelectedIndex - 1 || (SelectedIndex == 0 && i == Images.Count - 1)) else if (i == SelectedIndex - 1 || (SelectedIndex == 0 && i == Images.Count - 1))
{ {
targetX = centerX - spacing - 75; targetX = centerX - spacing -175;
targetScale = sideScale; targetScale = sideScale;
targetOpacity = 1.0; targetOpacity = 1.0;
} }
else if (i == SelectedIndex + 1 || (SelectedIndex == Images.Count - 1 && i == 0)) else if (i == SelectedIndex + 1 || (SelectedIndex == Images.Count - 1 && i == 0))
{ {
targetX = centerX + spacing - 75; targetX = centerX + spacing - 175;
targetScale = sideScale; targetScale = sideScale;
targetOpacity = 1.0; targetOpacity = 1.0;
} }
else else
{ {
targetX = centerX - 75; targetX = centerX - 175;
targetScale = sideScale; targetScale = sideScale;
targetOpacity = 0.0; targetOpacity = 0.0;
} }

View File

@ -15,7 +15,7 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Top" VerticalAlignment="Top"
Width="615" Width="615"
Margin="0,100,0,0" Margin="0,50,0,0"
/> />
<!-- CoverFlowControl距离图片80 --> <!-- CoverFlowControl距离图片80 -->
@ -25,12 +25,13 @@
VerticalAlignment="Top" VerticalAlignment="Top"
Height="900" Height="900"
Width="1920" Width="1920"
Margin="0,250,0,0" Margin="0,180,0,0"
Padding="0,100" Padding="0,100"
/> />
<Grid Margin="314,803,314,0" VerticalAlignment="Top" Height="182"> <Grid Margin="314,833,214,0" VerticalAlignment="Top" Height="182">
<Image <Image
Source="/Resources/Img/Album/change_back.png" Source="/Resources/Img/Album/change_back.png"
MouseDown="GoNew"
HorizontalAlignment="Left" HorizontalAlignment="Left"
VerticalAlignment="Top" VerticalAlignment="Top"
Width="330" Width="330"
@ -60,12 +61,6 @@
/> />
</Grid> </Grid>
<Image
gif:ImageBehavior.AnimatedSource="/Resources/Img/Album/3.gif"
gif:ImageBehavior.RepeatBehavior="Forever"
HorizontalAlignment="right"
VerticalAlignment="Top"
Margin="100,120,200,20"
/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -11,8 +11,10 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Animation; using System.Windows.Media.Animation;
using Wpf_AiSportsMicrospace;
using Wpf_AiSportsMicrospace.Common; using Wpf_AiSportsMicrospace.Common;
using Wpf_AiSportsMicrospace.Enum; using Wpf_AiSportsMicrospace.Enum;
using Wpf_AiSportsMicrospace.MyUserControl; using Wpf_AiSportsMicrospace.MyUserControl;
@ -38,7 +40,6 @@ namespace Wpf_AiSportsMicrospace
private SportOperate _sportOperate; private SportOperate _sportOperate;
public static Uri loadingImage = new Uri("/Resources/Img/Album/1.gif", UriKind.Relative); public static Uri loadingImage = new Uri("/Resources/Img/Album/1.gif", UriKind.Relative);
public Home() public Home()
{ {
InitializeComponent(); InitializeComponent();
@ -70,19 +71,19 @@ namespace Wpf_AiSportsMicrospace
private void Window_Loaded(object sender, RoutedEventArgs e) private void Window_Loaded(object sender, RoutedEventArgs e)
{ {
//_sportOperate = new SportOperate(); _sportOperate = new SportOperate();
//_webcamClient = _sportOperate.CreateRTSP(); _webcamClient = _sportOperate.CreateRTSP();
//_webcamClient.OnExtractFrame += frame => _webcamClient.OnExtractFrame += frame =>
//{ {
// if (frame != null) if (frame != null)
// _frameQueue.Enqueue(frame); _frameQueue.Enqueue(frame);
//}; };
//_webcamClient.StartExtract(); _webcamClient.StartExtract();
StartFrameProcessing(); StartFrameProcessing();
Utils.PlayBackgroundMusic("homeprojectselected.mp3"); //Utils.PlayBackgroundMusic("homeprojectselected.mp3");
//coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted; //coverFlow.ProgressCompleted += CoverFlow_ProgressCompleted;
} }
@ -105,7 +106,7 @@ namespace Wpf_AiSportsMicrospace
//coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted; //coverFlow.ProgressCompleted -= CoverFlow_ProgressCompleted;
// 根据图片跳转新窗口 // 根据图片跳转新窗口
string uri = item.ImageUri.ToString(); //string uri = item.ImageUri.ToString();
//if (uri.EndsWith("1.jpg")) //if (uri.EndsWith("1.jpg"))
// newWindow = new GroupJumpRope(); // newWindow = new GroupJumpRope();
@ -115,12 +116,13 @@ namespace Wpf_AiSportsMicrospace
// newWindow = new GroupJumpRope(); // newWindow = new GroupJumpRope();
// 找到主窗口,切换内容到 GroupJumpRopePage // 找到主窗口,切换内容到 GroupJumpRopePage
var mainWin = Application.Current.MainWindow as Main; //var mainWin = Application.Current.MainWindow as Main;
if (mainWin != null) //if (mainWin != null)
{ //{
Utils.PlayBackgroundMusic("musicjumprope1.mp3"); // Utils.PlayBackgroundMusic("musicjumprope1.mp3");
mainWin.SwitchPage(new GroupJumpRope(), true); // mainWin.SwitchPage(new GroupJumpRope(), true);
} //}
RouterGoNew();
} }
private void StartFrameProcessing() private void StartFrameProcessing()
@ -215,5 +217,31 @@ namespace Wpf_AiSportsMicrospace
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
//测试点击
private void GoNew(object sender, MouseButtonEventArgs e)
{
// 跳转逻辑(如导航到新页面并传递参数)
// 例如RaiseEvent、调用外部委托、或使用导航框架
var mainWin = Application.Current.MainWindow as Main;
var newPage = new CenterHome
{
NowSelect = coverFlow.SelectedIndex == 0 ? "test" : "play"
};
mainWin?.SwitchPage(newPage, true);
}
//跳转二级页面
private void RouterGoNew()
{
// 跳转逻辑(如导航到新页面并传递参数)
// 例如RaiseEvent、调用外部委托、或使用导航框架
var mainWin = Application.Current.MainWindow as Main;
var newPage = new CenterHome
{
NowSelect = coverFlow.SelectedIndex == 0 ? "test" : "play"
};
mainWin?.SwitchPage(newPage, true);
}
} }
} }

View File

@ -27,15 +27,79 @@ namespace Wpf_AiSportsMicrospace.Views
// 默认显示首页 // 默认显示首页
MainContent.Content = new Home(); 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);
// }
//}
public void SwitchPage(UserControl newPage, bool fromRight) public void SwitchPage(UserControl newPage, bool fromRight)
{ {
if (MainContent.Content == newPage) return; if (MainContent.Content == newPage) return;
var oldPage = MainContent.Content as UserControl; var oldPage = MainContent.Content as UserControl;
// 预加载新页面资源
PreloadPageResources(newPage);
if (oldPage != null) if (oldPage != null)
{ {
// 旧页面动画 MainContent.Content = null;
// 创建容器同时显示新旧页面
var container = new Grid();
container.Children.Add(newPage); // 新页面在底层
container.Children.Add(oldPage); // 旧页面在顶层
MainContent.Content = container;
// 设置新页面初始状态 - 轻微缩放和偏移
var newTransformGroup = new TransformGroup();
var newScale = new ScaleTransform(0.95, 0.95);
var newTranslate = new TranslateTransform(fromRight ? 80 : -80, 0);
newTransformGroup.Children.Add(newScale);
newTransformGroup.Children.Add(newTranslate);
newPage.RenderTransformOrigin = new Point(0.5, 0.5);
newPage.RenderTransform = newTransformGroup;
newPage.Opacity = 1;
// 旧页面动画 - 飞出效果
var oldTransformGroup = new TransformGroup(); var oldTransformGroup = new TransformGroup();
var oldScale = new ScaleTransform(1, 1); var oldScale = new ScaleTransform(1, 1);
var oldSkew = new SkewTransform(0, 0); var oldSkew = new SkewTransform(0, 0);
@ -43,33 +107,74 @@ namespace Wpf_AiSportsMicrospace.Views
oldTransformGroup.Children.Add(oldScale); oldTransformGroup.Children.Add(oldScale);
oldTransformGroup.Children.Add(oldSkew); oldTransformGroup.Children.Add(oldSkew);
oldTransformGroup.Children.Add(oldTranslate); oldTransformGroup.Children.Add(oldTranslate);
oldPage.RenderTransformOrigin = new Point(fromRight ? 1 : 0, 0.5); // 左右翻页中心 oldPage.RenderTransformOrigin = new Point(fromRight ? 1 : 0, 0.5);
oldPage.RenderTransform = oldTransformGroup; oldPage.RenderTransform = oldTransformGroup;
oldPage.Opacity = 1;
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 duration = TimeSpan.FromMilliseconds(1200);
var fadeAnim = new DoubleAnimation(1, 0.2, TimeSpan.FromMilliseconds(600)); var easing = new CubicEase { EasingMode = EasingMode.EaseInOut };
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); var oldScaleAnim = new DoubleAnimation(1, 1.1, duration) { EasingFunction = easing };
oldSkew.BeginAnimation(SkewTransform.AngleYProperty, skewAnim); var oldSkewAnim = new DoubleAnimation(0, fromRight ? 15 : -15, duration) { EasingFunction = easing };
oldTranslate.BeginAnimation(TranslateTransform.XProperty, translateAnim); var oldTranslateAnim = new DoubleAnimation(0, fromRight ? ActualWidth * 1.1 : -ActualWidth * 1.1, duration)
oldPage.BeginAnimation(OpacityProperty, fadeAnim);
fadeAnim.Completed += (s, e) =>
{ {
EasingFunction = easing
};
// 新页面进入动画
var newScaleAnim = new DoubleAnimation(0.8, 1, duration) { EasingFunction = easing };
var newTranslateAnim = new DoubleAnimation(fromRight ? -80 : -80, 0, duration) { EasingFunction = easing };
// 开始动画
oldScale.BeginAnimation(ScaleTransform.ScaleXProperty, oldScaleAnim);
oldScale.BeginAnimation(ScaleTransform.ScaleYProperty, oldScaleAnim);
oldSkew.BeginAnimation(SkewTransform.AngleYProperty, oldSkewAnim);
oldTranslate.BeginAnimation(TranslateTransform.XProperty, oldTranslateAnim);
newScale.BeginAnimation(ScaleTransform.ScaleXProperty, newScaleAnim);
newScale.BeginAnimation(ScaleTransform.ScaleYProperty, newScaleAnim);
newTranslate.BeginAnimation(TranslateTransform.XProperty, newTranslateAnim);
// 动画完成后清理
oldTranslateAnim.Completed += (s, e) =>
{
// 确保最终状态
newPage.RenderTransform = null;
newPage.Opacity = 1;
// 切换到只有新页面
MainContent.Content = newPage; MainContent.Content = newPage;
AnimateNewPageEnhanced(newPage, fromRight);
// 清理资源
if (oldPage is IDisposable disposable)
disposable.Dispose();
container.Children.Clear();
}; };
} }
else else
{ {
MainContent.Content = newPage; MainContent.Content = newPage;
AnimateNewPageEnhanced(newPage, fromRight); newPage.Opacity = 1;
} }
} }
private void PreloadPageResources(UserControl page)
{
// 先从原来的父容器中移除页面(如果存在)
if (page.Parent != null)
{
var parent = page.Parent as Panel;
parent?.Children.Remove(page);
}
// 强制WPF加载所有资源
page.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
page.Arrange(new Rect(0, 0, page.DesiredSize.Width, page.DesiredSize.Height));
}
private void AnimateNewPageEnhanced(UserControl newPage, bool fromRight) private void AnimateNewPageEnhanced(UserControl newPage, bool fromRight)
{ {
var transformGroup = new TransformGroup(); var transformGroup = new TransformGroup();

View File

@ -38,6 +38,16 @@
<None Remove="Resources\Img\gif\1.gif" /> <None Remove="Resources\Img\gif\1.gif" />
<None Remove="Resources\Img\gif\2.gif" /> <None Remove="Resources\Img\gif\2.gif" />
<None Remove="Resources\Img\gif\3.gif" /> <None Remove="Resources\Img\gif\3.gif" />
<None Remove="Resources\Img\play_img\play_home_bg.png" />
<None Remove="Resources\Img\play_img\play_home_title.png" />
<None Remove="Resources\Img\play_img\play_jump.png" />
<None Remove="Resources\Img\play_img\play_music.png" />
<None Remove="Resources\Img\play_img\play_vs.png" />
<None Remove="Resources\Img\test_img\test_home_bg.png" />
<None Remove="Resources\Img\test_img\test_home_title.png" />
<None Remove="Resources\Img\test_img\test_jump.png" />
<None Remove="Resources\Img\test_img\test_rope.png" />
<None Remove="Resources\Img\test_img\test_situp.png" />
<None Remove="Resources\Music\homeprojectselected.mp3" /> <None Remove="Resources\Music\homeprojectselected.mp3" />
<None Remove="Resources\Music\homeprojectselected1.mp3" /> <None Remove="Resources\Music\homeprojectselected1.mp3" />
<None Remove="Resources\Music\musicjumprope.mp3" /> <None Remove="Resources\Music\musicjumprope.mp3" />
@ -170,6 +180,36 @@
<Resource Include="Resources\Img\gif\3.gif"> <Resource Include="Resources\Img\gif\3.gif">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource> </Resource>
<Resource Include="Resources\Img\play_img\play_home_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\play_img\play_home_title.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\play_img\play_jump.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\play_img\play_music.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\play_img\play_vs.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_home_bg.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_home_title.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_jump.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_rope.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Img\test_img\test_situp.png">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Music\homeprojectselected.mp3"> <Resource Include="Resources\Music\homeprojectselected.mp3">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource> </Resource>