WPF弹幕效果示例代码,如何实现长尾词弹幕?

2026-03-31 09:261阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计883个文字,预计阅读时间需要4分钟。

WPF弹幕效果示例代码,如何实现长尾词弹幕?

WPF 弹窗效果实现与框架使用;适用于 .NET 4.0 及以上;使用 Visual Studio 2022;项目遵循 MIT 开源许可;代码目的仅为分享思路,实现基础弹窗功能;主要利用 Canvas,实现左移效果。

WPF 实现弹幕效果

框架使用大于等于.NET40

Visual Studio 2022;

项目使用MIT开源许可协议;

此篇代码目的只是为了分享思路

实现基础弹幕一定是要使用Canvas比较简单,只需实现Left动画从右到左。

  • 弹幕消息使用Border做弹幕背景。
  • 内容使用TextBlock做消息文本展示。
  • 当动画执行完成默认移除Canvas中的弹幕控件。
  • 使用这种方式去加载弹幕GPU会占较高。

1) 准备BarrageExample.xaml如下:

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.BarrageExample"              xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="schemas.microsoft.com/winfx/2006/xaml"              xmlns:mc="schemas.openxmlformats.org/markup-compatibility/2006"               xmlns:d="schemas.microsoft.com/expression/blend/2008"               xmlns:wpfdev="github.com/WPFDevelopersOrg/WPFDevelopers"              xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"              mc:Ignorable="d"               d:DesignHeight="450" d:DesignWidth="800">     <Grid>         <Grid.RowDefinitions>             <RowDefinition/>             <RowDefinition Height="Auto"/>         </Grid.RowDefinitions>         <Canvas Name="MyCanvas" Background="Transparent">         </Canvas>         <Grid Grid.Row="1" Name="MyGrid">             <Grid.ColumnDefinitions>                 <ColumnDefinition/>                 <ColumnDefinition Width="Auto"/>             </Grid.ColumnDefinitions>             <TextBox wpfdev:ElementHelper.IsWatermark="True"                      x:Name="tbBarrage"                      wpfdev:ElementHelper.Watermark="请弹幕内容"/>             <Button Grid.Column="1" Style="{StaticResource PrimaryButton}"                     Content="发射弹幕" Margin="4,0,0,0"                      Click="ButtonBase_OnClick"/>         </Grid>     </Grid> </UserControl>

2) 逻辑BarrageExample.xaml.cs如下:

using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; namespace WPFDevelopers.Samples.ExampleViews {     /// <summary>     /// BarrageExample.xaml 的交互逻辑     /// </summary>     public partial class BarrageExample : UserControl     {         private Dictionary<TimeSpan, List<Border>> _dicBorder;         private long _num, _index;         private double _right, _top;         private Random _random = new Random();         public BarrageExample()         {             InitializeComponent();             _dicBorder = new Dictionary<TimeSpan, List<Border>>();             Loaded += delegate             {                 _num = (int)(ActualHeight - MyGrid.ActualHeight) / 40;                 var list = new List<string>();                 list.Add("2333");                 list.Add("测试弹幕");                 list.Add("很难开心");                 list.Add("map");                 list.Add("map加载");                 list.Add("bing");                 list.Add("地图");                 foreach (var item in list)                 {                     SolidColorBrush brush = new SolidColorBrush(Color.FromRgb((byte)_random.Next(1, 255),                         (byte)_random.Next(1, 255), (byte)_random.Next(1, 233)));                     AddBarrage(brush.Color, item);                 }             };         }         void AddBarrage(Color color, string text)         {             _index++;             TimeSpan time = default;             var linearGradientBrush = new LinearGradientBrush()             {                 StartPoint = new Point(0, 0),                 EndPoint = new Point(1, 1),                 MappingMode = BrushMappingMode.RelativeToBoundingBox,                 GradientStops = new GradientStopCollection                 {                     new GradientStop { Color = Colors.Transparent, Offset = 2},                     new GradientStop { Color = color },                 },             };             var border = new Border()             {                 Background = linearGradientBrush,                 Height = 40,                 CornerRadius = new CornerRadius(20),                 Padding = new Thickness(40, 0, 40, 0)             };             var textBlock = new TextBlock()             {                 Text = text,                 Foreground = Brushes.White,                 VerticalAlignment = VerticalAlignment.Center,             };             border.Child = textBlock;             MyCanvas.Children.Add(border);             border.Loaded += delegate             {                 time = TimeSpan.FromMilliseconds(border.ActualWidth * 60);                 _right = _right == 0 ? ActualWidth + border.ActualWidth : _right;                 var y = ActualHeight - MyGrid.ActualHeight - border.ActualHeight;                 _top = _top + 40 >= y ? border.ActualHeight : _top;                 Canvas.SetLeft(border, _right);                 Canvas.SetTop(border, _top);                 var doubleAnimation = new DoubleAnimation                 {                     From = _right,                     To = -(ActualWidth + border.ActualWidth),                     Duration = time                 };                 doubleAnimation.Completed += (s, e) =>                 {                     var animationClock = s as AnimationClock;                     if (animationClock == null) return;                     var duration = animationClock.Timeline.Duration;                     var bordersList = new List<Border>();                     _dicBorder.TryGetValue(duration.TimeSpan, out bordersList);                     if (bordersList != null && bordersList.Count > 0)                     {                         foreach (var item in bordersList)                         {                             MyCanvas.Children.Remove(item);                         }                         _dicBorder.Remove(duration.TimeSpan);                     }                 };                 border.BeginAnimation(Canvas.LeftProperty, doubleAnimation);                 _top += border.ActualHeight + 20;                 if (!_dicBorder.ContainsKey(time))                     _dicBorder.Add(time, new List<Border> { border });                 else                 {                     var bordersList = new List<Border>();                     _dicBorder.TryGetValue(time, out bordersList);                     bordersList.Add(border);                 }             };             if (_index > _num)             {                 _index = 0;             }         }         private void ButtonBase_OnClick(object sender, RoutedEventArgs e)         {             SolidColorBrush brush = new SolidColorBrush(Color.FromRgb((byte)_random.Next(1, 255),                 (byte)_random.Next(1, 255), (byte)_random.Next(1, 233)));             AddBarrage(brush.Color, tbBarrage.Text);         }     } }

以上就是基于WPF实现弹幕效果的示例代码的详细内容,更多关于WPF弹幕的资料请关注自由互联其它相关文章!

WPF弹幕效果示例代码,如何实现长尾词弹幕?

本文共计883个文字,预计阅读时间需要4分钟。

WPF弹幕效果示例代码,如何实现长尾词弹幕?

WPF 弹窗效果实现与框架使用;适用于 .NET 4.0 及以上;使用 Visual Studio 2022;项目遵循 MIT 开源许可;代码目的仅为分享思路,实现基础弹窗功能;主要利用 Canvas,实现左移效果。

WPF 实现弹幕效果

框架使用大于等于.NET40

Visual Studio 2022;

项目使用MIT开源许可协议;

此篇代码目的只是为了分享思路

实现基础弹幕一定是要使用Canvas比较简单,只需实现Left动画从右到左。

  • 弹幕消息使用Border做弹幕背景。
  • 内容使用TextBlock做消息文本展示。
  • 当动画执行完成默认移除Canvas中的弹幕控件。
  • 使用这种方式去加载弹幕GPU会占较高。

1) 准备BarrageExample.xaml如下:

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.BarrageExample"              xmlns="schemas.microsoft.com/winfx/2006/xaml/presentation"              xmlns:x="schemas.microsoft.com/winfx/2006/xaml"              xmlns:mc="schemas.openxmlformats.org/markup-compatibility/2006"               xmlns:d="schemas.microsoft.com/expression/blend/2008"               xmlns:wpfdev="github.com/WPFDevelopersOrg/WPFDevelopers"              xmlns:local="clr-namespace:WPFDevelopers.Samples.ExampleViews"              mc:Ignorable="d"               d:DesignHeight="450" d:DesignWidth="800">     <Grid>         <Grid.RowDefinitions>             <RowDefinition/>             <RowDefinition Height="Auto"/>         </Grid.RowDefinitions>         <Canvas Name="MyCanvas" Background="Transparent">         </Canvas>         <Grid Grid.Row="1" Name="MyGrid">             <Grid.ColumnDefinitions>                 <ColumnDefinition/>                 <ColumnDefinition Width="Auto"/>             </Grid.ColumnDefinitions>             <TextBox wpfdev:ElementHelper.IsWatermark="True"                      x:Name="tbBarrage"                      wpfdev:ElementHelper.Watermark="请弹幕内容"/>             <Button Grid.Column="1" Style="{StaticResource PrimaryButton}"                     Content="发射弹幕" Margin="4,0,0,0"                      Click="ButtonBase_OnClick"/>         </Grid>     </Grid> </UserControl>

2) 逻辑BarrageExample.xaml.cs如下:

using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation; namespace WPFDevelopers.Samples.ExampleViews {     /// <summary>     /// BarrageExample.xaml 的交互逻辑     /// </summary>     public partial class BarrageExample : UserControl     {         private Dictionary<TimeSpan, List<Border>> _dicBorder;         private long _num, _index;         private double _right, _top;         private Random _random = new Random();         public BarrageExample()         {             InitializeComponent();             _dicBorder = new Dictionary<TimeSpan, List<Border>>();             Loaded += delegate             {                 _num = (int)(ActualHeight - MyGrid.ActualHeight) / 40;                 var list = new List<string>();                 list.Add("2333");                 list.Add("测试弹幕");                 list.Add("很难开心");                 list.Add("map");                 list.Add("map加载");                 list.Add("bing");                 list.Add("地图");                 foreach (var item in list)                 {                     SolidColorBrush brush = new SolidColorBrush(Color.FromRgb((byte)_random.Next(1, 255),                         (byte)_random.Next(1, 255), (byte)_random.Next(1, 233)));                     AddBarrage(brush.Color, item);                 }             };         }         void AddBarrage(Color color, string text)         {             _index++;             TimeSpan time = default;             var linearGradientBrush = new LinearGradientBrush()             {                 StartPoint = new Point(0, 0),                 EndPoint = new Point(1, 1),                 MappingMode = BrushMappingMode.RelativeToBoundingBox,                 GradientStops = new GradientStopCollection                 {                     new GradientStop { Color = Colors.Transparent, Offset = 2},                     new GradientStop { Color = color },                 },             };             var border = new Border()             {                 Background = linearGradientBrush,                 Height = 40,                 CornerRadius = new CornerRadius(20),                 Padding = new Thickness(40, 0, 40, 0)             };             var textBlock = new TextBlock()             {                 Text = text,                 Foreground = Brushes.White,                 VerticalAlignment = VerticalAlignment.Center,             };             border.Child = textBlock;             MyCanvas.Children.Add(border);             border.Loaded += delegate             {                 time = TimeSpan.FromMilliseconds(border.ActualWidth * 60);                 _right = _right == 0 ? ActualWidth + border.ActualWidth : _right;                 var y = ActualHeight - MyGrid.ActualHeight - border.ActualHeight;                 _top = _top + 40 >= y ? border.ActualHeight : _top;                 Canvas.SetLeft(border, _right);                 Canvas.SetTop(border, _top);                 var doubleAnimation = new DoubleAnimation                 {                     From = _right,                     To = -(ActualWidth + border.ActualWidth),                     Duration = time                 };                 doubleAnimation.Completed += (s, e) =>                 {                     var animationClock = s as AnimationClock;                     if (animationClock == null) return;                     var duration = animationClock.Timeline.Duration;                     var bordersList = new List<Border>();                     _dicBorder.TryGetValue(duration.TimeSpan, out bordersList);                     if (bordersList != null && bordersList.Count > 0)                     {                         foreach (var item in bordersList)                         {                             MyCanvas.Children.Remove(item);                         }                         _dicBorder.Remove(duration.TimeSpan);                     }                 };                 border.BeginAnimation(Canvas.LeftProperty, doubleAnimation);                 _top += border.ActualHeight + 20;                 if (!_dicBorder.ContainsKey(time))                     _dicBorder.Add(time, new List<Border> { border });                 else                 {                     var bordersList = new List<Border>();                     _dicBorder.TryGetValue(time, out bordersList);                     bordersList.Add(border);                 }             };             if (_index > _num)             {                 _index = 0;             }         }         private void ButtonBase_OnClick(object sender, RoutedEventArgs e)         {             SolidColorBrush brush = new SolidColorBrush(Color.FromRgb((byte)_random.Next(1, 255),                 (byte)_random.Next(1, 255), (byte)_random.Next(1, 233)));             AddBarrage(brush.Color, tbBarrage.Text);         }     } }

以上就是基于WPF实现弹幕效果的示例代码的详细内容,更多关于WPF弹幕的资料请关注自由互联其它相关文章!

WPF弹幕效果示例代码,如何实现长尾词弹幕?