基于WPF实现弹幕效果的示例代码

WPF 实现弹幕效果

框架使用大于等于.NET40

Visual Studio 2022;

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

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

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

  • 弹幕消息使用Border做弹幕背景。
  • 内容使用TextBlock做消息文本展示。
  • 当动画执行完成默认移除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="发射弹幕" 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弹幕的资料请关注我们其它相关文章!

(0)

相关推荐

  • WPF实现文本描边+外发光效果的示例代码

    解决思路: (1)描边效果可以将文本字符串用GDI+生成Bitmap,然后转成BitmapImage,再用WPF的Image控件显示. (2)外发光效果用WPF自带的Effect实现 代码: using System; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.IO; namespace TextHighLighthDemo { public clas

  • WPF实现3D粒子波浪效果

    本文实例为大家分享了WPF实现3D粒子波浪效果的具体代码,供大家参考,具体内容如下 实现效果如下: 步骤: 1.3D粒子类Particle.cs public class Particle { public Point3D Position;//位置 public double Size;//尺寸 public int XIndex;//X位置标识 public int YIndex;//Y位置标识 } 2.粒子系统ParticleSystem类 public class ParticleSys

  • WPF实现倒计时转场动画效果

    代码如下 一.创建 CountdownTimer.xaml 继承ContentControl代码如下. using System; using System.Linq; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windo

  • WPF实现动画效果

    学习平台 微软开发者博客:https://devblogs.microsoft.com/?WT.mc_id=DT-MVP-5003986微软文档与学习:https://docs.microsoft.com/zh-cn/?WT.mc_id=DT-MVP-5003986微软开发者平台:https://developer.microsoft.com/en-us/?WT.mc_id=DT-MVP-5003986 1.介绍 在之前做winform中, 也做过一些动画效果, 但是整个动画都需要我们自己去编写

  • 基于WPF实现控件轮廓跑马灯动画效果

    代码如下 一.创建EdgeLight.xaml代码如下. <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     xmlns:controls="c

  • WPF实现抽屉菜单效果的示例代码

    WPF 实现抽屉菜单 框架使用大于等于.NET40: Visual Studio 2022; 项目使用 MIT 开源许可协议: 更多效果可以通过GitHub[1]|码云[2]下载代码; 由于在WPF中没有现成的类似UWP的抽屉菜单,所以我们自己实现一个. 1) DrawerMenu.cs 代码如下. using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System

  • 基于WPF实现弹幕效果的示例代码

    WPF 实现弹幕效果 框架使用大于等于.NET40: Visual Studio 2022; 项目使用 MIT 开源许可协议: 此篇代码目的只是为了分享思路 实现基础弹幕一定是要使用Canvas比较简单,只需实现Left动画从右到左. 弹幕消息使用Border做弹幕背景. 内容使用TextBlock做消息文本展示. 当动画执行完成默认移除Canvas中的弹幕控件. 使用这种方式去加载弹幕GPU会占较高. 1) 准备BarrageExample.xaml如下: <UserControl x:Cla

  • 基于原生JS实现分页效果的示例代码

    这个只是一个分页的demo,主要是思路整理(很久之前项目用的东西) 分页实现的效果 主要是 左侧上一页 右侧是下一页 中间显示主要是超过5个显示 省略号 然后是可配置选项 实现之后的效果 首先需要初始化该对象的一些基本属性,显示总页码数,中间显示的页面数, 添加一个回调函数,在页面变化激活回调函数并返回当前页面和一些需要的其他参数 init为对象初始化的方法(里面的参数都是可以写成活的,我这里偷懒了所以写成死的了) 这个里的 z_page 可以接是接口返回的总页数 function Page(o

  • WPF实现窗体亚克力效果的示例代码

    WPF 窗体设置亚克力效果 框架使用大于等于.NET40. Visual Studio 2022. 项目使用 MIT 开源许可协议. WindowAcrylicBlur 设置亚克力颜色. Opacity 设置透明度. 实现代码 1) 准备WindowAcrylicBlur.cs如下: using System; using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; usi

  • 使用mint-ui实现省市区三级联动效果的示例代码

    引用插件:饿了么的mint-ui组件中的picker功能,具体API可参照官网说明:http://mint-ui.github.io/docs/#/zh-cn2/picker 背景:项目需要做一个省份-城市-地区的选择级联效果,我从gayhub上找了一下,决定使用mint-ui的组件,因为各个功能都很全而且设计跟我们的项目风格类似. 具体实现: 通过阅读官网的实例,大概就能知道这个组件的用法: 在vue中写入组件:<mt-picker :slots="slots" @change

  • 基于Java实现修改图片分辨率示例代码

    目录 前言 环境依赖 代码 验证一下 前言 本文提供可以修改图片分辨率的java工具类,实用主义的狂欢. 环境依赖 添加必要的一些maven依赖. <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.7.15</version> </dependency> <dependency&

  • 基于Python实现超级玛丽游戏的示例代码

    目录 效果演示 基础源码 1.基础设置(tools部分) 2.设置背景音乐以及场景中的文字(setup部分) 3.设置游戏规则(load_screen) 4.设置游戏内菜单等(main_menu) 5.main() 6.调用以上函数实现 效果演示 基础源码 1.基础设置(tools部分) 这个部分设置马里奥以及游戏中蘑菇等怪的的移动设置. import os import pygame as pg keybinding = { 'action':pg.K_s, 'jump':pg.K_a, 'l

  • 【JS+CSS3】实现带预览图幻灯片效果的示例代码

    一.前期准备 1.1 案例分析 适用场景:单例布局 1.2 方法论 V视图 HTML+CSS+调试 C js实现控制流程 D数据 优化扩展 二.代码 结构 <div class="slider"><!-- 特效区 --> <div class="main"><!-- 主视图区 --> <div class="main_i"> <div class="caption&quo

  • Vue 实现展开折叠效果的示例代码

    本文介绍了Vue 实现展开折叠效果的示例代码,分享给大家,具体如下: 效果如见: 1.html代码 <!DOCTYPE html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>js文本段落展开和收拢效果</title> <script type="text/javasc

随机推荐