WPF 实现弹幕效果
框架使用
大于等于.NET40;
Visual Studio 2022;
项目使用
MIT 开源许可协议;
此篇代码目的只是为了分享思路
实现基础弹幕一定是要使用Canvas比较简单,只需实现Left动画从右到左。
弹幕消息使用Border做弹幕背景。内容使用TextBlock做消息文本展示。当动画执行完成默认移除Canvas中的弹幕控件。使用这种方式去加载弹幕GPU会占较高。
1) 准备
BarrageExample.xaml如下:
<UserControlx: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/>
<RowDefinitionHeight="Auto"/>
</Grid.RowDefinitions>
<CanvasNam="MyCanvas"Background="Transparent">
</Canvas>
<GridGrid.Row="1"Name="MyGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinitionWidth="Auto"/>
</Grid.ColumnDefinitions>
<TextBoxwpfdev:ElementHelper.IsWatermark="True"
x:Name="tbBarrage"
wpfdev:ElementHelper.Watermark="请弹幕内容"/>
<ButtonGrid.Column="1"Style="{StaticResourcePrimaryButton}"
Content="发射弹幕"Margin="4,0,0,0"
Click="ButtonBase_OnClick"/>
</Grid>
</Grid>
</UserControl>2) 逻辑
BarrageExample.xaml.cs如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Windows;
usingSystem.Windows.Controls;
usingSystem.Windows.Media;
usingSystem.Windows.Media.Animation;
namespaceWPFDevelopers.Samples.ExampleViews
{
///<summary>
///BarrageExample.xaml的交互逻辑
///</summary>
publicpartialclassBarrageExample:UserControl
{
privateDictionary<TimeSpan,List<Border>>_dicBorder;
privatelong_num,_index;
privatedouble_right,_top;
privateRandom_random=newRandom();
publicBarrageExample()
{
InitializeComponent();
_dicBorder=newDictionary<TimeSpan,List<Border>>();
Loaded+=delegate
{
_num=(int)(ActualHeight-MyGrid.ActualHeight)/40;
varlist=newList<string>();
list.Add("2333");
list.Add("测试弹幕");
list.Add("很难开心");
list.Add("map");
list.Add("map加载");
list.Add("bing");
list.Add("地图");
foreach(variteminlist)
{
SolidColorBrushbrush=newSolidColorBrush(Color.FromRgb((byte)_random.Next(1,255),
(byte)_random.Next(1,255),(byte)_random.Next(1,233)));
AddBarrage(brush.Color,item);
}
};
}
voidAddBarrage(Colorcolor,stringtext)
{
_index++;
TimeSpantime=default;
varlinearGradientBrush=newLinearGradientBrush()
{
StartPoint=newPoint(0,0),
EndPoint=newPoint(1,1),
MappingMode=BrushMappingMode.RelativeToBoundingBox,
GradientStops=newGradientStopCollection
{
newGradientStop{Color=Colors.Transparent,Offset=2},
newGradientStop{Color=color},
},
};
varborder=newBorder()
{
Background=linearGradientBrush,
Height=40,
CornerRadius=newCornerRadius(20),
Padding=newThickness(40,0,40,0)
};
vartextBlock=newTextBlock()
{
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;
vary=ActualHeight-MyGrid.ActualHeight-border.ActualHeight;
_top=_top+40>=y?border.ActualHeight:_top;
Canvas.SetLeft(border,_right);
Canvas.SetTop(border,_top);
vardoubleAnimation=newDoubleAnimation
{
From=_right,
To=-(ActualWidth+border.ActualWidth),
Duration=time
};
doubleAnimation.Completed+=(s,e)=>
{
varanimationClock=sasAnimationClock;
if(animationClock==null)return;
varduration=animationClock.Timeline.Duration;
varbordersList=newList<Border>();
_dicBorder.TryGetValue(duration.TimeSpan,outbordersList);
if(bordersList!=null&&bordersList.Count>0)
{
foreach(variteminbordersList)
{
MyCanvas.Children.Remove(item);
}
_dicBorder.Remove(duration.TimeSpan);
}
};
border.BeginAnimation(Canvas.LeftProperty,doubleAnimation);
_top+=border.ActualHeight+20;
if(!_dicBorder.ContainsKey(time))
_dicBorder.Add(time,newList<Border>{border});
else
{
varbordersList=newList<Border>();
_dicBorder.TryGetValue(time,outbordersList);
bordersList.Add(border);
}
};
if(_index>_num)
{
_index=0;
}
}
privatevoidButtonBase_OnClick(objectsender,RoutedEventArgse)
{
SolidColorBrushbrush=newSolidColorBrush(Color.FromRgb((byte)_random.Next(1,255),
(byte)_random.Next(1,255),(byte)_random.Next(1,233)));
AddBarrage(brush.Color,tbBarrage.Text);
}
}
}
以上就是基于WPF实现弹幕效果的示例代码的详细内容,更多关于WPF弹幕的资料请关注中国红客联盟其它相关文章!