using CommunityToolkit.Mvvm.Messaging; using LiveTools.Data; using Newtonsoft.Json.Linq; using ryCommon; using System.Collections; using System.IO; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Interop; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace LiveTools { /// /// Interaction logic for MainWindow.xaml /// public partial class FrmEffects : Window { public FrmEffects() { InitializeComponent(); cvsGround.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#00ff00")); this.Background = cvsGround.Background; } public DirectInfo DirectInfo { get; set; } = new DirectInfo(); public BitmapImage GetImage(string path) { BitmapImage bi = new BitmapImage(); // BitmapImage.UriSource must be in a BeginInit/EndInit block. bi.BeginInit(); bi.UriSource = new Uri(path, UriKind.RelativeOrAbsolute); bi.EndInit(); return bi; } private void Button_Click(object sender, RoutedEventArgs e) { List imgList = new List(); imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240329144830.png")); imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240307182811.png")); imgList.Add(GetImage("C:\\Users\\李凤鑫\\Desktop\\微信图片_20240329144727.png")); for (int i = 0; i < 10; i++) { Random rd2 = new Random(Guid.NewGuid().GetHashCode()); Image simpleImage = new Image(); simpleImage.Width = 50; //Canvas.SetLeft(simpleImage, i * 300); // Set the image source. simpleImage.Source = imgList[rd2.Next(0,imgList.Count)]; cvsGround.Children.Add(simpleImage); RotateTransform rotateTransform = new RotateTransform(rd2.Next(0,181)); simpleImage.RenderTransform = rotateTransform; KK(simpleImage); } //KK(GroupboxArea); //KK(GroupboxArea3); } void KK(Image grid) { var IsLandscape = false;//是否是横屏 Random rd = new Random(Guid.NewGuid().GetHashCode()); var endPos = new Point(this.Width / 2, this.Height / 2); var mm = rd.Next(0, 4); var startPos = new Point(0, rd.Next(0, 500)); switch (mm) { case 0://左边 startPos = new Point(0, rd.NextDouble() * this.Height); break; case 1://上边 startPos = new Point(this.Width * rd.NextDouble(), 0); break; case 2://右边 startPos = new Point(this.Width, rd.NextDouble() * this.Height); break; case 3://下边 startPos = new Point(rd.NextDouble() * this.Width, this.Height); break; } var story = StartAnim(startPos, endPos); story.Completed += delegate (object? sender2, EventArgs e2) { cvsGround.Children.Remove(grid); };//完成后要做的事 story.Begin(); //story.RepeatBehavior = RepeatBehavior.Forever;//无限次循环,需要的自己加上 Storyboard StartAnim(Point startPos, Point endPos) { var Duration = rd.NextDouble() * 0.4; // 创建两个DoubleAnimation来描述X和Y方向的移动 DoubleAnimation animX = new DoubleAnimation(); animX.From = startPos.X;//起点 animX.To = endPos.X; // 目标X坐标值 animX.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间 DoubleAnimation animY = new DoubleAnimation(); animY.From = startPos.Y; // 目标Y坐标值 animY.To = endPos.Y; // 目标Y坐标值 animY.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间 // // 使用Storyboard来关联动画和物体 Storyboard.SetTarget(animX, grid); Storyboard.SetTargetProperty(animX, new PropertyPath(Canvas.LeftProperty)); Storyboard.SetTarget(animY, grid); Storyboard.SetTargetProperty(animY, new PropertyPath(Canvas.TopProperty)); Storyboard _story = new Storyboard(); _story.Children.Add(animX); _story.Children.Add(animY); //第二段动画 // 创建两个DoubleAnimation来描述X和Y方向的移动 //DoubleAnimation animX_end = new DoubleAnimation(); //animX_end.From = endPos.X;//起点 //animX_end.To = startPos.X; // 目标X坐标值 //animX_end.BeginTime = TimeSpan.FromSeconds(Duration); //animX_end.Duration = TimeSpan.FromSeconds(1.5); // 动画持续时间 //PathGeometry pathGeometry = PathGeometry.CreateFromGeometry(Geometry.Parse("M "+ endPos.X+ ","+ endPos.Y+ " Q "+ (endPos.X+20)+ ","+ (endPos.Y+20)+ " "+ (endPos.X+10)+ ",0")); // Y轴方向上的动画 //DoubleAnimationUsingPath animationY = new DoubleAnimationUsingPath //{ // Source = PathAnimationSource.Y, // BeginTime = TimeSpan.FromSeconds(Duration), // Duration = TimeSpan.FromSeconds(Duration), // PathGeometry = pathGeometry //}; //DoubleAnimation animY_end = new DoubleAnimation(); //animY_end.From = endPos.Y; // 目标Y坐标值 //animY_end.To = this.Height; // 目标Y坐标值 //animY_end.BeginTime = TimeSpan.FromSeconds(Duration); //animY_end.Duration = TimeSpan.FromSeconds(Duration); // 动画持续时间 //animY_end.AccelerationRatio = 0.6; var offset = rd.Next(-200, 200); var offset2 = offset > 0 ? offset + 200 : offset - 200; var time = rd.NextDouble(); var xx = IsLandscape ? endPos.Y : endPos.X; var yy = IsLandscape ? endPos.X : endPos.Y; DoubleAnimationUsingKeyFrames animationX = new DoubleAnimationUsingKeyFrames(); animationX.BeginTime = TimeSpan.FromSeconds(Duration); animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx, TimeSpan.FromSeconds(0))); // X from 0 animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx + offset, TimeSpan.FromSeconds(0.3))); // X to 50 in 1 second animationX.KeyFrames.Add(new LinearDoubleKeyFrame(xx + offset2, TimeSpan.FromSeconds(time * 2))); // X to 100 in another 1 second DoubleAnimationUsingKeyFrames animationY = new DoubleAnimationUsingKeyFrames(); animationY.BeginTime = TimeSpan.FromSeconds(Duration); animationY.KeyFrames.Add(new EasingDoubleKeyFrame(yy, TimeSpan.FromSeconds(0), new QuadraticEase() { EasingMode = EasingMode.EaseOut })); // Y from 0 animationY.KeyFrames.Add(new EasingDoubleKeyFrame(yy - rd.Next(50, 200), TimeSpan.FromSeconds(0.3), new QuadraticEase() { EasingMode = EasingMode.EaseIn })); // Y to -50 in 1 second animationY.KeyFrames.Add(new EasingDoubleKeyFrame(IsLandscape ? 0 : this.Height, TimeSpan.FromSeconds(time * 2), new BounceEase() { EasingMode = EasingMode.EaseOut })); // Y to 300 in another 1 second Storyboard.SetTarget(animationX, grid); Storyboard.SetTargetProperty(animationX, new PropertyPath(Canvas.LeftProperty)); Storyboard.SetTarget(animationY, grid); Storyboard.SetTargetProperty(animationY, new PropertyPath(Canvas.TopProperty)); _story.Children.Add(animationX); _story.Children.Add(animationY); return _story; } } private bool IsProcUse { get; set; } = false; /// /// 正在播放的列表 /// Hashtable PlayingList { get; set; } = new Hashtable(); /// /// 上一次播放时间 /// Hashtable LastPlayTimeList { get; set; } = new Hashtable(); private void OnReceive(object recipient, MsgToken message) { if(message.Value is EffectInfo info) { if(message.Msg== "Close" && message.From == "Web") { IsProcUse = true; this.Close(); return; } if ((info.ID == DirectInfo.Id || info.ID==0) && message.From=="Web") { ///如果已经过期 if (Config.UserInfo.UserId.Length==0 || Config.UserInfo.OutTime { Image simpleImage = new Image(); simpleImage.Width = action_item.GetJsonValue("PicSize", 70); //Canvas.SetLeft(simpleImage, i * 300); // Set the image source. simpleImage.Source = GetImage(PicPath); cvsGround.Children.Add(simpleImage); RotateTransform rotateTransform = new RotateTransform(rd2.Next(0, 181)); simpleImage.RenderTransform = rotateTransform; KK(simpleImage); })); } } if (action_item.GetJsonValue("PlaySound", true)) { var th = new Thread(StartPlay); th.Start(); void StartPlay() { //var md5 = rySafe.MD5Sha1.GetMD5("AA|" +info.ID+"|"+ DateTime.Now + "|" + Guid.NewGuid()); if (System.IO.File.Exists(Config.SysDbFolder + "\\audio\\砸.mp3")) { Thread.Sleep(300); LiveTools.SoundPlay sound = new LiveTools.SoundPlay { Volume = 100 / 100f }; sound.Play(Config.SysDbFolder + "\\audio\\砸.mp3"); } } } } #endregion } break; case "Rule_SoundPlay": MSoundPlay(); void MSoundPlay() { if (!action_item.GetJsonValue("MultiPlaySound", false)) { if (info.RuleID > 0) { if (IsPlaying) { return; } if (PlayingList.Count > 0) { return; } if (LastPlayTimeList.ContainsKey(info.RuleID)) { var time= (DateTime)LastPlayTimeList[info.RuleID]; if (time >= DateTime.Now.AddSeconds(-action_item.GetJsonValue("PlaySoundInterval", 10))) { return; } } } } var th = new Thread(StartPlay); th.Start(); void StartPlay() { IsPlaying = true; var PlayCustomSound_Path =API.GetTruePath(action_item.GetJsonValue("PlayCustomSound_Path", "")); var md5 = rySafe.MD5Sha1.GetMD5(PlayCustomSound_Path + "|" + DateTime.Now + "|" + Guid.NewGuid()); if (System.IO.File.Exists(PlayCustomSound_Path)) { LiveTools.SoundPlay sound = new LiveTools.SoundPlay { Volume = action_item.GetJsonValue("Vol", 100) / 100f }; PlayingList[md5]=sound; sound.Play(PlayCustomSound_Path); PlayingList.Remove(md5); } else if (System.IO.Directory.Exists(PlayCustomSound_Path)) { var files = RyFiles.GetFiles(PlayCustomSound_Path, "*.mp3;*.wav;*.flac;*.wma"); if (files.Count > 0) { Random rd = new Random(Guid.NewGuid().GetHashCode()); LiveTools.SoundPlay sound = new LiveTools.SoundPlay { Volume = action_item.GetJsonValue("Vol", 100) / 100f }; PlayingList[md5]= sound; sound.Play(files[rd.Next(0, files.Count)]); PlayingList.Remove(md5); } } if (LastPlayTimeList.ContainsKey(info.RuleID)) { LastPlayTimeList[info.RuleID] = DateTime.Now; } else { LastPlayTimeList[info.RuleID]= DateTime.Now; } IsPlaying = false; } } break; } } } } } } private DateTime LastPlayTime = DateTime.Now; private bool IsPlaying =false; private void Window_Loaded(object sender, RoutedEventArgs e) { //Title = DirectInfo.Name + "[" + DirectInfo.Platform + "]特效"; WeakReferenceMessenger.Default.Register(this, OnReceive); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (!IsProcUse) { if (HandyControl.Controls.MessageBox.Show("关闭特效窗口,将导致当前直播特效对应Web功能也同步关闭.\r\n是否确定要关闭?", "关闭确认", MessageBoxButton.OKCancel) != MessageBoxResult.OK) { e.Cancel = true; } else { EffectInfo effectInfo = new EffectInfo(); effectInfo.ID = DirectInfo.Id; effectInfo.EffectMode = -1; WeakReferenceMessenger.Default.Send(new MsgToken(effectInfo) { ID = MsgTokenId.Effects, From = "Effects", Msg = "Close" }); } } try { foreach (var item in PlayingList.Values) { if (item is LiveTools.SoundPlay sound) { sound.Stop(); } } } catch { } } } /// /// 特效信息 /// public class EffectInfo { public int ID { get; set; } = 0; public int RuleID { get; set; } = 0; /// /// 事件类型,0表示发生特效,-1表示要关闭当前窗口。 /// public int EffectMode { get; set; } = 0; /// /// 循环次数 /// public int LoopCount { get; set; } = 1; /// /// 动作列表 /// public JArray ActionList { get; set; } =null; } }