Demo:https://download.csdn.net/download/wu110112/21628782?spm=1001.2014.3001.5501

动效礼物可支持各位为:gif和webp格式

20210830-155059

20210827-162020

 BulletCrtan.h

#pragma once
#include <QWidget>
#include <QVector>
#include <QString>
#include <QStringList>
#include <QPoint>
#include <QFont>
#include <QTimer>
#include <QMovie>
#include <QLabel>
/************************************************************************
*作者:wujianhua
*时间:2021/08/26
*类介绍:弹幕类【支持文案飘屏、礼物动效展示】
************************************************************************/
namespace Bullet_Curtain{//弹幕信息结构typedef struct tag_Bullet_Curtain_Info {QString content;               //内容数据QColor rgba;                      //文本显示颜色QPoint pt;                          //坐标int step;                               //弹幕步进tag_Bullet_Curtain_Info(){rgba = QColor(255, 255, 255, 230);}}BULLET_CURTAIN_INFO, *LPBULLET_CURTAIN_INFO;
};class BulletCurtain : public QWidget
{Q_OBJECTpublic:BulletCurtain(QWidget *parent);~BulletCurtain();/*************************************************************************作者:wujianhua*时间:2021/08/26*函数:发送弹幕*参数:*       info:弹幕信息*返回值:*       无************************************************************************/void sendBulletCurtain(Bullet_Curtain::BULLET_CURTAIN_INFO info);/*************************************************************************作者:wujianhua*时间:2021/08/27*函数:发送动效礼物*参数:*      path:礼物路径*返回值:*   无************************************************************************/void sendGift(const QString &path);/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:获取弹幕最大显示行数*参数:*        无*返回值:*      返回弹幕支持最大的弹幕行数************************************************************************/int getBulletCurtainMaxRow();/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:显示弹幕行数*参数:*      maxRow:弹幕最大行数*返回值:*       无************************************************************************/void showMaxCurtainMaxRow(unsigned int maxRow=1);/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:显示弹幕*参数:*        无*返回值:*      无************************************************************************/void showBulletCurtain();/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:隐藏弹幕*参数:*        无*返回值:*      无************************************************************************/void hideBulletCurtain();/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:显示礼物*参数:*        无*返回值:*      无************************************************************************/void showGift();/*************************************************************************作者:wujianhua*时间:2021/08/30*函数:隐藏礼物*参数:*     无*返回值:*      无************************************************************************/void hideGift();protected:virtual void paintEvent(QPaintEvent * event);private:/*************************************************************************作者:wujianhua*时间:2021/08/26*函数:回执弹幕文本数据*参数:*      drawInfo:弹幕绘制信息*返回值:*     绘制成功返回true,绘制失败返回false【失败也可以理解当前弹幕内容已经轮播一次结束不在绘制了】************************************************************************/bool drawText(Bullet_Curtain::LPBULLET_CURTAIN_INFO drawInfo);/*************************************************************************作者:wujianhua*时间:2021/08/27*函数:播放礼物动效*参数:*     path:礼物物理路径*返回值:*     无************************************************************************/void playerGift(const QString &path);
private:QVector<Bullet_Curtain::LPBULLET_CURTAIN_INFO> m_vecInfoQueue;    //弹幕信息队列QTimer *m_timerReflush = nullptr;   //定时刷新QFont * m_font = nullptr; //弹幕字体unsigned int m_currentRow = 0;    //当前弹幕行号unsigned int m_maxRow = 1;      //最大显示弹幕行数//播放礼物动效QTimer *m_timeGift = nullptr;QStringList m_giftList;QLabel *m_webpLabel = nullptr;QMovie *m_webpMovie = nullptr;bool m_curGiftFinished = true;    //当前礼物播放完成bool m_showBulletCurtain = true;  //弹幕显示标志bool m_showGift = true;     //礼物显示标志
};

BulletCrtan.cpp

#include "BulletCurtain.h"
#include <QPainter>
#include <QTime>
#include <QDebug>
#include <QHBoxLayout>using namespace Bullet_Curtain;
BulletCurtain::BulletCurtain(QWidget *parent): QWidget(parent)
{setObjectName("BulletCrtan");//设置背景透明setAttribute(Qt::WA_TranslucentBackground);//创建播放礼物动效对象QHBoxLayout *layout = new QHBoxLayout(this);layout->setSpacing(0);layout->setContentsMargins(0, 0, 0, 0);m_webpLabel = new QLabel();m_webpLabel->setAlignment(Qt::AlignCenter);m_webpLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);m_webpLabel->setBackgroundRole(QPalette::Shadow);//m_webpLabel->setAutoFillBackground(true);layout->addWidget(m_webpLabel);setLayout(layout);m_webpMovie = new QMovie(this);m_webpMovie->setCacheMode(QMovie::CacheAll);connect(m_webpMovie, &QMovie::frameChanged, this, [=](int frameNumber) {int count = m_webpMovie->frameCount()-1;if(frameNumber == count ){m_webpMovie->stop();m_webpLabel->clear();m_curGiftFinished = true;}});//定时刷新弹幕m_timerReflush = new QTimer(this);connect(m_timerReflush, &QTimer::timeout, this, [=]() {update();});m_timerReflush->setInterval(50);m_timerReflush->start();//随机生成种子 弹幕步进使用qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));//设置字体m_font = new QFont("微软雅黑", 10, 10);m_font->setBold(true);m_font->setPointSize(12);connect(m_webpMovie, &QMovie::finished, this, [=]() {m_webpMovie->stop();m_webpLabel->clear();m_curGiftFinished = true;});//定时检测礼物m_timeGift = new QTimer(this);connect(m_timeGift, &QTimer::timeout, this, [=]() {while (m_giftList.size() && m_curGiftFinished && m_showGift) {playerGift(m_giftList.at(0));m_giftList.removeAt(0);}});m_timeGift->setInterval(100);m_timeGift->start();
}BulletCurtain::~BulletCurtain()
{m_timeGift->stop();delete m_timeGift, m_timeGift = nullptr;m_timerReflush->stop();delete m_timerReflush, m_timerReflush = nullptr;delete m_font, m_font = nullptr;m_webpMovie->stop();delete m_webpLabel, m_webpLabel = nullptr;delete m_webpMovie, m_webpMovie = nullptr;QVector<LPBULLET_CURTAIN_INFO>::iterator it = m_vecInfoQueue.begin();while (it != m_vecInfoQueue.end()){LPBULLET_CURTAIN_INFO &pInfo = *it;if (pInfo) {delete pInfo, pInfo = nullptr;}it++;}m_vecInfoQueue.clear();
}void BulletCurtain::sendBulletCurtain(BULLET_CURTAIN_INFO info)
{if (!m_showBulletCurtain)return;LPBULLET_CURTAIN_INFO drawInfo = new BULLET_CURTAIN_INFO;drawInfo->content = info.content;QFontMetrics metrics(*m_font);    //获取弹幕字体可以得到内容占用的x坐标长度metrics.width(info.content);int conentHeight = metrics.height();int yPix = m_currentRow * conentHeight+20;//10 + 30;drawInfo->pt = QPoint(size().width(), yPix);drawInfo->rgba = info.rgba;drawInfo->step = qrand() % 5+4;   //随机弹幕步进m_vecInfoQueue.push_back(drawInfo);m_currentRow++;int maxRow = getBulletCurtainMaxRow();if(m_maxRow >0 && m_maxRow < maxRow){maxRow = m_maxRow;}if(m_currentRow >= maxRow)m_currentRow = 0;
}void BulletCurtain::sendGift(const QString &path)
{m_giftList.push_back(path);
}int BulletCurtain::getBulletCurtainMaxRow()
{QFontMetrics metrics(*m_font); metrics.width("TEST ROW");int conentHeight = metrics.height();QSize size = this->size();int maxRow = qAbs(size.height() / conentHeight);return maxRow;
}void BulletCurtain::showMaxCurtainMaxRow(unsigned int maxRow/*=1*/)
{m_maxRow = maxRow;
}void BulletCurtain::showBulletCurtain()
{m_showBulletCurtain = true;
}void BulletCurtain::hideBulletCurtain()
{m_showBulletCurtain = false;m_currentRow = 0;QVector<LPBULLET_CURTAIN_INFO>::iterator it = m_vecInfoQueue.begin();while (it != m_vecInfoQueue.end()){LPBULLET_CURTAIN_INFO &pInfo = *it;if (pInfo) {delete pInfo, pInfo = nullptr;}it++;}m_vecInfoQueue.clear();}void BulletCurtain::showGift()
{m_showGift = true;
}void BulletCurtain::hideGift()
{m_showGift = false;m_giftList.clear();m_webpMovie->stop();m_webpLabel->clear();m_curGiftFinished = true;
}
void BulletCurtain::paintEvent(QPaintEvent * event)
{//弹幕滚屏qDebug() << "bulletcurtain queue size:" << m_vecInfoQueue.size();QVector<LPBULLET_CURTAIN_INFO>::iterator it = m_vecInfoQueue.begin();while (it != m_vecInfoQueue.end()){LPBULLET_CURTAIN_INFO &pInfo = *it;if (!pInfo) {it = m_vecInfoQueue.erase(it);}else {if (!drawText(pInfo)) {delete pInfo, pInfo = nullptr;it = m_vecInfoQueue.erase(it);}else {it++;}}}
}bool BulletCurtain::drawText(LPBULLET_CURTAIN_INFO drawInfo)
{if(drawInfo && m_showBulletCurtain){QPainter painter(this);painter.save();QPen pen(drawInfo->rgba);     //自定义画笔的样式,让文字周围有边框QFontMetrics metrics(*m_font);    //获取弹幕字体可以得到内容占用的x坐标长度int conentPix = metrics.width(drawInfo->content);//计算X坐标偏移int x = drawInfo->pt.x() - drawInfo->step;if(x+conentPix <0){x = size().width();return false;}painter.setRenderHint(QPainter::Antialiasing);drawInfo->pt.setX(x);painter.setPen(pen);painter.setFont(*m_font);painter.drawText(drawInfo->pt.x(), drawInfo->pt.y(), drawInfo->content);painter.restore();return true;}return false;
}void BulletCurtain::playerGift(const QString &path)
{m_webpMovie->stop();m_webpLabel->clear();m_webpLabel->setMovie(m_webpMovie);m_webpMovie->setFileName(path);m_webpMovie->start();if(m_webpMovie->isValid()){m_curGiftFinished = false;}
}

QT实现弹幕和webp格式礼物动效相关推荐

  1. 记录一次礼物动效的设计与实现过程

    实现礼物动效可以使用ViewGroup的方式也可以使用自定义View的方式.本文使用的是自定义View方式,不会讨论关于ViewGroup的实现方式. 数据模型 数据源列表使用mList 数据源列表使 ...

  2. 直播间赠送礼物动效、选礼物列表、赠送数量,礼物连发排队处理,Vue项目

    1.可以选择送的是礼物列表的哪一个.可以选择送的数量x1x2x3 2.礼物做了排队展示的处理,可以解决礼物连续发送.监听到别人发送礼物接口数据回调的排队问题,不会冲刷掉礼物动效 下面是一个完整的送礼物 ...

  3. 动效给程序员用什么格式_UI动效敲砖篇

    UI其实并不仅仅是静态,还包括动效设计!!!作为一个程序员,每天除了撸各种干燥无味的代码,我觉得大家有必要了解一下这个润滑产品,期间的滋味只有试了的人才懂! 我们这一代人还是清楚移动设备的演化:大哥大 ...

  4. 动效给程序员用什么格式_动效,一种属于前端程序员的浪漫,无与伦比的体验...

    一.初见 动效顾名思义就是动画效果.网页中为什么需要动效呢?简单来说就是为了有趣. 如果把网页和用户的关系比做正在恋爱的情侣,很显然网页的 UI 是颜值,而动效在我看来则是情侣之间的小浪漫.可能和颜值 ...

  5. 如何让动效又快又好落地?我分析了这5种格式的优缺点

    动效设计,可以提升界面的趣味性和引导性,让用户浏览过程中不会太枯燥,获得更好的体验. 最近做的金山知了(后面改名为金山知识库)官网,头图元素加入了缓动效果,第一眼挺新颖的.金山协作新年许愿活动,许愿按 ...

  6. js svg语音波动动画_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  7. 怎么用class引入svg_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  8. 动效素材极速交付: 腾讯PAG动效组件技术揭秘

    编者按:音视频产品中的动效素材需求是源源不断的,例如贴纸花字,转场特效,照片和视频模板等,并且对它们的产量,上线速度,以及视觉效果都有比较高的要求.但在传统工作流中的交付成本却非常高,需要通过代码来手 ...

  9. 499张WEBP格式动漫图片

    499张WEBP格式动漫图片  Lan   2020-05-10 19:13   185 人阅读  0 条评论 用处多多,即可当网站背景,还可以配合WE当桌面壁纸 本资源转载于网络,如有问题请联系E- ...

最新文章

  1. Spark HistoryServer日志解析清理异常
  2. 机器学习基石13-Hazard of Overfitting
  3. 【小夕精选】多轮对话之对话管理(Dialog Management)
  4. Android开发笔记(三十一)SQLite游标及其数据结构
  5. python怎么读取excel-python 读取 Excel
  6. 公布中秋福利中奖名单
  7. fatal error: libmemcached/memcached.h: No such file or directory
  8. 电脑telnet工具如何开启
  9. 阻容感基础03:电阻器分类(1)-片式电阻器
  10. python把两张图片合成一张_怎么合成图片-利用Python将两张图片合成为一张图
  11. 带你走进springboot
  12. 源码下载地址及各类资源站点
  13. 方差分析结果如何看?指标怎么计算?
  14. 视频号怎么赚钱?视频号有什么功能?
  15. 探索 nunustudio 开发3D模型 第二弹:根据矢量图制作动画效果
  16. php js 对象追加元素,JS添加元素新节点
  17. 高品质回音消除 模块 : F-23
  18. The Armijo Goldstein line search scheme
  19. Azure-900【定义云模型】
  20. C#数字转化为货币金钱格式,元角分。

热门文章

  1. 数据资产盘点的流程和方法
  2. 快速排序详细分析--单向扫描和双向扫描
  3. IE、360、百度三者的比较
  4. Winfrom窗体应用程序图标的改变
  5. 国产FPGA研究框架
  6. Python数据处理工具——Pandas
  7. 阿里云混合云Apsara Stack
  8. 【汇正财经】上证50逆势收涨,大盘健康震固
  9. 跟领导汇报工作时,这句话建议你不要说
  10. c语言mac小游戏,Mac自带小游戏怎么玩以打发空闲时间