232 lines
8.3 KiB
C#
232 lines
8.3 KiB
C#
using HandyControl.Controls;
|
|
using SharpDX.Direct3D9;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
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;
|
|
using WpfAnimatedGif;
|
|
|
|
namespace Wpf_AiSportsMicrospace.MyUserControl
|
|
{
|
|
/// <summary>
|
|
/// CoverFlowControl.xaml 的交互逻辑
|
|
/// </summary>
|
|
/// ST
|
|
///
|
|
public partial class PopSilder : UserControl
|
|
{
|
|
|
|
private List<double> _musicBeats = new List<double>()
|
|
{
|
|
0.545,1.09,1.635,2.18,2.725,3.27,3.815,4.36,4.905,5.45,
|
|
5.995,6.54,7.085,7.63,8.175,8.72,9.265,9.81,10.355,10.9,
|
|
//11.445,11.99,12.535,13.08,13.625,14.17,14.715,15.26,15.805,16.35,
|
|
//16.895,17.44,17.985,18.53,19.075,19.62,20.165,20.71,21.255,21.8,
|
|
//22.345,22.89,23.435,23.98,24.525,25.07,25.615,26.16,26.705,27.25,
|
|
//27.795,28.34,28.885,29.43,29.975,30.52,31.065,31.61,32.155,32.7,
|
|
//33.245,33.79,34.335,34.88,35.425,35.97,36.515,37.06,37.605,38.15,
|
|
//38.695,39.24,39.785,40.33,40.875,41.42,41.965,42.51,43.055,43.6,
|
|
//44.145,44.69,45.235,45.78,46.325,46.87,47.415,47.96,48.505,49.05,
|
|
//49.595,50.14,50.685,51.23,51.775,52.32,52.865,53.41,53.955,54.5,
|
|
//55.045,55.59,56.135,56.68,57.225,57.77,58.315,58.86,59.405,59.95,
|
|
//60.495,61.04,61.585,62.13,62.675,63.22,63.765,64.31,64.855,65.4,
|
|
//65.945,66.49,67.035,67.58,68.125,68.67,69.215,69.76,70.305,70.85,
|
|
//71.395,71.94,72.485,73.03,73.575,74.12,74.665,75.21,75.755,76.3,
|
|
//76.845,77.39,77.935,78.48,79.025,79.57,80.115,80.66,81.205,81.75,
|
|
//82.295,82.84,83.385,83.93,84.475,85.02,85.565,86.11,86.655,87.2,
|
|
//87.745,88.29,88.835,89.38,89.925,90.47,91.015,91.56,92.105,92.65,
|
|
//93.195,93.74,94.285,94.83,95.375,95.92,96.465,97.01,97.555,98.1,
|
|
//98.645,99.19,99.735,100.28,100.825,101.37,101.915,102.46,103.005,103.55,
|
|
//104.095,104.64,105.185,105.73,106.275,106.82,107.365,107.91,108.455
|
|
};
|
|
private Storyboard _marginStoryboard;
|
|
private ThicknessAnimation _marginAnimation;
|
|
private TimedEventTrigger _trigger;
|
|
private bool _isMiss = true;
|
|
public bool IsMiss
|
|
{
|
|
get => _isMiss;
|
|
set
|
|
{
|
|
_isMiss = value;
|
|
}
|
|
}
|
|
public PopSilder()
|
|
{
|
|
InitializeComponent();
|
|
double time = Math.Floor(_musicBeats[_musicBeats.Count - 1]);
|
|
double startMargin = _musicBeats[0] * 200;
|
|
ani.Margin = new Thickness(startMargin, 0, 0, 0);
|
|
for (int i = 1; i < _musicBeats.Count + 1; i++)
|
|
{
|
|
double width = i != _musicBeats.Count ? (_musicBeats[i] - _musicBeats[i - 1]) * 200 : 0;
|
|
var img = new Image
|
|
{
|
|
Width = 52,
|
|
Height = 50,
|
|
Source = new BitmapImage(new Uri("pack://application:,,,/Resources/Img/play_img/music_rope/point.png")),
|
|
};
|
|
var grid = new StackPanel
|
|
{
|
|
Width = width,
|
|
Height = 5,
|
|
Background = new SolidColorBrush(Color.FromRgb(0, 0, 0))
|
|
};
|
|
|
|
var StackPanel = new StackPanel { Orientation = Orientation.Horizontal };
|
|
StackPanel.Children.Add(img);
|
|
StackPanel.Children.Add(grid);
|
|
ani.Children.Add(StackPanel);
|
|
}
|
|
}
|
|
|
|
|
|
private void InitializeMarginAnimation()
|
|
{
|
|
double time = Math.Floor(_musicBeats[_musicBeats.Count - 1]) + 1;
|
|
double startMargin = _musicBeats[0] * 200;
|
|
// 创建厚度动画
|
|
_marginAnimation = new ThicknessAnimation
|
|
{
|
|
From = new Thickness(startMargin, 0, 0, 0), // 起始值
|
|
To = new Thickness(-time * (200 + 52) - 350, 0, 0, 0), // 目标值
|
|
Duration = TimeSpan.FromSeconds(time), // time秒持续时间
|
|
FillBehavior = FillBehavior.HoldEnd // 动画完成后保持状态
|
|
};
|
|
Console.WriteLine("ani.Width:" + ani.Width);
|
|
// 创建故事板
|
|
_marginStoryboard = new Storyboard();
|
|
_marginStoryboard.Children.Add(_marginAnimation);
|
|
|
|
// 设置目标对象和属性
|
|
Storyboard.SetTarget(_marginAnimation, ani);
|
|
Storyboard.SetTargetProperty(_marginAnimation, new PropertyPath(StackPanel.MarginProperty));
|
|
|
|
|
|
_trigger = new TimedEventTrigger(_musicBeats);
|
|
_trigger.TimePointReached += OnTimePointReached;
|
|
}
|
|
|
|
// 鼠标点击事件 - 开始动画
|
|
private void ani_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
|
{
|
|
StartMarginAnimation();
|
|
}
|
|
|
|
public void StartMarginAnimation()
|
|
{
|
|
InitializeMarginAnimation();
|
|
_marginStoryboard?.Begin();
|
|
_trigger.Start();
|
|
}
|
|
|
|
public void StopMarginAnimation()
|
|
{
|
|
_marginStoryboard?.Stop();
|
|
_trigger.Stop();
|
|
}
|
|
|
|
|
|
private void OnTimePointReached(double timePoint)
|
|
{
|
|
Console.WriteLine($"触发时间点: {timePoint}");
|
|
if (_isMiss)
|
|
{
|
|
head_m.Visibility = Visibility.Visible;
|
|
miss.Visibility = Visibility.Visible;
|
|
//200ms后隐藏
|
|
var hideTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
|
|
hideTimer.Tick += (s, e) =>
|
|
{
|
|
//head_m.Visibility = Visibility.Hidden;
|
|
//_isMiss = true;
|
|
hideTimer.Stop();
|
|
};
|
|
}
|
|
else
|
|
{
|
|
head_g.Visibility = Visibility.Visible;
|
|
great.Visibility = Visibility.Visible;
|
|
//200ms后隐藏
|
|
var hideTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(200) };
|
|
hideTimer.Tick += (s, e) =>
|
|
{
|
|
head_g.Visibility = Visibility.Hidden;
|
|
great.Visibility = Visibility.Hidden;
|
|
hideTimer.Stop();
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TimedEventTrigger
|
|
{
|
|
private DispatcherTimer _timer;
|
|
private List<double> _timePoints;
|
|
private int _currentIndex;
|
|
private DateTime _startTime;
|
|
|
|
public TimedEventTrigger(List<double> timePoints)
|
|
{
|
|
_timePoints = timePoints;
|
|
_currentIndex = 0;
|
|
|
|
_timer = new DispatcherTimer();
|
|
_timer.Interval = TimeSpan.FromMilliseconds(10); // 10ms精度
|
|
_timer.Tick += CheckTimePoint;
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
_startTime = DateTime.Now;
|
|
_timer.Start();
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
_timer.Stop();
|
|
}
|
|
|
|
private void CheckTimePoint(object sender, EventArgs e)
|
|
{
|
|
double elapsedSeconds = (DateTime.Now - _startTime).TotalSeconds;
|
|
|
|
// 检查是否到达下一个时间点
|
|
if (_currentIndex < _timePoints.Count &&
|
|
elapsedSeconds >= _timePoints[_currentIndex])
|
|
{
|
|
// 触发事件
|
|
OnTimePointReached(_timePoints[_currentIndex]);
|
|
_currentIndex++;
|
|
}
|
|
|
|
// 所有时间点都处理完毕,停止计时器
|
|
if (_currentIndex >= _timePoints.Count)
|
|
{
|
|
_timer.Stop();
|
|
}
|
|
}
|
|
|
|
public event Action<double> TimePointReached;
|
|
|
|
protected virtual void OnTimePointReached(double timePoint)
|
|
{
|
|
TimePointReached?.Invoke(timePoint);
|
|
}
|
|
}
|
|
} |