最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

WPF+SkiaSharp實(shí)現(xiàn)自繪彈幕效果

 更新時(shí)間:2022年09月26日 09:44:11   作者:驚鏵  
這篇文章主要為大家詳細(xì)介紹了如何利用WPF和SkiaSharp實(shí)現(xiàn)自制彈幕效果,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定幫助,感興趣的小伙伴可以了解一下

SkiaSharp 自繪彈幕效果

框架使用.NET60;

Visual Studio 2022;

項(xiàng)目使用 MIT 開源許可協(xié)議;

接著上一篇 WPF 彈幕

上期有網(wǎng)友建議使用Skia實(shí)現(xiàn)彈幕。

  • 彈幕消息使用SKElement做彈幕展現(xiàn),然后在SKCanvas進(jìn)行繪制彈幕。
  • 由于需要繪制矩形與文本所以需要使用到SKBitmap進(jìn)行繪制彈幕類。
  • 創(chuàng)建SKBitmap設(shè)置寬(根據(jù)文本的長度定義寬度)與高度40。
  • 創(chuàng)建對象SKCanvas并實(shí)例化的時(shí)候?qū)?code>SKBitmap傳入,然后對SKCanvas進(jìn)行繪制背景DrawRoundRect 與文本DrawText ,使用屬性記錄XY的值方便在動(dòng)畫的時(shí)候讓彈幕動(dòng)起來。
  • BarrageRender的時(shí)候進(jìn)行繪制彈幕圖片DrawImage(SKBitmap,x,y) 。
  • 彈幕每次移動(dòng)多少值 等于SKCanvas的寬除以彈幕的。
  • 當(dāng)彈幕移動(dòng)Move()時(shí)如超過-Width則通過out返回GUID 就移除彈幕對象。

實(shí)現(xiàn)代碼

1) 準(zhǔn)備 MsgInfo 彈幕消息類如下:

using?System;
using?SkiaSharp;

namespace?SkiaSharpBarrage
{
????///?<summary>
????///?????msg?info
????///?</summary>
????public?class?MsgInfo
????{
????????private?string?_msg;

????????public?string?GUID;

????????public?MsgInfo(string?msg,?SKTypeface?_font,?float?windowsWidth)
????????{
????????????_msg?=?msg;
????????????var?_random?=?new?Random();
????????????var?skColor?=?new?SKColor((byte)?_random.Next(1,?255),
????????????????(byte)?_random.Next(1,?255),?(byte)?_random.Next(1,?233));
????????????using?var?paint?=?new?SKPaint
????????????{
????????????????Color?=?skColor,
????????????????Style?=?SKPaintStyle.Fill,
????????????????IsAntialias?=?true,
????????????????StrokeWidth?=?2
????????????};
????????????paint.Shader?=?SKShader.CreateLinearGradient(
????????????????new?SKPoint(0,?0),
????????????????new?SKPoint(1,?1),
????????????????new[]?{SKColors.Transparent,?skColor},
????????????????new?float[]?{0,?1},
????????????????SKShaderTileMode.Repeat);

????????????using?var?paintText?=?new?SKPaint
????????????{
????????????????Color?=?SKColors.White,
????????????????IsAntialias?=?true,
????????????????Typeface?=?_font,
????????????????TextSize?=?24
????????????};
????????????var?textBounds?=?new?SKRect();
????????????paintText.MeasureText(msg,?ref?textBounds);
????????????var?width?=?textBounds.Width?+?100;
????????????SKImage?skImage;
????????????using?(var?bitmap?=?new?SKBitmap((int)?width,?40,?true))
????????????using?(var?canvas?=?new?SKCanvas(bitmap))
????????????{
????????????????canvas.DrawRoundRect(0,?0,?width,?40,?20,?20,?paint);
????????????????canvas.DrawText(msg,?width?/?2?-?textBounds.Width?/?2,?bitmap.Height?/?2?+?textBounds.Height?/?2,
????????????????????paintText);
????????????????var?image?=?SKImage.FromBitmap(bitmap);
????????????????skImage?=?image;
????????????}

????????????SKImage?=?skImage;
????????????Width?=?width;
????????????X?=?windowsWidth?+?Width;
????????????CanvasWidth?=?windowsWidth;
????????????CostTime?=?TimeSpan.FromMilliseconds(Width);
????????????GUID?=?Guid.NewGuid().ToString("N");
????????}

????????public?float?X?{?get;?set;?}
????????public?float?Y?{?get;?set;?}
????????public?float?Width?{?get;?set;?}
????????public?float?CanvasWidth?{?get;?set;?}
????????public?SKImage?SKImage?{?get;?set;?}
????????public?float?MoveNum?=>?CanvasWidth?/?(float)?CostTime.TotalMilliseconds;
????????public?TimeSpan?CostTime?{?get;?set;?}

????????///?<summary>
????????///?????定時(shí)調(diào)用,移動(dòng)指定距離
????????///?</summary>
????????public?void?Move(out?string?guid)
????????{
????????????guid?=?string.Empty;
????????????X?=?X?-?MoveNum;
????????????if?(X?<=?-Width)
????????????????guid?=?GUID;
????????}
????}
}

2) 新建 Barrage.cs 類如下:

using?System.Collections.Generic;
using?System.Linq;
using?SkiaSharp;

namespace?SkiaSharpBarrage
{
????public?class?Barrage
????{
????????private?readonly?SKTypeface?_font;
????????private?readonly?List<MsgInfo>?_MsgInfo;
????????private?int?_num,?_index;
????????private?double?_right,?_top;
????????private?float?_width;
????????private?readonly?float?_height;

????????public?Barrage(SKTypeface?font,?float?width,?float?height,?List<string>?strList)
????????{
????????????_width?=?width;
????????????_height?=?height;
????????????_font?=?font;
????????????_num?=?(int)?height?/?40;
????????????_MsgInfo?=?new?List<MsgInfo>();
????????????foreach?(var?item?in?strList)?BuildMsgInfo(item);
????????}

????????private?void?BuildMsgInfo(string?text)
????????{
????????????_index++;
????????????if?(_right?!=?0)
????????????????_width?=?(float)?_right;
????????????var?model?=?new?MsgInfo(text,?_font,?_width);
????????????_right?=?_right?==?0???_height?+?model.Width?:?_right;
????????????var?y?=?_height?-?40;
????????????_top?=?_top?+?40?>=?y???40?:?_top;
????????????model.Y?=?(float)?_top;
????????????_MsgInfo.Add(model);
????????????_top?+=?60;
????????}

????????public?void?AddBarrage(string?text)
????????{
????????????BuildMsgInfo(text);
????????}

????????public?void?Render(SKCanvas?canvas,?SKTypeface?font,?int?width,?int?height,?List<string>?strList)
????????{
????????????for?(var?i?=?0;?i?<?_MsgInfo.Count;?i++)
????????????{
????????????????var?info?=?_MsgInfo[i];
????????????????var?guid?=?string.Empty;
????????????????info.Move(out?guid);
????????????????if?(!string.IsNullOrEmpty(guid))
????????????????{
????????????????????var?model?=?_MsgInfo.FirstOrDefault(x?=>?x.GUID?==?guid);
????????????????????_MsgInfo.Remove(model);
????????????????}

????????????????canvas.DrawImage(info.SKImage,?info.X,?info.Y);
????????????}
????????}
????}
}

3) MainWindow.xaml.cs 如下:

<wpfdev:Window?x:Class="SkiaSharpBarrage.MainWindow"
???????????????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
???????????????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
???????????????xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
???????????????xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
???????????????xmlns:wpfdev="https://github.com/WPFDevelopersOrg/WPFDevelopers"
???????????????xmlns:skia="clr-namespace:SkiaSharp.Views.WPF;assembly=SkiaSharp.Views.WPF"
???????????????mc:Ignorable="d"?WindowStartupLocation="CenterScreen"
???????????????ResizeMode="CanMinimize"
???????????????Title="SkiaSharpBarrage?-?彈幕篇"?Height="450"?Width="800">
????<Grid?Margin="4">
????????<Grid.RowDefinitions>
????????????<RowDefinition?/>
????????????<RowDefinition?Height="Auto"?/>
????????</Grid.RowDefinitions>
????????<MediaElement?Stretch="Uniform"?Grid.RowSpan="2"
??????????????????????Name="myMediaElement"?/>
????????<skia:SKElement?x:Name="skElement"?/>
????????<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="請彈幕內(nèi)容"?/>
????????????<Button?Grid.Column="1"?Style="{StaticResource?PrimaryButton}"
????????????????????Content="發(fā)射彈幕"?Margin="4,0,0,0"
????????????????????Click="ButtonBase_OnClick"?/>
????????</Grid>
????</Grid>
</wpfdev:Window>

3) 邏輯 MainWindow.xaml.cs 如下:

using?System;
using?System.Collections.Generic;
using?System.IO;
using?System.Linq;
using?System.Threading;
using?System.Threading.Tasks;
using?System.Windows;
using?SkiaSharp;
using?SkiaSharp.Views.Desktop;

namespace?SkiaSharpBarrage
{
????///?<summary>
????///?????Interaction?logic?for?MainWindow.xaml
????///?</summary>
????public?partial?class?MainWindow
????{
????????private?readonly?Barrage?_barrage;
????????private?readonly?SKTypeface?_font;
????????private?readonly?List<string>?list?=?new?List<string>();

????????public?MainWindow()
????????{
????????????list.Add("2333");
????????????list.Add("測試彈幕公眾號:WPF開發(fā)者");
????????????list.Add("很難開心");
????????????list.Add("LOL~");
????????????list.Add("青春記憶");
????????????list.Add("bing");
????????????list.Add("Microsoft");
????????????InitializeComponent();
????????????var?index?=?SKFontManager.Default.FontFamilies.ToList().IndexOf("微軟雅黑");
????????????_font?=?SKFontManager.Default.GetFontStyles(index).CreateTypeface(0);
????????????_barrage?=?new?Barrage(_font,?(float)?Width,?(float)?Height?-?(float)?MyGrid.ActualHeight,?list);
????????????skElement.PaintSurface?+=?SkElement_PaintSurface;
????????????Loaded?+=?delegate
????????????{
????????????????myMediaElement.Source?=
????????????????????new?Uri(Path.Combine(AppDomain.CurrentDomain.BaseDirectory,?"Leagueoflegends.mp4"));
????????????};
????????????_?=?Task.Run(()?=>
????????????{
????????????????try
????????????????{
????????????????????while?(true)
????????????????????{
????????????????????????Dispatcher.Invoke(()?=>?{?skElement.InvalidateVisual();?});
????????????????????????_?=?SpinWait.SpinUntil(()?=>?false,?1000?/?60);?//每秒60幀
????????????????????}
????????????????}
????????????????catch?(Exception?e)
????????????????{
????????????????}
????????????});
????????}


????????private?void?SkElement_PaintSurface(object??sender,?SKPaintSurfaceEventArgs?e)
????????{
????????????var?canvas?=?e.Surface.Canvas;
????????????canvas.Clear();
????????????_barrage.Render(canvas,?_font,?e.Info.Width,?e.Info.Height,?list);
????????}

????????private?void?ButtonBase_OnClick(object?sender,?RoutedEventArgs?e)
????????{
????????????_barrage.AddBarrage(tbBarrage.Text);
????????}
????}
}

實(shí)現(xiàn)效果

到此這篇關(guān)于WPF+SkiaSharp實(shí)現(xiàn)自繪彈幕效果的文章就介紹到這了,更多相關(guān)WPF SkiaSharp彈幕內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#如何添加PPT背景

    C#如何添加PPT背景

    這篇文章主要為大家詳細(xì)介紹了C#如何添加PPT背景,添加純色背景、漸變色背景、圖片背景等,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-07-07
  • C#值類型和引用類型的深入理解

    C#值類型和引用類型的深入理解

    本篇文章主要是對C#中值類型和引用類型進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • C#生成隨機(jī)數(shù)功能示例

    C#生成隨機(jī)數(shù)功能示例

    這篇文章主要介紹了C#生成隨機(jī)數(shù)功能,涉及C#數(shù)學(xué)運(yùn)算與字符串操作相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2017-01-01
  • DevExpress實(shí)現(xiàn)TreeList向上遞歸獲取符合條件的父節(jié)點(diǎn)

    DevExpress實(shí)現(xiàn)TreeList向上遞歸獲取符合條件的父節(jié)點(diǎn)

    這篇文章主要介紹了DevExpress實(shí)現(xiàn)TreeList向上遞歸獲取符合條件的父節(jié)點(diǎn),需要的朋友可以參考下
    2014-08-08
  • C# 元組和值元組的具體使用

    C# 元組和值元組的具體使用

    這篇文章主要介紹了C# 元組和值元組的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • C#使用集合實(shí)現(xiàn)二叉查找樹

    C#使用集合實(shí)現(xiàn)二叉查找樹

    這篇文章介紹了C#使用集合實(shí)現(xiàn)二叉查找樹的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • C#生成圖形驗(yàn)證碼的實(shí)現(xiàn)方式

    C#生成圖形驗(yàn)證碼的實(shí)現(xiàn)方式

    我們當(dāng)用戶登錄系統(tǒng)時(shí)經(jīng)常會(huì)用到圖形驗(yàn)證碼技術(shù),要求用戶識別圖片中的內(nèi)容,并正確輸入,方可嘗試登錄,因此,圖形驗(yàn)證碼是一個(gè)網(wǎng)絡(luò)安全技術(shù)手段,圖形驗(yàn)證碼的呈現(xiàn)形式有很多種,這里我們將介紹最基本的生成方式,感興趣的朋友可以參考下
    2024-04-04
  • 深入淺析C#?11?對?ref?和?struct?的改進(jìn)

    深入淺析C#?11?對?ref?和?struct?的改進(jìn)

    這篇文章主要介紹了C#?11?對?ref?和?struct?的改進(jìn),有了這些基礎(chǔ)設(shè)施,開發(fā)者們將能輕松使用安全的方式來編寫沒有任何堆內(nèi)存開銷的高性能代碼,需要的朋友可以參考下
    2022-04-04
  • WinForm限制窗體不能移到屏幕外的方法

    WinForm限制窗體不能移到屏幕外的方法

    這篇文章主要介紹了WinForm限制窗體不能移到屏幕外的方法,實(shí)例分析了C#中WinForm窗體操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-08-08
  • C#處理文本文件TXT實(shí)例詳解

    C#處理文本文件TXT實(shí)例詳解

    這篇文章主要介紹了C#處理文本文件TXT的方法,以實(shí)例形式詳細(xì)分析了txt文本文件的讀取、修改及打印等功能的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-02-02

最新評論

宣城市| 普兰店市| 克什克腾旗| 大方县| 东乡| 洪湖市| 阿拉善左旗| 衢州市| 城市| 宜春市| 石阡县| 清苑县| 兴文县| 红河县| 黑龙江省| 桓仁| 上林县| 城固县| 凤山县| 都江堰市| 车致| 涟源市| 将乐县| 都安| 布尔津县| 丰都县| 全椒县| 囊谦县| 乌拉特后旗| 盈江县| 罗定市| 浏阳市| 辽宁省| 泌阳县| 贡山| 于都县| 北碚区| 长兴县| 留坝县| 陇川县| 涿州市|