using Newtonsoft.Json; using System; using System.IO; using System.Reflection; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; namespace Ink_Canvas.Windows { /// /// SplashScreen.xaml 的交互逻辑 /// public partial class SplashScreen : Window { private int _actualSplashStyle = 1; public SplashScreen() { InitializeComponent(); InitializeSplashScreen(); } private void InitializeSplashScreen() { // 设置窗口居中 WindowStartupLocation = WindowStartupLocation.CenterScreen; // 设置版本号 SetVersionText(); // 加载启动图片并获取实际样式 _actualSplashStyle = LoadSplashImageWithStyle(); } public void CloseSplashScreen() { // 添加淡出动画 var fadeOutAnimation = new DoubleAnimation { From = 1, To = 0, Duration = TimeSpan.FromMilliseconds(300), EasingFunction = new CubicEase { EasingMode = EasingMode.EaseIn } }; fadeOutAnimation.Completed += (s, e) => { this.Close(); }; this.BeginAnimation(OpacityProperty, fadeOutAnimation); } /// /// 设置加载进度(0-100) /// /// 进度百分比 public void SetProgress(int progress) { Dispatcher.Invoke(() => { // 设置进度条颜色 SetProgressBarColor(); // 获取进度条容器的实际宽度 double containerWidth = ProgressBarBackground.ActualWidth; if (containerWidth <= 0) { // 如果ActualWidth为0,使用设计时宽度 containerWidth = 530; } // 计算目标宽度 double targetWidth = containerWidth * (progress / 100.0); // 创建Storyboard动画 var storyboard = new Storyboard(); // 创建宽度动画 var widthAnimation = new DoubleAnimation { From = ProgressBarFill.Width, To = targetWidth, Duration = TimeSpan.FromMilliseconds(300), EasingFunction = new CubicEase { EasingMode = EasingMode.EaseOut } }; // 设置动画目标 Storyboard.SetTarget(widthAnimation, ProgressBarFill); Storyboard.SetTargetProperty(widthAnimation, new PropertyPath(Border.WidthProperty)); // 添加动画到Storyboard storyboard.Children.Add(widthAnimation); // 添加动画完成事件 storyboard.Completed += (s, e) => { // 确保最终值正确设置 ProgressBarFill.Width = targetWidth; // 根据进度调整圆角 if (progress >= 100) { // 进度100%时,底部角都是圆角 ProgressBarFill.CornerRadius = new CornerRadius(0, 0, 7, 7); } else { // 进度未满时,只有左侧是圆角 ProgressBarFill.CornerRadius = new CornerRadius(0, 0, 0, 7); } }; // 开始动画 storyboard.Begin(); }); } /// /// 设置加载消息 /// /// 加载消息 public void SetLoadingMessage(string message) { // 使用实际选择的样式 SetLoadingMessage(message, _actualSplashStyle); } public void SetLoadingMessage(string message, int actualSplashStyle) { Dispatcher.Invoke(() => { LoadingText.Text = message; // 根据实际启动动画样式调整加载文本样式 if (actualSplashStyle == 6) // 马年限定 { // 马年限定样式 LoadingText.FontSize = 12; LoadingText.FontWeight = FontWeights.SemiBold; LoadingText.Foreground = Brushes.White; LoadingText.HorizontalAlignment = HorizontalAlignment.Center; LoadingText.Margin = new Thickness(0, 200, 140, 4); } else { // 默认样式 LoadingText.FontSize = 18; LoadingText.FontWeight = FontWeights.SemiBold; LoadingText.Foreground = Brushes.White; LoadingText.HorizontalAlignment = HorizontalAlignment.Center; LoadingText.Margin = new Thickness(0, 200, 0, 0); } }); } /// /// 获取当前启动动画样式 /// /// 启动动画样式索引 private int GetCurrentSplashStyle() { try { var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", "Settings.json"); if (File.Exists(settingsPath)) { var json = File.ReadAllText(settingsPath); dynamic obj = JsonConvert.DeserializeObject(json); if (obj?["appearance"]?["splashScreenStyle"] != null) { return (int)obj["appearance"]["splashScreenStyle"]; } } return 1; // 默认跟随四季 } catch { return 1; // 默认跟随四季 } } /// /// 设置版本号文本 /// private void SetVersionText() { try { var version = Assembly.GetExecutingAssembly().GetName().Version; if (version != null) { VersionTextBlock.Text = $"v{version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; } else { VersionTextBlock.Text = "v5.0.4.0"; } } catch { VersionTextBlock.Text = "v5.0.4.0"; } } /// /// 加载启动图片 /// private void LoadSplashImage() { try { string imagePath = GetSplashImagePath(); if (!string.IsNullOrEmpty(imagePath)) { StartupImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(imagePath)); } } catch (Exception ex) { // 如果加载失败,使用默认图片 System.Diagnostics.Debug.WriteLine($"加载启动图片失败: {ex.Message}"); } } /// /// 加载启动图片并返回实际样式 /// /// 实际选择的样式 public int LoadSplashImageWithStyle() { try { int actualStyle; string imagePath = GetSplashImagePath(out actualStyle); if (!string.IsNullOrEmpty(imagePath)) { StartupImage.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri(imagePath)); } return actualStyle; } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"加载启动图片失败: {ex.Message}"); return GetActualStyle(1); } } /// /// 根据设置获取启动图片路径 /// private string GetSplashImagePath() { try { // 读取设置 var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", "Settings.json"); int splashStyle = 1; // 默认跟随四季 if (File.Exists(settingsPath)) { var json = File.ReadAllText(settingsPath); dynamic obj = JsonConvert.DeserializeObject(json); if (obj?["appearance"]?["splashScreenStyle"] != null) { splashStyle = (int)obj["appearance"]["splashScreenStyle"]; } } // 根据样式选择图片 string imageName = GetImageNameByStyle(splashStyle); return $"pack://application:,,,/Resources/Startup-animation/{imageName}"; } catch { string imageName = GetImageNameByStyle(1); return $"pack://application:,,,/Resources/Startup-animation/{imageName}"; } } /// /// 根据设置获取启动图片路径和实际样式 /// /// 返回实际选择的样式 /// 图片路径 private string GetSplashImagePath(out int actualStyle) { try { // 读取设置 var settingsPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Configs", "Settings.json"); int splashStyle = 1; // 默认跟随四季 if (File.Exists(settingsPath)) { var json = File.ReadAllText(settingsPath); dynamic obj = JsonConvert.DeserializeObject(json); if (obj?["appearance"]?["splashScreenStyle"] != null) { splashStyle = (int)obj["appearance"]["splashScreenStyle"]; } } // 根据样式选择图片,并获取实际样式 actualStyle = GetActualStyle(splashStyle); string imageName = GetImageNameByStyle(splashStyle); return $"pack://application:,,,/Resources/Startup-animation/{imageName}"; } catch { actualStyle = GetActualStyle(1); string imageName = GetImageNameByStyle(1); return $"pack://application:,,,/Resources/Startup-animation/{imageName}"; } } /// /// 获取实际样式 /// /// 设置中的样式 /// 实际选择的样式 private int GetActualStyle(int style) { switch (style) { case 0: // 随机 var random = new Random(); var randomStyles = new[] { 2, 3, 4, 5, 6 }; // 春季、夏季、秋季、冬季、马年限定 return randomStyles[random.Next(randomStyles.Length)]; case 1: // 跟随四季 var month = DateTime.Now.Month; if (month >= 3 && month <= 5) return 2; // 春季 if (month >= 6 && month <= 8) return 3; // 夏季 if (month >= 9 && month <= 11) return 4; // 秋季 return 5; // 冬季 default: return style; } } /// /// 根据样式获取图片名称 /// private string GetImageNameByStyle(int style) { switch (style) { case 0: // 随机 var random = new Random(); var randomStyles = new[] { 2, 3, 4, 5, 6 }; // 春季、夏季、秋季、冬季、马年限定 return GetImageNameByStyle(randomStyles[random.Next(randomStyles.Length)]); case 1: // 跟随四季 var month = DateTime.Now.Month; if (month >= 2 && month <= 4) return GetImageNameByStyle(2); // 春季 if (month >= 5 && month <= 7) return GetImageNameByStyle(3); // 夏季 if (month >= 8 && month <= 10) return GetImageNameByStyle(4); // 秋季 return GetImageNameByStyle(5); // 冬季 case 2: // 春季 return "ICC Spring.png"; case 3: // 夏季 return "ICC Summer.png"; case 4: // 秋季 return "ICC Autumn.png"; case 5: // 冬季 return "ICC Winter.png"; case 6: // 马年限定 return "ICC Horse.png"; default:// 默认返回 return "ICC Horse.png"; } } /// /// 根据实际样式设置进度条颜色 /// private void SetProgressBarColor() { Color progressColor; switch (_actualSplashStyle) { case 2: // 春季 - H=136, S=15, L=22 progressColor = HslToRgb(136, 15, 22); break; case 3: // 夏季 - H=6, S=15, L=22 progressColor = HslToRgb(6, 15, 22); break; case 4: // 秋季 - H=39, S=15, L=22 progressColor = HslToRgb(39, 15, 22); break; case 5: // 冬季 - H=204, S=15, L=22 progressColor = HslToRgb(204, 15, 22); break; case 6: // 马年限定 - 白色 progressColor = Colors.White; break; default: // 默认使用 progressColor = Colors.White; break; } // 创建渐变画刷 var gradientBrush = new LinearGradientBrush { StartPoint = new System.Windows.Point(0, 0), EndPoint = new System.Windows.Point(1, 0) }; // 根据颜色类型设置渐变 if (_actualSplashStyle == 6) // 马年限定使用白色渐变 { gradientBrush.GradientStops.Add(new GradientStop(Colors.White, 0)); gradientBrush.GradientStops.Add(new GradientStop(Color.FromArgb(200, 255, 255, 255), 0.5)); gradientBrush.GradientStops.Add(new GradientStop(Color.FromArgb(150, 255, 255, 255), 1)); } else // 其他样式使用HSL颜色的渐变 { var lighterColor = Color.FromArgb(255, (byte)Math.Min(255, progressColor.R + 30), (byte)Math.Min(255, progressColor.G + 30), (byte)Math.Min(255, progressColor.B + 30)); var darkerColor = Color.FromArgb(255, (byte)Math.Max(0, progressColor.R - 30), (byte)Math.Max(0, progressColor.G - 30), (byte)Math.Max(0, progressColor.B - 30)); gradientBrush.GradientStops.Add(new GradientStop(lighterColor, 0)); gradientBrush.GradientStops.Add(new GradientStop(progressColor, 0.5)); gradientBrush.GradientStops.Add(new GradientStop(darkerColor, 1)); } ProgressBarFill.Background = gradientBrush; } /// /// 将HSL颜色转换为RGB颜色 /// /// 色相 (0-360) /// 饱和度 (0-100) /// 亮度 (0-100) /// RGB颜色 private Color HslToRgb(double h, double s, double l) { // 将HSL值转换为0-1范围 h = h / 360.0; s = s / 100.0; l = l / 100.0; double r, g, b; if (s == 0) { // 无饱和度,为灰度 r = g = b = l; } else { double q = l < 0.5 ? l * (1 + s) : l + s - l * s; double p = 2 * l - q; r = HueToRgb(p, q, h + 1.0 / 3.0); g = HueToRgb(p, q, h); b = HueToRgb(p, q, h - 1.0 / 3.0); } return Color.FromRgb( (byte)Math.Round(r * 255), (byte)Math.Round(g * 255), (byte)Math.Round(b * 255) ); } /// /// HSL颜色转换辅助方法 /// private double HueToRgb(double p, double q, double t) { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1.0 / 6.0) return p + (q - p) * 6 * t; if (t < 1.0 / 2.0) return q; if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6; return p; } } }