Merge branch 'dev' of http://8.153.108.90:3000/YD/Wpf_AiSportsMicrospace into dev
@ -229,7 +229,7 @@ namespace Wpf_AiSportsMicrospace.Common
|
||||
if (k.Name != "right_ankle" && k.Name != "left_ankle")
|
||||
continue;
|
||||
|
||||
double x = k.X;
|
||||
double x = 1920 - k.X;
|
||||
double y = k.Y;
|
||||
|
||||
if (Math.Abs(x - cx) <= halfW &&
|
||||
|
||||
@ -367,7 +367,7 @@ namespace Wpf_AiSportsMicrospace.Common
|
||||
{
|
||||
cfg.Point1, cfg.Point2, cfg.Point3,
|
||||
cfg.Point4, cfg.Point5, cfg.Point6,
|
||||
cfg.Point7, cfg.Point8, cfg.Point9, cfg.Point10
|
||||
cfg.Point7, cfg.Point8, cfg.Point9
|
||||
};
|
||||
|
||||
// 取前 pointCount 个点
|
||||
|
||||
@ -1,57 +1,154 @@
|
||||
<UserControl x:Class="Wpf_AiSportsMicrospace.MyUserControl.CoverFlowControl"
|
||||
<UserControl x:Class="Wpf_AiSportsMicrospace.MyUserControl.CoverFlowControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:Wpf_AiSportsMicrospace.MyUserControl"
|
||||
Width="1080">
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="900"
|
||||
d:DesignWidth="1920">
|
||||
<UserControl.Resources>
|
||||
<BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||
<local:ProgressToRectangleGeometryConverter x:Key="ProgressToRectangleGeometryConverter"/>
|
||||
|
||||
<!-- 单张卡片模板:中间卡片(选中)发光 + 进度条 -->
|
||||
<DataTemplate x:Key="CardTemplate" DataType="{x:Type local:CoverFlowItem}">
|
||||
<ContentControl x:Name="ImageContainer"
|
||||
Width="346"
|
||||
Height="534"
|
||||
Background="Transparent"
|
||||
BorderThickness="4"
|
||||
BorderBrush="#00FFFFFF"
|
||||
SnapsToDevicePixels="True">
|
||||
<!-- 用 ContentControl.Template 承载 Border + 呼吸灯 Trigger -->
|
||||
<ContentControl.Style>
|
||||
<Style TargetType="{x:Type ContentControl}">
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type ContentControl}">
|
||||
<Border x:Name="Root"
|
||||
Width="{TemplateBinding Width}"
|
||||
Height="{TemplateBinding Height}"
|
||||
CornerRadius="28"
|
||||
Background="{TemplateBinding Background}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
BorderBrush="{TemplateBinding BorderBrush}"
|
||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
|
||||
<Border.Effect>
|
||||
<DropShadowEffect x:Name="GlowEffect"
|
||||
Color="#FF57D7FF"
|
||||
BlurRadius="0"
|
||||
ShadowDepth="0"
|
||||
Opacity="0"/>
|
||||
</Border.Effect>
|
||||
<ContentPresenter/>
|
||||
</Border>
|
||||
|
||||
<ControlTemplate.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="True">
|
||||
<Setter TargetName="Root" Property="BorderBrush">
|
||||
<Setter.Value>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Offset="0" Color="#FF8AE6FF"/>
|
||||
<GradientStop Offset="1" Color="#FF2B73FF"/>
|
||||
</LinearGradientBrush>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard x:Name="BreathingGlowStoryboard">
|
||||
<Storyboard RepeatBehavior="Forever" AutoReverse="True">
|
||||
<DoubleAnimation Storyboard.TargetName="GlowEffect"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
From="0.35" To="0.95"
|
||||
Duration="0:0:0.8"/>
|
||||
<DoubleAnimation Storyboard.TargetName="GlowEffect"
|
||||
Storyboard.TargetProperty="BlurRadius"
|
||||
From="14" To="34"
|
||||
Duration="0:0:0.8"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
<DataTrigger.ExitActions>
|
||||
<StopStoryboard BeginStoryboardName="BreathingGlowStoryboard"/>
|
||||
</DataTrigger.ExitActions>
|
||||
</DataTrigger>
|
||||
|
||||
<DataTrigger Binding="{Binding IsSelected}" Value="False">
|
||||
<Setter TargetName="Root" Property="BorderBrush" Value="#00FFFFFF"/>
|
||||
<DataTrigger.EnterActions>
|
||||
<BeginStoryboard>
|
||||
<Storyboard>
|
||||
<DoubleAnimation Storyboard.TargetName="GlowEffect"
|
||||
Storyboard.TargetProperty="Opacity"
|
||||
To="0"
|
||||
Duration="0:0:0.15"/>
|
||||
<DoubleAnimation Storyboard.TargetName="GlowEffect"
|
||||
Storyboard.TargetProperty="BlurRadius"
|
||||
To="0"
|
||||
Duration="0:0:0.15"/>
|
||||
</Storyboard>
|
||||
</BeginStoryboard>
|
||||
</DataTrigger.EnterActions>
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
</ContentControl.Style>
|
||||
|
||||
<Grid ClipToBounds="False">
|
||||
<Image Source="{Binding ImageUri}"
|
||||
Stretch="UniformToFill"
|
||||
Width="308"
|
||||
Height="514"/>
|
||||
|
||||
<Path StrokeThickness="12"
|
||||
Visibility="{Binding IsSelected, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
StrokeStartLineCap="Flat"
|
||||
StrokeEndLineCap="Flat"
|
||||
Data="{Binding Progress, Converter={StaticResource ProgressToRectangleGeometryConverter}, ConverterParameter='328,534,24,12'}">
|
||||
<Path.Stroke>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientStop Offset="0" Color="{Binding ProgressColor1}"/>
|
||||
<GradientStop Offset="0.9" Color="{Binding ProgressColor2}"/>
|
||||
</LinearGradientBrush>
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
</Grid>
|
||||
</ContentControl>
|
||||
</DataTemplate>
|
||||
</UserControl.Resources>
|
||||
<Grid ClipToBounds="False" Background="Transparent">
|
||||
<ItemsControl x:Name="ItemsHost" ItemsSource="{Binding Images, RelativeSource={RelativeSource AncestorType=UserControl}}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Canvas/>
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<Grid Background="Transparent" ClipToBounds="False">
|
||||
<!-- 轮播视口(显示 5 张),卡片发光允许溢出所以外层不裁剪 -->
|
||||
<Canvas x:Name="CarouselCanvas"
|
||||
Width="1760"
|
||||
Height="580"
|
||||
Background="Transparent"
|
||||
Focusable="True"
|
||||
PreviewKeyDown="Carousel_PreviewKeyDown"
|
||||
PreviewMouseWheel="Carousel_PreviewMouseWheel">
|
||||
<!-- 左二/左一/中/右一/右二五张 -->
|
||||
<ContentPresenter x:Name="CardFarLeft"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
MouseLeftButtonUp="CardFarLeft_Click"/>
|
||||
<ContentPresenter x:Name="CardLeft"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
MouseLeftButtonUp="CardLeft_Click"/>
|
||||
<ContentPresenter x:Name="CardCenter"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
MouseLeftButtonUp="CardCenter_Click"/>
|
||||
<ContentPresenter x:Name="CardRight"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
MouseLeftButtonUp="CardRight_Click"/>
|
||||
<ContentPresenter x:Name="CardFarRight"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
MouseLeftButtonUp="CardFarRight_Click"/>
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Border x:Name="ImageContainer" RenderTransformOrigin="0.5,0.5" CornerRadius="28"
|
||||
MouseLeftButtonDown="Image_MouseLeftButtonDown" Background="#fff">
|
||||
<Border.RenderTransform>
|
||||
<TransformGroup>
|
||||
<ScaleTransform x:Name="scale" ScaleX="1" ScaleY="1"/>
|
||||
<TranslateTransform x:Name="translate" X="0" Y="0"/>
|
||||
</TransformGroup>
|
||||
</Border.RenderTransform>
|
||||
<Grid ClipToBounds="False">
|
||||
|
||||
<Grid Width="372" Height="456" Background="Transparent" >
|
||||
<Image Source="{Binding ImageUri}" Stretch="UniformToFill" Width="346" Height="430">
|
||||
<Image.RenderTransform>
|
||||
<TranslateTransform X="0" Y="0"/>
|
||||
</Image.RenderTransform>
|
||||
</Image>
|
||||
</Grid>
|
||||
|
||||
<!-- 矩形进度条 Stroke="{Binding ProgressColor}" -->
|
||||
|
||||
<Path StrokeThickness="13" Visibility="{Binding IsSelected, Converter={StaticResource BoolToVisibilityConverter}}" StrokeStartLineCap="Flat" StrokeEndLineCap="Flat"
|
||||
Data="{Binding Progress, Converter={StaticResource ProgressToRectangleGeometryConverter}, ConverterParameter='372,456,22,13'}">
|
||||
<Path.Stroke>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
|
||||
<GradientStop Offset="0" Color="{Binding ProgressColor1}"/>
|
||||
<GradientStop Offset="0.9" Color="{Binding ProgressColor2}"/>
|
||||
</LinearGradientBrush>
|
||||
</Path.Stroke>
|
||||
</Path>
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
<!-- 预备卡片:用于从右/左滑入 -->
|
||||
<ContentPresenter x:Name="CardSpare"
|
||||
ContentTemplate="{StaticResource CardTemplate}"
|
||||
Opacity="0"/>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@ -1,21 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
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.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
@ -25,9 +14,16 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
/// </summary>
|
||||
public partial class CoverFlowControl : UserControl
|
||||
{// 新增事件:进度条完成
|
||||
public event Action<CoverFlowItem> ProgressCompleted;
|
||||
public event Action<CoverFlowItem>? ProgressCompleted;
|
||||
public ObservableCollection<CoverFlowItem> Images { get; set; } = new ObservableCollection<CoverFlowItem>();
|
||||
private int _selectedIndex = 0;
|
||||
private bool _isAnimating;
|
||||
private int _pendingSlideSteps;
|
||||
|
||||
private const double CardWidth = 346;
|
||||
private const double CardHeight = 534;
|
||||
private const double CardGap = 30; // 卡片之间水平间距
|
||||
private const double SlideDurationMs = 420; // 动画时长
|
||||
|
||||
public int SelectedIndex
|
||||
{
|
||||
@ -40,10 +36,8 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
else if (value >= Images.Count) _selectedIndex = 0;
|
||||
else _selectedIndex = value;
|
||||
|
||||
for (int i = 0; i < Images.Count; i++)
|
||||
Images[i].IsSelected = i == _selectedIndex;
|
||||
|
||||
UpdateLayoutWithAnimation();
|
||||
UpdateSelectionFlags();
|
||||
RefreshCards(instant: true);
|
||||
|
||||
// 启动进度条动画
|
||||
//var current = Images[_selectedIndex];
|
||||
@ -56,7 +50,7 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
{
|
||||
InitializeComponent();
|
||||
DataContext = this;
|
||||
Loaded += (s, e) => UpdateLayoutWithAnimation(true);
|
||||
Loaded += CoverFlowControl_Loaded;
|
||||
|
||||
//var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(5) };
|
||||
//timer.Tick += (s, e) =>
|
||||
@ -68,9 +62,21 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
//};
|
||||
//timer.Start();
|
||||
}
|
||||
private EventHandler _renderHandler;
|
||||
private EventHandler? _renderHandler;
|
||||
|
||||
private CoverFlowItem _currentItem;
|
||||
private CoverFlowItem? _currentItem;
|
||||
|
||||
private void CoverFlowControl_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (Images.Count > 0)
|
||||
{
|
||||
UpdateSelectionFlags();
|
||||
RefreshCards(instant: true);
|
||||
}
|
||||
|
||||
CarouselCanvas.Focus();
|
||||
Keyboard.Focus(CarouselCanvas);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 针对当前选中项启动进度条动画
|
||||
@ -104,25 +110,11 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
_currentItem = item;
|
||||
item.Progress = 0;
|
||||
|
||||
var container = ItemsHost.ItemContainerGenerator.ContainerFromItem(item) as ContentPresenter;
|
||||
if (container == null) return;
|
||||
|
||||
var canvas = FindVisualChild<Canvas>(container);
|
||||
var spark = FindVisualChild<Ellipse>(canvas);
|
||||
if (spark != null)
|
||||
spark.Visibility = Visibility.Visible;
|
||||
|
||||
_renderHandler = (s, e) =>
|
||||
{
|
||||
if (_currentItem.Progress < 1)
|
||||
{
|
||||
_currentItem.Progress += 0.01; // 控制速度
|
||||
if (spark != null)
|
||||
{
|
||||
var pos = GetSparkPosition(_currentItem.Progress, 150, 200);
|
||||
Canvas.SetLeft(spark, pos.X - spark.Width / 2);
|
||||
Canvas.SetTop(spark, pos.Y - spark.Height / 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -147,139 +139,320 @@ namespace Wpf_AiSportsMicrospace.MyUserControl
|
||||
if (_currentItem != null)
|
||||
{
|
||||
_currentItem.Progress = 0;
|
||||
//_currentItem.IsSelected = true;
|
||||
|
||||
var container = ItemsHost.ItemContainerGenerator.ContainerFromItem(_currentItem) as ContentPresenter;
|
||||
if (container != null)
|
||||
{
|
||||
var canvas = FindVisualChild<Canvas>(container);
|
||||
var spark = FindVisualChild<Ellipse>(canvas);
|
||||
if (spark != null)
|
||||
spark.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
_currentItem = null;
|
||||
}
|
||||
}
|
||||
|
||||
private Point GetSparkPosition(double progress, double width, double height)
|
||||
private void UpdateSelectionFlags()
|
||||
{
|
||||
double perimeter = 2 * (width + height);
|
||||
double len = progress * perimeter;
|
||||
|
||||
if (len <= width) return new Point(len, 0); // 上边
|
||||
len -= width;
|
||||
if (len <= height) return new Point(width, len); // 右边
|
||||
len -= height;
|
||||
if (len <= width) return new Point(width - len, height); // 下边
|
||||
len -= width;
|
||||
return new Point(0, height - len); // 左边
|
||||
for (int i = 0; i < Images.Count; i++)
|
||||
Images[i].IsSelected = i == _selectedIndex;
|
||||
}
|
||||
|
||||
private void Image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||
private int WrapIndex(int index)
|
||||
{
|
||||
if (sender is Border border)
|
||||
if (Images.Count == 0) return 0;
|
||||
var m = index % Images.Count;
|
||||
if (m < 0) m += Images.Count;
|
||||
return m;
|
||||
}
|
||||
|
||||
private double SlotDistance => CardWidth + CardGap;
|
||||
|
||||
private double XFarLeft => 0;
|
||||
private double XLeft => SlotDistance;
|
||||
private double XCenter => SlotDistance * 2;
|
||||
private double XRight => SlotDistance * 3;
|
||||
private double XFarRight => SlotDistance * 4;
|
||||
private double XOffLeft => -SlotDistance;
|
||||
private double XOffRight => SlotDistance * 5;
|
||||
|
||||
private void SetCard(ContentPresenter card, CoverFlowItem? item, double left, double opacity = 1)
|
||||
{
|
||||
card.Content = item;
|
||||
Canvas.SetLeft(card, left);
|
||||
Canvas.SetTop(card, 0);
|
||||
card.Opacity = opacity;
|
||||
}
|
||||
|
||||
private void RefreshCards(bool instant)
|
||||
{
|
||||
if (Images.Count == 0) return;
|
||||
|
||||
var farLeft = Images[WrapIndex(_selectedIndex - 2)];
|
||||
var left = Images[WrapIndex(_selectedIndex - 1)];
|
||||
var center = Images[WrapIndex(_selectedIndex)];
|
||||
var right = Images[WrapIndex(_selectedIndex + 1)];
|
||||
var farRight = Images[WrapIndex(_selectedIndex + 2)];
|
||||
|
||||
SetCard(CardFarLeft, farLeft, XFarLeft, 1);
|
||||
SetCard(CardLeft, left, XLeft, 1);
|
||||
SetCard(CardCenter, center, XCenter, 1);
|
||||
SetCard(CardRight, right, XRight, 1);
|
||||
SetCard(CardFarRight, farRight, XFarRight, 1);
|
||||
|
||||
// spare stays hidden offscreen
|
||||
SetCard(CardSpare, null, XOffRight, 0);
|
||||
|
||||
if (!instant)
|
||||
return;
|
||||
}
|
||||
|
||||
private void Carousel_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
||||
{
|
||||
if (e.Delta < 0) SlideLeft();
|
||||
else if (e.Delta > 0) SlideRight();
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
private void Carousel_PreviewKeyDown(object sender, KeyEventArgs e)
|
||||
{
|
||||
if (e.Key == Key.Right || e.Key == Key.Down)
|
||||
{
|
||||
var container = ItemsHost.ItemContainerGenerator.ContainerFromItem(border.DataContext) as ContentPresenter;
|
||||
if (container != null)
|
||||
{
|
||||
int index = ItemsHost.ItemContainerGenerator.IndexFromContainer(container);
|
||||
SelectedIndex = index;
|
||||
}
|
||||
SlideLeft();
|
||||
e.Handled = true;
|
||||
}
|
||||
else if (e.Key == Key.Left || e.Key == Key.Up)
|
||||
{
|
||||
SlideRight();
|
||||
e.Handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLayoutWithAnimation(bool instant = false)
|
||||
private void CardLeft_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
double centerX = ActualWidth / 2;
|
||||
double spacing = 530;
|
||||
double sideScale = 0.98;
|
||||
double centerScale = 1.33;
|
||||
RequestSlide(-1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < ItemsHost.Items.Count; i++)
|
||||
private void CardRight_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
RequestSlide(+1);
|
||||
}
|
||||
|
||||
private void CardFarLeft_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
RequestSlide(-2);
|
||||
}
|
||||
|
||||
private void CardFarRight_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
RequestSlide(+2);
|
||||
}
|
||||
|
||||
private void CardCenter_Click(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// center click: treat as selecting current (already selected)
|
||||
}
|
||||
|
||||
private void RequestSlide(int steps)
|
||||
{
|
||||
if (Images.Count == 0) return;
|
||||
if (steps == 0) return;
|
||||
|
||||
_pendingSlideSteps += steps;
|
||||
TryRunNextSlide();
|
||||
}
|
||||
|
||||
private void TryRunNextSlide()
|
||||
{
|
||||
if (_isAnimating) return;
|
||||
if (_pendingSlideSteps == 0) return;
|
||||
|
||||
if (_pendingSlideSteps > 0)
|
||||
{
|
||||
var container = ItemsHost.ItemContainerGenerator.ContainerFromIndex(i) as ContentPresenter;
|
||||
if (container == null) continue;
|
||||
|
||||
var border = FindVisualChild<Border>(container);
|
||||
if (border == null) continue;
|
||||
|
||||
var transformGroup = border.RenderTransform as TransformGroup;
|
||||
var scale = transformGroup.Children[0] as ScaleTransform;
|
||||
var translate = transformGroup.Children[1] as TranslateTransform;
|
||||
|
||||
double targetX;
|
||||
double targetScale;
|
||||
double targetOpacity;
|
||||
|
||||
if (i == SelectedIndex)
|
||||
{
|
||||
targetX = centerX - 175;
|
||||
targetScale = centerScale;
|
||||
targetOpacity = 1.0;
|
||||
}
|
||||
else if (i == SelectedIndex - 1 || (SelectedIndex == 0 && i == Images.Count - 1))
|
||||
{
|
||||
targetX = centerX - spacing -175;
|
||||
targetScale = sideScale;
|
||||
targetOpacity = 1.0;
|
||||
}
|
||||
else if (i == SelectedIndex + 1 || (SelectedIndex == Images.Count - 1 && i == 0))
|
||||
{
|
||||
targetX = centerX + spacing - 175;
|
||||
targetScale = sideScale;
|
||||
targetOpacity = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
targetX = centerX - 175;
|
||||
targetScale = sideScale;
|
||||
targetOpacity = 0.0;
|
||||
}
|
||||
|
||||
if (instant)
|
||||
{
|
||||
translate.X = targetX;
|
||||
scale.ScaleX = scale.ScaleY = targetScale;
|
||||
border.Opacity = targetOpacity;
|
||||
}
|
||||
else
|
||||
{
|
||||
translate.BeginAnimation(TranslateTransform.XProperty,
|
||||
new DoubleAnimation(targetX, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
|
||||
scale.BeginAnimation(ScaleTransform.ScaleXProperty,
|
||||
new DoubleAnimation(targetScale, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
|
||||
scale.BeginAnimation(ScaleTransform.ScaleYProperty,
|
||||
new DoubleAnimation(targetScale, TimeSpan.FromMilliseconds(400)) { EasingFunction = new QuadraticEase() });
|
||||
border.BeginAnimation(Border.OpacityProperty,
|
||||
new DoubleAnimation(targetOpacity, TimeSpan.FromMilliseconds(400)));
|
||||
}
|
||||
_pendingSlideSteps--;
|
||||
AnimateLeftOne();
|
||||
}
|
||||
else
|
||||
{
|
||||
_pendingSlideSteps++;
|
||||
AnimateRightOne();
|
||||
}
|
||||
}
|
||||
|
||||
private static T FindVisualChild<T>(DependencyObject obj) where T : DependencyObject
|
||||
private void AnimateLeftOne()
|
||||
{
|
||||
if (obj == null) return null;
|
||||
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
|
||||
if (_isAnimating) return;
|
||||
if (Images.Count == 0) return;
|
||||
|
||||
_isAnimating = true;
|
||||
StopProgress();
|
||||
|
||||
var newSelected = WrapIndex(_selectedIndex + 1);
|
||||
var incomingFarRight = Images[WrapIndex(newSelected + 2)];
|
||||
|
||||
// Prepare spare entering from the right (to far-right slot)
|
||||
SetCard(CardSpare, incomingFarRight, XOffRight, 1);
|
||||
|
||||
var sb = new Storyboard { FillBehavior = FillBehavior.Stop };
|
||||
var ease = new CubicEase { EasingMode = EasingMode.EaseOut };
|
||||
var dur = TimeSpan.FromMilliseconds(SlideDurationMs);
|
||||
|
||||
void AddMove(FrameworkElement fe, double toX)
|
||||
{
|
||||
var child = VisualTreeHelper.GetChild(obj, i);
|
||||
if (child is T target) return target;
|
||||
var result = FindVisualChild<T>(child);
|
||||
if (result != null) return result;
|
||||
var anim = new DoubleAnimation
|
||||
{
|
||||
To = toX,
|
||||
Duration = new Duration(dur),
|
||||
EasingFunction = ease
|
||||
};
|
||||
Storyboard.SetTarget(anim, fe);
|
||||
Storyboard.SetTargetProperty(anim, new PropertyPath("(Canvas.Left)"));
|
||||
sb.Children.Add(anim);
|
||||
}
|
||||
return null;
|
||||
|
||||
void AddFade(FrameworkElement fe, double toOpacity)
|
||||
{
|
||||
var anim = new DoubleAnimation
|
||||
{
|
||||
To = toOpacity,
|
||||
Duration = new Duration(dur),
|
||||
EasingFunction = ease
|
||||
};
|
||||
Storyboard.SetTarget(anim, fe);
|
||||
Storyboard.SetTargetProperty(anim, new PropertyPath("Opacity"));
|
||||
sb.Children.Add(anim);
|
||||
}
|
||||
|
||||
// Far-left card slides out to left and fades
|
||||
AddMove(CardFarLeft, XOffLeft);
|
||||
AddFade(CardFarLeft, 0);
|
||||
|
||||
// Shift others left by one slot, spare enters to far-right
|
||||
AddMove(CardLeft, XFarLeft);
|
||||
AddMove(CardCenter, XLeft);
|
||||
AddMove(CardRight, XCenter);
|
||||
AddMove(CardFarRight, XRight);
|
||||
AddMove(CardSpare, XFarRight);
|
||||
|
||||
sb.Completed += (_, _) =>
|
||||
{
|
||||
_selectedIndex = newSelected;
|
||||
UpdateSelectionFlags();
|
||||
|
||||
// After shift left:
|
||||
// new FarLeft = old Left
|
||||
// new Left = old Center
|
||||
// new Center = old Right
|
||||
// new Right = old FarRight
|
||||
// new FarRight = old Spare
|
||||
var oldFarLeftContent = (CoverFlowItem?)CardFarLeft.Content;
|
||||
var oldLeftContent = (CoverFlowItem?)CardLeft.Content;
|
||||
var oldCenterContent = (CoverFlowItem?)CardCenter.Content;
|
||||
var oldRightContent = (CoverFlowItem?)CardRight.Content;
|
||||
var oldFarRightContent = (CoverFlowItem?)CardFarRight.Content;
|
||||
var oldSpareContent = (CoverFlowItem?)CardSpare.Content;
|
||||
|
||||
SetCard(CardFarLeft, oldLeftContent, XFarLeft, 1);
|
||||
SetCard(CardLeft, oldCenterContent, XLeft, 1);
|
||||
SetCard(CardCenter, oldRightContent, XCenter, 1);
|
||||
SetCard(CardRight, oldFarRightContent, XRight, 1);
|
||||
SetCard(CardFarRight, oldSpareContent, XFarRight, 1);
|
||||
|
||||
SetCard(CardSpare, null, XOffRight, 0);
|
||||
|
||||
_isAnimating = false;
|
||||
TryRunNextSlide();
|
||||
};
|
||||
|
||||
sb.Begin(this, true);
|
||||
}
|
||||
|
||||
private void AnimateRightOne()
|
||||
{
|
||||
if (_isAnimating) return;
|
||||
if (Images.Count == 0) return;
|
||||
|
||||
_isAnimating = true;
|
||||
StopProgress();
|
||||
|
||||
var newSelected = WrapIndex(_selectedIndex - 1);
|
||||
var incomingFarLeft = Images[WrapIndex(newSelected - 2)];
|
||||
|
||||
// Prepare spare entering from the left (to far-left slot)
|
||||
SetCard(CardSpare, incomingFarLeft, XOffLeft, 1);
|
||||
|
||||
var sb = new Storyboard { FillBehavior = FillBehavior.Stop };
|
||||
var ease = new CubicEase { EasingMode = EasingMode.EaseOut };
|
||||
var dur = TimeSpan.FromMilliseconds(SlideDurationMs);
|
||||
|
||||
void AddMove(FrameworkElement fe, double toX)
|
||||
{
|
||||
var anim = new DoubleAnimation
|
||||
{
|
||||
To = toX,
|
||||
Duration = new Duration(dur),
|
||||
EasingFunction = ease
|
||||
};
|
||||
Storyboard.SetTarget(anim, fe);
|
||||
Storyboard.SetTargetProperty(anim, new PropertyPath("(Canvas.Left)"));
|
||||
sb.Children.Add(anim);
|
||||
}
|
||||
|
||||
void AddFade(FrameworkElement fe, double toOpacity)
|
||||
{
|
||||
var anim = new DoubleAnimation
|
||||
{
|
||||
To = toOpacity,
|
||||
Duration = new Duration(dur),
|
||||
EasingFunction = ease
|
||||
};
|
||||
Storyboard.SetTarget(anim, fe);
|
||||
Storyboard.SetTargetProperty(anim, new PropertyPath("Opacity"));
|
||||
sb.Children.Add(anim);
|
||||
}
|
||||
|
||||
// Far-right card slides out to right and fades
|
||||
AddMove(CardFarRight, XOffRight);
|
||||
AddFade(CardFarRight, 0);
|
||||
|
||||
// Shift others right by one slot, spare enters to far-left
|
||||
AddMove(CardRight, XFarRight);
|
||||
AddMove(CardCenter, XRight);
|
||||
AddMove(CardLeft, XCenter);
|
||||
AddMove(CardFarLeft, XLeft);
|
||||
AddMove(CardSpare, XFarLeft);
|
||||
|
||||
sb.Completed += (_, _) =>
|
||||
{
|
||||
_selectedIndex = newSelected;
|
||||
UpdateSelectionFlags();
|
||||
|
||||
var oldFarLeftContent = (CoverFlowItem?)CardFarLeft.Content;
|
||||
var oldLeftContent = (CoverFlowItem?)CardLeft.Content;
|
||||
var oldCenterContent = (CoverFlowItem?)CardCenter.Content;
|
||||
var oldRightContent = (CoverFlowItem?)CardRight.Content;
|
||||
var oldFarRightContent = (CoverFlowItem?)CardFarRight.Content;
|
||||
var oldSpareContent = (CoverFlowItem?)CardSpare.Content;
|
||||
|
||||
// After shift right:
|
||||
// new FarRight = old Right
|
||||
// new Right = old Center
|
||||
// new Center = old Left
|
||||
// new Left = old FarLeft
|
||||
// new FarLeft = old Spare
|
||||
SetCard(CardFarRight, oldRightContent, XFarRight, 1);
|
||||
SetCard(CardRight, oldCenterContent, XRight, 1);
|
||||
SetCard(CardCenter, oldLeftContent, XCenter, 1);
|
||||
SetCard(CardLeft, oldFarLeftContent, XLeft, 1);
|
||||
SetCard(CardFarLeft, oldSpareContent, XFarLeft, 1);
|
||||
|
||||
SetCard(CardSpare, null, XOffRight, 0);
|
||||
|
||||
_isAnimating = false;
|
||||
TryRunNextSlide();
|
||||
};
|
||||
|
||||
sb.Begin(this, true);
|
||||
}
|
||||
|
||||
|
||||
public void SlideLeft()
|
||||
{
|
||||
StopProgress();
|
||||
SelectedIndex++;
|
||||
RequestSlide(+1);
|
||||
}
|
||||
public void SlideRight()
|
||||
{
|
||||
StopProgress();
|
||||
SelectedIndex--;
|
||||
RequestSlide(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,23 +13,25 @@
|
||||
<Grid>
|
||||
|
||||
<!--<Border Background="#60000000" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
|
||||
<Image Source="/Resources/Img/test_img/one_rope/top_bg.png" Width="224"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,0,0,0"/>
|
||||
<Image Source="/Resources/Img/new/group/top_bg.png" Width="294"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="26,398,0,0" Height="117"/>
|
||||
<!--<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}"-->
|
||||
<TextBlock Text="{Binding DisplayText, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontSize="26"
|
||||
Foreground="#fff"
|
||||
FontWeight="Bold"
|
||||
FontStyle="Italic"
|
||||
Margin="-17,4,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="28,437,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"/>
|
||||
<!--<TextBlock Text="{Binding NumberText, RelativeSource={RelativeSource AncestorType=UserControl}}"-->
|
||||
<TextBlock Text="{Binding NumberText, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontSize="36"
|
||||
Foreground="#000"
|
||||
FontWeight="Bold"
|
||||
FontStyle="Italic"
|
||||
Margin="0,45,0,0"
|
||||
HorizontalAlignment="Center"
|
||||
Margin="159,431,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"/>
|
||||
|
||||
<!--<Image Source="/Resources/Img/test_img/one_rope/out_user.png" Width="250" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,131,0,0"
|
||||
@ -46,20 +48,21 @@
|
||||
Margin="0,131,0,0"
|
||||
Visibility="{Binding ImageState, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource ImageStateToVisibilityConverter}, ConverterParameter=2}" />-->
|
||||
|
||||
<Image Source="/Resources/Img/test_img/one_rope/out_user.png" Width="230" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,151,0,0"
|
||||
<Image Source="/Resources/Img/new/group/out.png" Width="180" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,45,0,0"
|
||||
x:Name="image3" Visibility="Hidden"/>
|
||||
<Image Source="/Resources/Img/test_img/one_rope/pre_user.png" Width="230" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,151,0,0"
|
||||
<Image Source="/Resources/Img/new/group/pre_user.png" Width="180" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,45,0,0"
|
||||
x:Name="image1" Visibility="Collapsed" />
|
||||
<!--<Image Source="/Resources/Img/test_img/one_rope/nopeople.png" Width="270" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,131,0,0"
|
||||
x:Name="image0" Visibility="Collapsed"/>-->
|
||||
<Image gif:ImageBehavior.AnimatedSource="/Resources/Img/test_img/one_rope/jump_rope.gif"
|
||||
<Image gif:ImageBehavior.AnimatedSource="/Resources/Img/new/group/jump_rope.gif"
|
||||
x:Name="image2"
|
||||
gif:ImageBehavior.AutoStart="True"
|
||||
gif:ImageBehavior.RepeatBehavior="Forever"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Width="345"
|
||||
Margin="0,91,0,0"
|
||||
gif:ImageBehavior.RepeatBehavior="Forever"
|
||||
gif:ImageBehavior.AnimateInDesignMode="True"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Top"
|
||||
Width="345"
|
||||
Margin="-33,-88,0,0" Height="594"
|
||||
/>
|
||||
|
||||
</Grid>
|
||||
|
||||
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/jump_rope.gif
Normal file
|
After Width: | Height: | Size: 2.6 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/out.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/pre_user.png
Normal file
|
After Width: | Height: | Size: 149 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/test_bg.png
Normal file
|
After Width: | Height: | Size: 5.1 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/test_title.png
Normal file
|
After Width: | Height: | Size: 154 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/group/top_bg.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/card_1.png
Normal file
|
After Width: | Height: | Size: 468 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/card_2.png
Normal file
|
After Width: | Height: | Size: 552 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/card_3.png
Normal file
|
After Width: | Height: | Size: 512 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/card_4.png
Normal file
|
After Width: | Height: | Size: 304 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/card_5.png
Normal file
|
After Width: | Height: | Size: 373 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/home_bg.png
Normal file
|
After Width: | Height: | Size: 2.4 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/home/home_title.png
Normal file
|
After Width: | Height: | Size: 455 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/bottom - 复制.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/bottom.png
Normal file
|
After Width: | Height: | Size: 42 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/head_top.png
Normal file
|
After Width: | Height: | Size: 123 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/jump_bg.jpg
Normal file
|
After Width: | Height: | Size: 1.9 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/jumping.gif
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/jumping1.gif
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/mat.png
Normal file
|
After Width: | Height: | Size: 828 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/mat1.png
Normal file
|
After Width: | Height: | Size: 502 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/people.png
Normal file
|
After Width: | Height: | Size: 259 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/right_hand.gif
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 85 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/rotate_img.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/tip.png
Normal file
|
After Width: | Height: | Size: 417 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/title.png
Normal file
|
After Width: | Height: | Size: 124 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/top.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
Wpf_AiSportsMicrospace/Resources/Img/new/long/win_bg.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
@ -5,13 +5,13 @@
|
||||
xmlns:gif="http://wpfanimatedgif.codeplex.com"
|
||||
xmlns:hc="https://handyorg.github.io/handycontrol"
|
||||
Height="1080" Width="1920" Loaded="Window_Loaded" Unloaded="Home_Unloaded">
|
||||
<Grid VerticalAlignment="Bottom">
|
||||
<Grid VerticalAlignment="Bottom" Height="1080" Width="1920">
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="/Resources/Img/Album/home_bg.png" Stretch="UniformToFill"/>
|
||||
<ImageBrush ImageSource="/Resources/Img/new/home/home_bg.png" Stretch="UniformToFill"/>
|
||||
</Grid.Background>
|
||||
<!-- 顶部图片 -->
|
||||
<Image
|
||||
Source="/Resources/Img/Album/title.png"
|
||||
Source="/Resources/Img/new/home/home_title.png"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Width="615"
|
||||
@ -26,7 +26,7 @@
|
||||
VerticalAlignment="Top"
|
||||
Height="900"
|
||||
Width="1920"
|
||||
Margin="0,180,0,0"
|
||||
Margin="0,60,0,0"
|
||||
Padding="0,100"
|
||||
/>
|
||||
<Grid Margin="314,833,214,0" VerticalAlignment="Top" Height="182">
|
||||
@ -66,14 +66,7 @@
|
||||
|
||||
|
||||
</Grid>
|
||||
<Image
|
||||
gif:ImageBehavior.AnimatedSource="/Resources/Img/Album/leight.gif"
|
||||
gif:ImageBehavior.RepeatBehavior="Forever"
|
||||
gif:ImageBehavior.AnimateInDesignMode="True"
|
||||
VerticalAlignment="Top"
|
||||
Margin="20,80,0,0"
|
||||
Width="880"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
<!-- 隐藏的管理员触发按钮(右上角)-->
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
using AiSportsMicrospaceDB.DBContext;
|
||||
using AiSportsMicrospaceDB.DBContext;
|
||||
using AiSportsMicrospaceDB.Entities;
|
||||
using Common;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -48,13 +48,13 @@ namespace Wpf_AiSportsMicrospace
|
||||
// --------------------- CoverFlow 加载 ---------------------
|
||||
coverFlow.Images.Add(new CoverFlowItem
|
||||
{
|
||||
ImageUri = GetResourceUri("test_img/test_rope.png"),
|
||||
ImageUri = GetResourceUri("new/home/card_1.png"),
|
||||
ProgressColor1 = "#215bc7",
|
||||
ProgressColor2 = "#fc640e",
|
||||
});
|
||||
coverFlow.Images.Add(new CoverFlowItem
|
||||
{
|
||||
ImageUri = GetResourceUri("play_img/play_music.png"),
|
||||
ImageUri = GetResourceUri("new/home/card_2.png"),
|
||||
ProgressColor1 = "#e73d42",
|
||||
ProgressColor2 = "#fd8212"
|
||||
|
||||
@ -62,11 +62,25 @@ namespace Wpf_AiSportsMicrospace
|
||||
coverFlow.Images.Add(new CoverFlowItem
|
||||
{
|
||||
//ImageUri = GetResourceUri("Album/home_history.png"),
|
||||
ImageUri = GetResourceUri("play_img/whack_mole.png"),
|
||||
ImageUri = GetResourceUri("new/home/card_3.png"),
|
||||
ProgressColor1 = "#e73d42",
|
||||
ProgressColor2 = "#215bc7"
|
||||
});
|
||||
|
||||
// 为了演示 5 个入口,这里复用前面 3 张图补足到 5 张
|
||||
coverFlow.Images.Add(new CoverFlowItem
|
||||
{
|
||||
ImageUri = GetResourceUri("new/home/card_4.png"),
|
||||
ProgressColor1 = "#215bc7",
|
||||
ProgressColor2 = "#fc640e",
|
||||
});
|
||||
coverFlow.Images.Add(new CoverFlowItem
|
||||
{
|
||||
ImageUri = GetResourceUri("new/home/card_5.png"),
|
||||
ProgressColor1 = "#e73d42",
|
||||
ProgressColor2 = "#fd8212"
|
||||
});
|
||||
|
||||
// 默认选中第3张
|
||||
coverFlow.SelectedIndex = 0;
|
||||
Loaded += Window_Loaded;
|
||||
|
||||
@ -9,27 +9,27 @@
|
||||
Height="1080" Width="1920" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
|
||||
<Grid>
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="/Resources/Img/test_img/test_home_bg.png" Stretch="UniformToFill"/>
|
||||
<ImageBrush ImageSource="/Resources/Img/new/long/jump_bg.jpg" Stretch="UniformToFill"/>
|
||||
</Grid.Background>
|
||||
<Grid Height="1080" Width="1920" x:Name="userBox" >
|
||||
<Image x:Name="videoImage" Stretch="Uniform" />
|
||||
<Image x:Name="centerImg1" Source="/Resources/Img/test_img/jump_long/title.png" HorizontalAlignment="Center" VerticalAlignment="Top" Width="615" Margin="0,0,0,0"/>
|
||||
<Image x:Name="centerImg2" Source="/Resources/Img/test_img/jump_long/mat.png" HorizontalAlignment="Center" VerticalAlignment="Top" Width="1337" Margin="0,556,0,0" Height="210"/>
|
||||
<Image
|
||||
<Image x:Name="centerImg1" Source="/Resources/Img/new/long/title.png" HorizontalAlignment="Center" VerticalAlignment="Top" Width="315" Margin="0,25,0,0"/>
|
||||
<Image x:Name="centerImg2" Source="/Resources/Img/new/long/mat.png" HorizontalAlignment="Center" VerticalAlignment="Top" Width="1337" Margin="0,556,0,0" Height="210"/>
|
||||
<!--<Image
|
||||
x:Name="centerImg3"
|
||||
gif:ImageBehavior.AnimatedSource="/Resources/Img/test_img/jump_long/right_hand.gif"
|
||||
gif:ImageBehavior.AnimatedSource="/Resources/Img/new/long/right_hand.gif"
|
||||
gif:ImageBehavior.RepeatBehavior="Forever"
|
||||
gif:ImageBehavior.AnimateInDesignMode="True"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1242,301,0,0" Height="438" Width="360"/>
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="1220,251,0,0" Height="438" Width="360"/>-->
|
||||
<Image
|
||||
x:Name="centerImg4"
|
||||
Visibility="Hidden"
|
||||
gif:ImageBehavior.AnimatedSource="/Resources/Img/test_img/jump_long/jumping.gif"
|
||||
Visibility="Visible"
|
||||
gif:ImageBehavior.AnimatedSource="/Resources/Img/new/long/jumping.gif"
|
||||
gif:ImageBehavior.RepeatBehavior="1x"
|
||||
gif:ImageBehavior.AutoStart="False"
|
||||
gif:ImageBehavior.AutoStart="True"
|
||||
gif:ImageBehavior.AnimationSpeedRatio="1.5"
|
||||
gif:ImageBehavior.AnimateInDesignMode="True"
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="824,72,0,0" Width="824" Height="610"/>
|
||||
HorizontalAlignment="Left" VerticalAlignment="Top" Margin="488,95,0,0" Width="1072" Height="750"/>
|
||||
<Grid Width="1920" Height="1080" Background="#80000000" x:Name="TipBox" Opacity="0">
|
||||
<Image Source="/Resources/Img/test_img/jump_long/tip.png" HorizontalAlignment="Center" VerticalAlignment="Center" Width="1416" Margin="0,0,0,-700"/>
|
||||
</Grid>
|
||||
@ -45,7 +45,7 @@
|
||||
/>
|
||||
|
||||
|
||||
<Grid Width="1380" Height="697" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,180,0,0" x:Name="ScoreGrid">
|
||||
<Grid Width="880" Height="597" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,180,0,0" x:Name="ScoreGrid">
|
||||
<!--<Border Background="#FEDE50" CornerRadius="20"/>-->
|
||||
<Image Source="/Resources/Img/test_img/jump_long/rotate_img.png" Width="1000" Height="1000" Margin="205,-454,175,151" RenderTransformOrigin="0.5,0.5">
|
||||
<Image.RenderTransform>
|
||||
@ -68,14 +68,14 @@
|
||||
</Image>
|
||||
|
||||
<Image Source="/Resources/Img/test_img/jump_long/head_top.png" HorizontalAlignment="Center" VerticalAlignment="Top" Height="110" Margin="0,-104,0,0" />
|
||||
<Image Source="/Resources/Img/test_img/jump_long/win_bg.png" HorizontalAlignment="Center" VerticalAlignment="Center" Width="1530" Height="770" />
|
||||
<Border Background="#ff8600" CornerRadius="20" Width="300" Height="90" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,20,0,0" >
|
||||
<Image Source="/Resources/Img/test_img/jump_long/win_bg.png" HorizontalAlignment="Center" VerticalAlignment="Top" Width="880" Height="870" Margin="0,-3,0,0" />
|
||||
<Border Background="#ff8600" CornerRadius="20" Width="350" Height="200" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,120,0,0" >
|
||||
<Grid>
|
||||
<TextBlock Text="跳远成绩" FontSize="22" TextAlignment="Center" Padding="0,10,0,0" FontWeight="Bold" Foreground="#80ffffff" />
|
||||
<TextBlock x:Name="count" Text="165cm" FontSize="49" TextAlignment="Center" Padding="0,35,0,0" FontWeight="Bold" Foreground="#fff" FontStyle="Italic" />
|
||||
<TextBlock Text="跳远成绩" FontSize="36" TextAlignment="Center" Padding="0,30,0,0" FontWeight="Bold" Foreground="#80ffffff" />
|
||||
<TextBlock x:Name="count" Text="165cm" FontSize="79" TextAlignment="Center" Padding="0,85,0,0" FontWeight="Bold" Foreground="#fff" FontStyle="Italic" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<StackPanel Margin="60,130,50,30" Orientation="Horizontal">
|
||||
<!--<StackPanel Margin="60,130,50,30" Orientation="Horizontal">
|
||||
<Grid Width="600">
|
||||
<Border Background="#fff" CornerRadius="20"></Border>
|
||||
<Border Background="#e54229" CornerRadius="20 ,20,0,0" VerticalAlignment="Top" Padding="0,15,0,0" Width="600" Height="60">
|
||||
@ -98,7 +98,7 @@
|
||||
<TextBlock Text="105cm" FontSize="55" FontWeight="Bold" FontStyle="Italic" Margin="54,373,-54,-373" />
|
||||
<TextBlock x:Name="time" Text="00:11" FontSize="55" FontWeight="Bold" FontStyle="Italic" Margin="397,373,-397,-373" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</StackPanel>-->
|
||||
</Grid>
|
||||
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ namespace Views.JumpLong
|
||||
private JumpLongPoints _Points;
|
||||
|
||||
private int _sportType = 0; // 0:未开始 1:运动中 2:运动结束展示排行榜
|
||||
|
||||
private bool isBack = false; //是否返回主页
|
||||
#endregion
|
||||
|
||||
public StandingLeap()
|
||||
@ -101,23 +101,24 @@ namespace Views.JumpLong
|
||||
try
|
||||
{
|
||||
if (humans == null || humans.Count == 0) return;
|
||||
//左手返回
|
||||
int leftWaving = DetectLeftHandRaise(humans);
|
||||
if (leftWaving == 5)
|
||||
{
|
||||
//_mainWin.WebcamClient.StopExtract();
|
||||
|
||||
// 举左手逻辑,例如结束动画或退出
|
||||
if (isBack) return; // 已经返回过主页了,避免重复执行
|
||||
_mainWin.HumanFrameUpdated -= this.OnFrameUpdated;
|
||||
isBack = true;
|
||||
var newPage = new Home();
|
||||
_mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
||||
|
||||
return; // 提前退出
|
||||
}
|
||||
//举手检测 未开始 :退出& 开始 运动中:不检测 2.结束:继续测试 & 退出
|
||||
if (_sportType != 1)
|
||||
{
|
||||
//左手返回
|
||||
int leftWaving = DetectLeftHandRaise(humans);
|
||||
if (leftWaving == 5)
|
||||
{
|
||||
//_mainWin.HumanFrameUpdated -= this.OnFrameUpdated;
|
||||
//_mainWin.WebcamClient.StopExtract();
|
||||
|
||||
// 举左手逻辑,例如结束动画或退出
|
||||
var newPage = new Home();
|
||||
_mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
||||
return; // 提前退出
|
||||
}
|
||||
|
||||
//右手判断
|
||||
int rightWaving = DetectRightHandRaise(humans);
|
||||
if (rightWaving >= 3 && _sportType == 0) //举手完成 开始跳远检测
|
||||
@ -213,7 +214,7 @@ namespace Views.JumpLong
|
||||
// };
|
||||
// TipBox.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
|
||||
|
||||
// });
|
||||
// });;
|
||||
//});
|
||||
|
||||
}
|
||||
@ -238,9 +239,9 @@ namespace Views.JumpLong
|
||||
ImageBehavior.GetAnimationController(centerImg4).Play();
|
||||
await Task.Delay(2100);
|
||||
_sport.Stop();//关闭运动
|
||||
_mainWin.FacialRecognitionEvent -= this.HumanPredicting;
|
||||
//_mainWin.FacialRecognitionEvent -= this.HumanPredicting;
|
||||
count.Text = counts;
|
||||
time.Text = _sport.GetFormatTimes();
|
||||
//time.Text = _sport.GetFormatTimes();
|
||||
ShowRope();
|
||||
if (!_sport.IsCounting)
|
||||
{
|
||||
@ -283,7 +284,7 @@ namespace Views.JumpLong
|
||||
if (i == 8)
|
||||
{
|
||||
centerImg4.Visibility = Visibility.Hidden;
|
||||
centerImg3.Visibility = Visibility.Visible;
|
||||
//centerImg3.Visibility = Visibility.Visible;
|
||||
}
|
||||
if (i == 1)
|
||||
{
|
||||
@ -521,7 +522,7 @@ namespace Views.JumpLong
|
||||
|
||||
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
||||
_mainWin.ShowCountDownAnimation();
|
||||
centerImg3.Visibility = Visibility.Hidden;
|
||||
//centerImg3.Visibility = Visibility.Hidden;
|
||||
centerImg4.Visibility = Visibility.Visible;
|
||||
//if (_sport?.IsCounting == true)
|
||||
//_mainWin.WebcamClient.OnExtractFrame += this.OnFrameExtracted;
|
||||
@ -583,7 +584,7 @@ namespace Views.JumpLong
|
||||
videoImage.Opacity = 1;
|
||||
centerImg1.Opacity = 0;
|
||||
centerImg2.Opacity = 0;
|
||||
centerImg3.Opacity = 0;
|
||||
//centerImg3.Opacity = 0;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,14 +8,14 @@
|
||||
mc:Ignorable="d" Height="1080" Width="1920" Loaded="UserControl_Loaded" Unloaded="UserControl_Unloaded">
|
||||
<Grid>
|
||||
<Grid.Background>
|
||||
<ImageBrush ImageSource="/Resources/Img/test_img/test_home_bg.png" Stretch="UniformToFill"/>
|
||||
<ImageBrush ImageSource="/Resources/Img/new/group/test_bg.png" Stretch="UniformToFill"/>
|
||||
</Grid.Background>
|
||||
<Image
|
||||
Source="/Resources/Img/test_img/one_rope/title.png"
|
||||
Source="/Resources/Img/new/group/test_title.png"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Top"
|
||||
Width="615"
|
||||
Margin="0,0,0,0"
|
||||
Width="315"
|
||||
Margin="0,25,0,0"
|
||||
/>
|
||||
<Grid Height="1080" Width="1920" x:Name="userBox"/>
|
||||
|
||||
@ -76,7 +76,7 @@
|
||||
Margin="0,168"
|
||||
/>
|
||||
|
||||
<Grid Width="1346" Height="520" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,331,0,0" x:Name="ScoreGrid">
|
||||
<Grid Width="1346" Height="560" HorizontalAlignment="Center" VerticalAlignment="Top" Margin="0,331,0,0" x:Name="ScoreGrid">
|
||||
<Border Background="#FEDE50" CornerRadius="0,0,20,20"/>
|
||||
<Grid HorizontalAlignment="Center" VerticalAlignment="Top" Width="1344" Height="71">
|
||||
<Border Background="#f7f7f7"/>
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
using Common;
|
||||
using Dto;
|
||||
using Emgu.CV.Flann;
|
||||
using Emgu.CV.Structure;
|
||||
using Enum;
|
||||
using HandyControl.Controls;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -66,7 +67,7 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
private readonly object _updateLock = new object();
|
||||
private readonly Dictionary<int, (string lastNumber, DateTime lastChangeTime, string currentState)> _jumpStatus = new Dictionary<int, (string, DateTime, string)>();
|
||||
private GroupJumpRopeContext _groupJumpRopeContext;
|
||||
|
||||
Image tipImage;
|
||||
public GroupJumpRope()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -138,13 +139,14 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
}
|
||||
private void ShowCenterTip(string imagePath, TimeSpan duration)
|
||||
{
|
||||
var tipImage = new Image
|
||||
tipImage = new Image
|
||||
{
|
||||
Source = new BitmapImage(new Uri(imagePath, UriKind.Absolute)),
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
Opacity = 0,
|
||||
Margin = new Thickness(0, -100, 0, 0),
|
||||
Name= "TipImage"
|
||||
};
|
||||
|
||||
// 增加图片的大小,调整比例
|
||||
@ -164,26 +166,26 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeInAnimation);
|
||||
|
||||
// 定时移除,并且渐变消失
|
||||
Task.Delay(duration).ContinueWith(_ =>
|
||||
{
|
||||
Dispatcher.Invoke(() =>
|
||||
{
|
||||
// 渐变消失动画
|
||||
var fadeOutAnimation = new DoubleAnimation
|
||||
{
|
||||
From = 1,
|
||||
To = 0,
|
||||
Duration = TimeSpan.FromSeconds(1.5)
|
||||
};
|
||||
tipImage.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
|
||||
//Task.Delay(duration).ContinueWith(_ =>
|
||||
//{
|
||||
// Dispatcher.Invoke(() =>
|
||||
// {
|
||||
// // 渐变消失动画
|
||||
// var fadeOutAnimation = new DoubleAnimation
|
||||
// {
|
||||
// From = 1,
|
||||
// To = 0,
|
||||
// Duration = TimeSpan.FromSeconds(1.5)
|
||||
// };
|
||||
// tipImage.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation);
|
||||
|
||||
// 完成后移除图片
|
||||
fadeOutAnimation.Completed += (s, e) =>
|
||||
{
|
||||
userBox.Children.Remove(tipImage);
|
||||
};
|
||||
});
|
||||
});
|
||||
// // 完成后移除图片
|
||||
// fadeOutAnimation.Completed += (s, e) =>
|
||||
// {
|
||||
// userBox.Children.Remove(tipImage);
|
||||
// };
|
||||
// });
|
||||
//});
|
||||
}
|
||||
|
||||
private void MediaPlayer_MediaEnded(object sender, EventArgs e)
|
||||
@ -210,6 +212,7 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
if (leftWaving == 5)
|
||||
{
|
||||
// 举左手逻辑,例如结束动画或退出
|
||||
_isCountdownStarted = true;
|
||||
var newPage = new Home();
|
||||
_mainWin?.SwitchPageWithMaskAnimation(newPage, true);
|
||||
return; // 提前退出
|
||||
@ -238,7 +241,9 @@ namespace Wpf_AiSportsMicrospace.Views
|
||||
|
||||
private async void StartCountdown(int start = 3)
|
||||
{
|
||||
tipImage.Visibility = Visibility.Collapsed;
|
||||
_mainWin.ShowCountDownAnimation();
|
||||
//_currentCountdown = start;
|
||||
|
||||
Utils.PlayBackgroundMusic("countdown_3.mp3", false);
|
||||
|
||||
|
||||
@ -48,6 +48,29 @@
|
||||
<None Remove="Resources\Img\gif\bottom_animation_image.png" />
|
||||
<None Remove="Resources\Img\gif\time_3.gif" />
|
||||
<None Remove="Resources\Img\gif\top_animation_image.png" />
|
||||
<None Remove="Resources\Img\new\group\test_bg.png" />
|
||||
<None Remove="Resources\Img\new\group\test_title.png" />
|
||||
<None Remove="Resources\Img\new\home\card_1.png" />
|
||||
<None Remove="Resources\Img\new\home\card_2.png" />
|
||||
<None Remove="Resources\Img\new\home\card_3.png" />
|
||||
<None Remove="Resources\Img\new\home\card_4.png" />
|
||||
<None Remove="Resources\Img\new\home\card_5.png" />
|
||||
<None Remove="Resources\Img\new\home\home_bg.png" />
|
||||
<None Remove="Resources\Img\new\home\home_title.png" />
|
||||
<None Remove="Resources\Img\new\long\bottom - 复制.png" />
|
||||
<None Remove="Resources\Img\new\long\bottom.png" />
|
||||
<None Remove="Resources\Img\new\long\head_top.png" />
|
||||
<None Remove="Resources\Img\new\long\jumping.gif" />
|
||||
<None Remove="Resources\Img\new\long\jump_bg.jpg" />
|
||||
<None Remove="Resources\Img\new\long\mat.png" />
|
||||
<None Remove="Resources\Img\new\long\mat1.png" />
|
||||
<None Remove="Resources\Img\new\long\people.png" />
|
||||
<None Remove="Resources\Img\new\long\rotate_img - 复制.png" />
|
||||
<None Remove="Resources\Img\new\long\rotate_img.png" />
|
||||
<None Remove="Resources\Img\new\long\tip.png" />
|
||||
<None Remove="Resources\Img\new\long\title.png" />
|
||||
<None Remove="Resources\Img\new\long\top.png" />
|
||||
<None Remove="Resources\Img\new\long\win_bg.png" />
|
||||
<None Remove="Resources\Img\play_img\music_rope\back.png" />
|
||||
<None Remove="Resources\Img\play_img\music_rope\bg_mic.gif" />
|
||||
<None Remove="Resources\Img\play_img\music_rope\great-p.png" />
|
||||
@ -139,6 +162,75 @@
|
||||
<Resource Include="Resources\app.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\group\test_bg.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\group\test_title.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\card_1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\card_2.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\card_3.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\card_4.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\card_5.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\home_bg.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\home\home_title.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\bottom - 复制.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\bottom.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\head_top.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\jumping.gif">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\jump_bg.jpg">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\mat.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\mat1.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\people.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\rotate_img - 复制.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\rotate_img.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\tip.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\title.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\top.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\new\long\win_bg.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
<Resource Include="Resources\Img\play_img\whack_mole.png">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</Resource>
|
||||
|
||||