• 【MediaElement】WPF视频播放器【2】


    一、前言

          上回说到需要做放视频的使用向导,这两天公司里的老司机一直帮我答疑解惑,让这个任务变得挺顺的,真心感谢他们!

           这次与【1】中的不同之处在于:

           (1)播放和暂停按钮集成在<MediaElement>的点击事件之中,点一下是播放,再点一下是暂停

           (2)加入了微软官方改写的粒子特效

           (3)加上了自己琢磨的按钮旋转效果,以及按钮弹出popup效果

           (4)进度条改善美观

    二、代码

          前台:

      1 <Window
      2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      4         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      5         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      6         xmlns:local="clr-namespace:WPF_Nav"
      7         xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol" xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui" x:Class="WPF_Nav.MainWindow"
      8         mc:Ignorable="d"
      9         Title="MainWindow" Height="600" Width="800" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation ="CenterScreen" Loaded="Window_Loaded">
     10 
     11     <Window.Resources>
     12         <LinearGradientBrush x:Key="SliderBackground"  StartPoint="0,0" EndPoint="0,1">
     13             <GradientStop Offset="0.5" Color="#00b3fe"/>
     14         </LinearGradientBrush>
     15         <LinearGradientBrush x:Key="SliderThumb"  StartPoint="0,0" EndPoint="0,1">
     16             <GradientStop Offset="0" Color="#FFD9D3E8"/>
     17         </LinearGradientBrush>
     18 
     19         <Style x:Key="Slider_RepeatButton" TargetType="RepeatButton">
     20             <Setter Property="Focusable" Value="false" />
     21             <Setter Property="Height" Value="5"/>
     22             <Setter Property="BorderBrush" Value="Transparent"/>
     23             <Setter Property="Template">
     24                 <Setter.Value>
     25                     <ControlTemplate TargetType="RepeatButton">
     26                         <Border Background="{StaticResource SliderBackground}" />
     27                     </ControlTemplate>
     28                 </Setter.Value>
     29             </Setter>
     30         </Style>
     31 
     32         <Style x:Key="Slider_RepeatButton1" TargetType="RepeatButton">
     33             <Setter Property="Focusable" Value="false" />
     34             <Setter Property="Height" Value="5"/>
     35             <Setter Property="BorderBrush" Value="Transparent"/>
     36             <Setter Property="Template">
     37                 <Setter.Value>
     38                     <ControlTemplate TargetType="RepeatButton">
     39                         <Border Background="Silver" />
     40                     </ControlTemplate>
     41                 </Setter.Value>
     42             </Setter>
     43         </Style>
     44 
     45         <Style x:Key="Slider_Thumb" TargetType="Thumb">
     46             <Setter Property="Focusable" Value="false" />
     47             <Setter Property="Template">
     48                 <Setter.Value>
     49                     <ControlTemplate TargetType="Thumb">
     50                         <Ellipse Name="e" Width="15" Height="15" Fill="White" Stroke="Gray"/>
     51                     </ControlTemplate>
     52                 </Setter.Value>
     53             </Setter>
     54         </Style>
     55 
     56         <Style  TargetType="Slider">
     57             <Setter Property="Focusable" Value="false" />
     58             <Setter Property="Template">
     59                 <Setter.Value>
     60                     <ControlTemplate TargetType="Slider">
     61                         <Grid>
     62                             <Border BorderBrush="Red" BorderThickness="0" CornerRadius="0,0,0,0">
     63                                 <Track  Name="PART_Track">
     64                                     <Track.DecreaseRepeatButton>
     65                                         <RepeatButton Style="{StaticResource Slider_RepeatButton}" Command="Slider.DecreaseLarge"/>
     66                                     </Track.DecreaseRepeatButton>
     67                                     <Track.IncreaseRepeatButton>
     68                                         <RepeatButton Style="{StaticResource Slider_RepeatButton1}" Command="Slider.IncreaseLarge"/>
     69                                     </Track.IncreaseRepeatButton>
     70                                     <Track.Thumb>
     71                                         <Thumb Style="{StaticResource Slider_Thumb}"/>
     72                                     </Track.Thumb>
     73                                 </Track>
     74                             </Border>
     75                         </Grid>
     76                     </ControlTemplate>
     77                 </Setter.Value>
     78             </Setter>
     79         </Style>
     80 
     81 
     82         <Style x:Key="Button_Close" TargetType="Button">
     83             <Setter Property="Template">
     84                 <Setter.Value>
     85                     <ControlTemplate>
     86                         <Image x:Name="IMG" Source="E:TestWPFTestSourcesClose.jpg"></Image>
     87                     </ControlTemplate>
     88                 </Setter.Value>
     89             </Setter>
     90         </Style>
     91 
     92         <Style x:Key="Button_Forbidden" TargetType="Button">
     93             <Setter Property="Template">
     94                 <Setter.Value>
     95                     <ControlTemplate>
     96                         <Image x:Name="IMG" Source="E:TestWPFTestSourcesForbidden.jpg"></Image>
     97                     </ControlTemplate>
     98                 </Setter.Value>
     99             </Setter>
    100         </Style>
    101 
    102 
    103         <Style x:Key="Button_Left" TargetType="Button">
    104             <Setter Property="Template">
    105                 <Setter.Value>
    106                     <ControlTemplate>
    107                         <Image x:Name="IMG" Source="E:TestWPFTestSourcesLeft.png" Stretch="Fill"></Image>
    108                     </ControlTemplate>
    109                 </Setter.Value>
    110             </Setter>
    111         </Style>
    112 
    113 
    114         <Style x:Key="Button_Right" TargetType="Button">
    115             <Setter Property="Template">
    116                 <Setter.Value>
    117                     <ControlTemplate>
    118                         <Image x:Name="IMG" Source="E:TestWPFTestSourcesRight.png" Stretch="Fill"></Image>
    119                     </ControlTemplate>
    120                 </Setter.Value>
    121             </Setter>
    122         </Style>
    123 
    124     </Window.Resources>
    125 
    126     <Grid Name="Main_Grid">
    127         <Grid.RowDefinitions>
    128             <RowDefinition Height="50"></RowDefinition>
    129             <RowDefinition Height="500"></RowDefinition>
    130             <RowDefinition Height="50"></RowDefinition>
    131         </Grid.RowDefinitions>
    132 
    133         <Border Name="title_Border" BorderBrush="#FBD3D0CD" BorderThickness="3" Grid.Row="0">
    134             <Grid Name="Title">
    135                 <Grid.ColumnDefinitions>
    136                     <ColumnDefinition Width="200"></ColumnDefinition>
    137                     <ColumnDefinition Width="400"></ColumnDefinition>
    138                     <ColumnDefinition Width="120"></ColumnDefinition>
    139                     <ColumnDefinition Width="80"></ColumnDefinition>
    140                 </Grid.ColumnDefinitions>
    141 
    142                 <Grid Grid.Column="1">
    143                     <Canvas x:Name="ParticleHost" Width="400" >
    144                         <TextBlock Name="txtB_Step" Grid.Column="1"  Width="200" Height="30" TextAlignment="Center" FontSize="20" FontFamily="Microsoft YaHei" Text="asss" Margin="100,7,0,0"/>
    145                     </Canvas>
    146                 </Grid>
    147                 
    148                 <Grid Name="grid_Cofig" Grid.Column="3">
    149                 <Button Name="btn_Forbidden"  Width="30" Click="Config_Click" Margin="2,10,48,12" HorizontalAlignment="Center"  Focusable="False" Style="{StaticResource Button_Forbidden}" RenderTransformOrigin="0.5,0.5" ToolTipService.ToolTip="播放设置"  ToolTipService.InitialShowDelay="1" ToolTipService.Placement="Bottom">
    150                     <Button.RenderTransform>
    151                         <RotateTransform x:Name="trans_forbidden" Angle="0"/>
    152                     </Button.RenderTransform>
    153                     <Button.Triggers>
    154                         <EventTrigger RoutedEvent="Button.MouseEnter">
    155                             <BeginStoryboard >
    156                                 <Storyboard>
    157                                     <DoubleAnimation From="0" To="90"  Duration="0:0:0.4"
    158                                              Storyboard.TargetName="trans_forbidden"
    159                                              Storyboard.TargetProperty="Angle"/>
    160                                 </Storyboard>
    161                             </BeginStoryboard>
    162                         </EventTrigger>
    163                     </Button.Triggers>
    164                 </Button>
    165                 </Grid>
    166 
    167                 <Popup x:Name="Pop" PopupAnimation="Slide" Placement="Bottom"  Width="93" Height="58" PlacementTarget="{Binding ElementName=grid_Cofig}" AllowsTransparency="True" StaysOpen="False" IsOpen="False" >
    168                     <Border Background="White"  BorderBrush="#FFC4C9CD" BorderThickness="2" Width="93">
    169                         <StackPanel Margin="1">
    170                             <StackPanel Name="sp_play" Orientation="Horizontal" Width="83" Height="22" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2" MouseEnter="sp_play_enter" MouseLeave="sp_play_leave" >
    171                                 <CheckBox x:Name="ch_play" VerticalAlignment="Center" Margin="3,4" />
    172                                 <TextBlock x:Name="txb_play" Text="不再播放" Margin="5,0" VerticalAlignment="Center"/>
    173                             </StackPanel>
    174                             <StackPanel Name="sp_doc" Width="83" Height="22" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2" MouseEnter="sp_doc_enter" MouseLeave="sp_doc_leave">
    175                                 <TextBlock Name="txb_Doc" Text="官方帮助文档" Margin="4,0,5,0" VerticalAlignment="Center">
    176                                 </TextBlock>
    177                             </StackPanel>
    178                         </StackPanel>
    179                     </Border>
    180                 </Popup>
    181 
    182                 <Button Name="btn_Close" Grid.Column="3" Width="30" Click="Close_Click" Margin="37,10,13,12" HorizontalAlignment="Center"  Focusable="False" Style="{StaticResource Button_Close}" RenderTransformOrigin="0.5,0.5" ToolTipService.ToolTip="关闭视频"  ToolTipService.InitialShowDelay="1" ToolTipService.Placement="Bottom">
    183                     <Button.RenderTransform>
    184                         <RotateTransform x:Name="trans" Angle="0"/>
    185                     </Button.RenderTransform>
    186                     <Button.Triggers>
    187                         <EventTrigger RoutedEvent="Button.MouseEnter">
    188                             <BeginStoryboard >
    189                                 <Storyboard>
    190                                     <DoubleAnimation From="0" To="90"  Duration="0:0:0.4"
    191                                              Storyboard.TargetName="trans"
    192                                              Storyboard.TargetProperty="Angle"/>
    193                                 </Storyboard>
    194                             </BeginStoryboard>
    195                         </EventTrigger>
    196                     </Button.Triggers>
    197                 </Button>
    198 
    199             </Grid>
    200         </Border>
    201 
    202 
    203         <Grid Name="Movie" Grid.Row="1">
    204             <MediaElement Stretch="Fill" LoadedBehavior="Manual" Name="QS_Movie" MediaOpened="Element_MediaOpened" Loaded="QS_Movie_Loaded" MouseLeftButtonDown="QS_Movie_MouseLeftButtonDown" />
    205             <Button Name="btn_pre" Width="30" Height="40" HorizontalAlignment="Left" VerticalAlignment="Center" Click="Left_Click"  Focusable="False"  Style="{StaticResource Button_Left}"/>
    206             <Button Name="btn_next" Width="30" Height="40" HorizontalAlignment="Right" VerticalAlignment="Center" Click="Right_Click" Focusable="False" Style="{StaticResource Button_Right}"/>
    207         </Grid>
    208 
    209 
    210         <Border Name="Progress_Border" BorderBrush="#FBD3D0CD" BorderThickness="3" Grid.Row="2">
    211             <Grid Name="Control_Progress" >
    212                 <Slider Grid.Column="0" Width="700" Name="timelineSlider" VerticalAlignment="Center"  PreviewMouseLeftButtonDown="timelineMDown"  PreviewMouseLeftButtonUp="timelineMUp" BorderThickness="0,6,0,0" />
    213             </Grid>
    214         </Border>
    215 
    216     </Grid>
    217 </Window>

           后台:

     1 using System.Windows.Media;
     2 using System.Windows.Media.Effects;
     3 using System.Windows.Shapes;
     4 
     5 namespace WPF_Nav
     6 {
     7     public class Particle
     8     {
     9         public Point3D Position { get; set; }
    10         public Point3D Velocity { get; set; }
    11         public double Size { get; set; }
    12         public Ellipse Ellipse { get; set; }
    13         public BlurEffect Blur { get; set; }
    14         public Brush Brush { get; set; }
    15     }
    16 }
     1 namespace WPF_Nav
     2 {
     3     public class Point3D
     4     {
     5         public double X { get; set; }
     6         public double Y { get; set; }
     7         public double Z { get; set; }
     8 
     9         public Point3D(double X, double Y, double Z)
    10         {
    11             this.X = X;
    12             this.Y = Y;
    13             this.Z = Z;
    14         }
    15     }
    16 }

         主体:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Threading.Tasks;
      6 using System.Windows;
      7 using System.Windows.Controls;
      8 using System.Windows.Controls.Primitives;
      9 using System.Windows.Data;
     10 using System.Windows.Documents;
     11 using System.Windows.Input;
     12 using System.Windows.Media;
     13 using System.Windows.Media.Imaging;
     14 using System.Windows.Navigation;
     15 using System.Windows.Shapes;
     16 using System.Windows.Threading;
     17 using System.Windows.Media.Effects;
     18 
     19 namespace WPF_Nav
     20 {
     21     /// <summary>
     22     /// MainWindow.xaml 的交互逻辑
     23     /// </summary>
     24     public partial class MainWindow : Window
     25     {
     26         DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer(); // 定义一个DT
     27         bool play_flag = true;  //判断播放状态
     28         int play_now = 0;       //判断当前视频索引
     29         int play_target;
     30         List<string> Play_Video = new List<string>();
     31         List<string> Title_Video = new List<string>();
     32 
     33 
     34 
     35         public MainWindow()
     36         {
     37             InitializeComponent();
     38             Play_Video = LoadMovies();
     39             Title_Video = LoadTitles();
     40         }
     41 
     42         private List<string> LoadTitles()
     43         {
     44             List<string> list_title = new List<string>();
     45             list_title.Add("Step1");
     46             list_title.Add("Step2");
     47             list_title.Add("Step3");
     48             return list_title;
     49         }
     50         private List<string> LoadMovies()
     51         {
     52             List<string> Movie_Uri = new List<string>();
     53             Movie_Uri.Add(@"E:TestWPFTestSourcespreview.mp4");
     54             Movie_Uri.Add(@"E:TestWPFTestSourcespreview1.mp4");
     55             Movie_Uri.Add(@"E:TestWPFTestSourcespreview2.mp4");
     56             return Movie_Uri;
     57         }
     58 
     59         private void Play_Click(object sender, RoutedEventArgs e)
     60         {         
     61             QS_Movie.Play();          
     62         }
     63 
     64         private void Pause_Click(object sender, RoutedEventArgs e)
     65         {
     66             QS_Movie.Pause();         
     67         }
     68 
     69         private void Element_MediaOpened(object sender, EventArgs e)
     70         {
     71             timelineSlider.Maximum = QS_Movie.NaturalDuration.TimeSpan.TotalMilliseconds;  //设置slider最大值
     72             dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick); //超过计时间隔时发生
     73             dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 0, 200); //DT间隔
     74             dispatcherTimer.Start(); //DT启动 
     75         }
     76 
     77         private void dispatcherTimer_Tick(object sender, EventArgs e)
     78         {
     79             int time = (int)QS_Movie.Position.TotalSeconds;
     80             timelineSlider.ToolTip = SecToTime(time);
     81             timelineSlider.Value = QS_Movie.Position.TotalMilliseconds; //slider滑动值随播放内容位置变化
     82         }
     83 
     84         private string SecToTime(int sec)
     85         {
     86             int min = sec / 60;
     87             sec = sec - min * 60;
     88             int hour = min / 60;
     89             min = min - hour * 60;
     90             string h = hour.ToString();
     91             string mm = ((min < 10) ? "0" : "") + min.ToString();
     92             string ss = ((sec < 10) ? "0" : "") + sec.ToString();
     93             string time = h + ":" + mm + ":" + ss;
     94             return time;
     95         }
     96         private void timelineMDown(object sender, EventArgs e)
     97         {
     98             dispatcherTimer.Stop();
     99         }
    100         private void timelineMUp(object sender, EventArgs e)
    101         {
    102             QS_Movie.Position = new TimeSpan(0, 0, 0, 0, (int)timelineSlider.Value);
    103             dispatcherTimer.Start();
    104             QS_Movie.Play();
    105         }
    106 
    107         
    108 
    109         private void QS_Movie_Loaded(object sender, RoutedEventArgs e)
    110         {
    111             PreLoad(400,play_now);
    112             
    113         }
    114 
    115         private void Left_Click(object sender, RoutedEventArgs e)
    116         {
    117                 play_target = (play_now + Play_Video.Count-1) % Play_Video.Count;
    118                 PreLoad(200, play_target);
    119                 play_now = play_target;           
    120         }
    121 
    122         private void Right_Click(object sender, RoutedEventArgs e)
    123         {
    124                play_target = (play_now + 1) % Play_Video.Count;
    125                PreLoad(200, play_target);
    126                play_now = play_target;
    127         }
    128 
    129         private void PreLoad(int interval, int index)
    130         {
    131             QS_Movie.Source = new Uri(Play_Video[index]);          
    132             QS_Movie.Play();
    133             System.Threading.Thread.Sleep(interval);
    134             QS_Movie.Pause();
    135             txtB_Step.Text = Title_Video[index];
    136         }
    137 
    138 
    139 
    140         
    141 
    142         private void QS_Movie_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    143         {
    144             
    145             if(play_flag==true)
    146             {
    147                 QS_Movie.Play();
    148                 btn_pre.Visibility = System.Windows.Visibility.Hidden;                            
    149                 btn_next.Visibility = btn_pre.Visibility = System.Windows.Visibility.Hidden;               
    150             }
    151             if(play_flag==false)
    152             {
    153                 QS_Movie.Pause();
    154                 btn_pre.Visibility = System.Windows.Visibility.Visible;
    155                 btn_next.Visibility = System.Windows.Visibility.Visible;
    156                                
    157             }
    158             play_flag = !play_flag;
    159         }
    160 
    161         private void Close_Click(object sender, RoutedEventArgs e)
    162         {
    163             this.Close();
    164         }
    165 
    166         private void Config_Click(object sender, RoutedEventArgs e)
    167         {
    168             this.Pop.IsOpen = true;
    169         }
    170 
    171         private void sp_play_enter(object sender, MouseEventArgs e)
    172         {
    173             Brush br_bg = new SolidColorBrush(Color.FromRgb(0, 162, 232));
    174             Brush br_white = new SolidColorBrush(Color.FromRgb(255, 255, 255));
    175             txb_play.Foreground = br_white;
    176             sp_play.Background = br_bg;
    177         }
    178 
    179         private void sp_play_leave(object sender, MouseEventArgs e)
    180         {
    181             Brush br_white = new SolidColorBrush(Color.FromRgb(255, 255, 255));
    182             Brush br_black = new SolidColorBrush(Color.FromRgb(0, 0, 0));
    183             txb_play.Foreground = br_black;
    184             sp_play.Background = br_white;
    185         }
    186 
    187         private void sp_doc_enter(object sender, MouseEventArgs e)
    188         {
    189             Brush br_bg = new SolidColorBrush(Color.FromRgb(0, 162, 232));
    190             Brush br_white = new SolidColorBrush(Color.FromRgb(255, 255, 255));
    191             txb_Doc.Foreground = br_white;
    192             sp_doc.Background = br_bg;
    193         }
    194 
    195         private void sp_doc_leave(object sender, MouseEventArgs e)
    196         {
    197             Brush br_white = new SolidColorBrush(Color.FromRgb(255, 255, 255));
    198             Brush br_black = new SolidColorBrush(Color.FromRgb(0, 0, 0));
    199             txb_Doc.Foreground = br_black;
    200             sp_doc.Background = br_white;
    201         }
    202 
    203 
    204 
    205 
    206 
    207 
    208         /// <summary>
    209         /// 特效部分
    210         /// </summary>
    211      
    212         List<Particle> particles = new List<Particle>();
    213         List<Particle> deadList = new List<Particle>();
    214         Random random = new Random();
    215 
    216 
    217         private void Window_Loaded(object sender, RoutedEventArgs e)
    218         {
    219             timer.Interval = TimeSpan.FromMilliseconds(10);
    220             timer.Tick += new EventHandler(timer_Tick);
    221             timer.Start();
    222         }
    223 
    224         void timer_Tick(object sender, EventArgs e)
    225         {
    226             UpdateParticules();
    227         }
    228 
    229         DispatcherTimer timer = new DispatcherTimer();
    230 
    231         double elapsed = 0.1;
    232         private void UpdateParticules()
    233         {
    234             //更新粒子信息
    235             deadList.Clear();
    236             foreach (Particle p in this.particles)
    237             {
    238                 if (p.Position.Y < -p.Size || p.Position.X < -p.Size || p.Position.X > Width + p.Size)
    239                 {
    240                     deadList.Add(p);
    241                 }
    242                 else
    243                 {
    244                     //更新位置
    245                     p.Position.X += p.Velocity.X * elapsed;
    246                     p.Position.Y += p.Velocity.Y * elapsed;
    247                     p.Position.Z += p.Velocity.Z * elapsed;
    248                     TranslateTransform t = (p.Ellipse.RenderTransform as TranslateTransform);
    249                     t.X = p.Position.X;
    250                     t.Y = p.Position.Y;
    251 
    252                     //更新颜色信息
    253                     p.Ellipse.Fill = p.Brush;
    254                     p.Ellipse.Effect = p.Blur;
    255                 }
    256             }
    257 
    258             //创建新的粒子
    259             for (int i = 0; i < 10 && this.particles.Count < 40; i++)
    260             {
    261                 //尝试循环使用已有例子
    262                 if (deadList.Count - 1 >= i)
    263                 {
    264                     SpawnParticle(deadList[i].Ellipse);
    265                     deadList[i].Ellipse = null;
    266                 }
    267                 else
    268                 {
    269                     SpawnParticle(null);
    270                 }
    271             }
    272 
    273             foreach (Particle p in deadList)
    274             {
    275                 if (p.Ellipse != null) ParticleHost.Children.Remove(p.Ellipse);
    276                 this.particles.Remove(p);
    277             }
    278         }
    279 
    280         private void SpawnParticle(Ellipse e)
    281         {
    282             double x = RandomWithVariance(Width / 2, Width / 2);
    283             double y = Height;
    284             double z = 10 * (random.NextDouble() * 100);
    285             double speed = RandomWithVariance(10, 10);
    286             double size = RandomWithVariance(10,10);
    287 
    288             Particle p = new Particle();
    289             p.Position = new Point3D(x, y, z);
    290             p.Size = size;
    291 
    292             //模糊
    293             var blur = new BlurEffect();
    294             blur.RenderingBias = RenderingBias.Performance;
    295             blur.Radius = RandomWithVariance(5, 5);
    296             p.Blur = blur;
    297             //颜色
    298             var brush = (Brush)Brushes.Lime.Clone();
    299             brush.Opacity = RandomWithVariance(0.6, 0.5);
    300             p.Brush = brush;
    301 
    302             TranslateTransform t;
    303 
    304             if (e != null)
    305             {
    306                 e.Fill = null;
    307                 e.Width = e.Height = size;
    308                 p.Ellipse = e;
    309 
    310                 t = e.RenderTransform as TranslateTransform;
    311             }
    312             else
    313             {
    314                 p.Ellipse = new Ellipse();
    315                 p.Ellipse.Width = p.Ellipse.Height = size;
    316                 this.ParticleHost.Children.Add(p.Ellipse);
    317 
    318                 t = new TranslateTransform();
    319                 p.Ellipse.RenderTransform = t;
    320                 p.Ellipse.RenderTransformOrigin = new Point(0.5, 0.5);
    321 
    322             }
    323 
    324             t.X = p.Position.X;
    325             t.Y = p.Position.Y;
    326 
    327             double velocityMultiplier = (random.NextDouble() + 0.25) * speed;
    328             double vX = (1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier;
    329             double vY = -Math.Abs((1.0 - (random.NextDouble() * 2.0)) * velocityMultiplier);
    330 
    331             p.Velocity = new Point3D(vX, vY, 0);
    332 
    333             this.particles.Add(p);
    334         }
    335 
    336         private double RandomWithVariance(double midvalue, double variance)
    337         {
    338             double min = Math.Max(midvalue - (variance / 2), 0);
    339             double max = midvalue + (variance / 2);
    340             double value = min + ((max - min) * random.NextDouble());
    341             return value;
    342         }
    343 
    344     }
    345 
    346 
    347 
    348 }

     三、效果

    四、小结

          WPF挺好玩的!前台就能解决一些基本的动画效果,加上后台简直爽。最后,感谢单位的老司机们!

  • 相关阅读:
    算法之路 level 01 problem set
    算法原理与实践(链表)
    散列表(HashTable)
    系统设计与实践(实战演练)
    桶排序 + 基数排序
    算法原理与实践(二叉树)
    Total Difference String
    【翻译】std::list::remove
    【翻译】std::remove
    Observer模式实践
  • 原文地址:https://www.cnblogs.com/lovecsharp094/p/5634540.html
Copyright © 2020-2023  润新知