基于WPF實現(xiàn)彈幕效果的示例代碼
更新時間:2022年09月13日 10:57:24 作者:驚鏵
這篇文章主要為大家詳細介紹了如何利用WPF實現(xiàn)彈幕效果,文中的示例代碼講解詳細,對我們學習或工作有一定幫助,感興趣的小伙伴可以了解一下
WPF 實現(xiàn)彈幕效果
框架使用大于等于.NET40
;
Visual Studio 2022
;
項目使用 MIT 開源許可協(xié)議;
此篇代碼目的只是為了分享思路
實現(xiàn)基礎彈幕一定是要使用Canvas
比較簡單,只需實現(xiàn)Left
動畫從右到左。
- 彈幕消息使用
Border
做彈幕背景。 - 內容使用
TextBlock
做消息文本展示。 - 當動畫執(zhí)行完成默認移除
Canvas
中的彈幕控件。 - 使用這種方式去加載彈幕
GPU
會占較高。
1) 準備BarrageExample.xaml如下:
<UserControl?x:Class="WPFDevelopers.Samples.ExampleViews.BarrageExample" ?????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" ?????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ?????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"? ?????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"? ?????????????xmlns:wpfdev="https://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="發(fā)射彈幕"?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實現(xiàn)彈幕效果的示例代碼的詳細內容,更多關于WPF彈幕的資料請關注腳本之家其它相關文章!
相關文章
C#利用Openxml讀取Excel數(shù)據(jù)實例
這篇文章主要介紹了C#利用Openxml讀取Excel數(shù)據(jù)的方法,包括使用中的注意點分析及疑難探討,需要的朋友可以參考下2014-09-09