vue封装一个弹幕组件详解
作者:JYeontu??????? 时间:2024-05-09 15:28:38
前言
现在很多地方都有使用到弹幕,最近在捣鼓自己的个人博客网站,也想着在里面加入一个弹幕模块,所以在这里封装了一个可复用的弹幕组件,目前已经实现了基本的功能,可能还会有存在缺陷,后续会继续优化。这里给大家介绍分享一下实现的过程。
功能实现
1、获取随机颜色
颜色编码是由6位16进制数组成,我们可以随机生成6位16进制数。
随机数生成
随机生成[min,max]区间的数字
getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
},
随机颜色编码生成
随机生成6位16进制数。
getColors() {
const arr = "0123456789abcdef";
let color = "#";
let n = 6;
while (n--) color += arr[this.getRandom(0, 15)];
return color;
},
2、随机生成弹幕出现的高度坐标
这里我划分了三块区域,分别为top、center和bottom,具体划分如下图:
代码如下:
getPosition(position = "") {
let content = this.content;
let height = content.offsetHeight * 0.9;
this.width =
content.offsetWidth +
(5 * content.offsetWidth) / this.time +
"px";
switch (position) {
case "top":
return this.getRandom(0, height / 3);
case "center":
return this.getRandom(height / 3, (2 * height) / 3);
case "bottom":
return this.getRandom((2 * height) / 3, height);
default:
return this.getRandom(0, height);
}
},
3、格式化弹幕对象
定义的弹幕对象结构如下:
{
text: "111",
color: "red",
position: "top" //top,center,bottom
}
我们需要进行以下处理:
颜色
这里的color允许为空,为空时会自动生成随机颜色
定位
弹幕对象传入的position为top,center,bottom或者random,我们需要将这些文字转化为具体的y坐标值(即出现的高度) 具体代码如下:
formatData(item = {}) {
item.position = this.getPosition(item.position);
if (!item.color) item.color = this.getColors();
return item;
},
4、创建弹幕对象
格式化了弹幕对象的数据之后,我们需要利用这些数据转换成真正可以在页面上展示出来的dom对象,具体实现如下:
滚动动画定义
我们弹幕可以从右边出现滚动到左边,也可以从左边出现滚动到右边,这里分别使用来个动画来实现,具体代码如下:
<style vars="{width}" lang="scss">
@keyframes moveLeft {
from {
left: 0px;
}
to {
left: var(--width);
}
}
@keyframes moveRight {
from {
right: 0px;
}
to {
right: var(--width);
}
}
</style>
创建弹幕dom对象实例
每一个弹幕我们使用一个span来生成,具体代码如下:
createBarrage(item) {
const content = this.content;
const span = document.createElement("span");
span.style.color = item.color;
span.innerHTML = item.text;
if (this.full) span.style.position = "fixed";
span.style.top = item.position + "px";
if (this.startFrom == "left") {
span.style.left = "0px";
span.style.animation = `moveLeft ${this.time}s linear`;
} else {
span.style.right = "0px";
span.style.animation = `moveRight ${this.time}s linear`;
}
if (this.mask) {
span.style.padding = "0.2em 0.5em";
span.style.backgroundColor = "#bbb2b2";
}
content.appendChild(span);
this.barrageNums++;
this.destroyBarrage(span);
},
弹幕销毁
弹幕滚动到屏幕外的时候我们需要将其销毁
destroyBarrage(dom = null) {
if (!dom) return;
let content = this.content;
if (content.offsetLeft + content.offsetWidth < dom.offsetLeft) {
content.removeChild(dom);
this.barrageNums--;
} else {
setTimeout(() => {
this.destroyBarrage(dom);
}, 1000);
}
},
弹幕循环
在弹幕全部生成并且最后生成的弹幕已经走过1/3时间的时候生成下一波的弹幕
if (
index == this.showBarrageDate.length - 1 &&
this.repetition
) {
setTimeout(() => {
this.generateBarrage();
}, timeFlag * 1000 + this.time / 3);
}
5、实时弹幕发送
我们可以这里输入弹幕信息,然后发送弹幕,具体实现如下:
html
<div class="j-barrage-send-box">
<span
class="j-barrage-tools-box"
@click.stop="() => {}"
v-if="showToolsBox"
>
<div class="j-barrage-send-box-item">
<span>颜色:</span
><input v-model="sendObj.color" type="color" />
</div>
<div class="j-barrage-send-box-item">
<span>位置:</span>
<template v-for="(pos, index) in position">
<span :key="'pos-span-' + index">{{ pos }}</span>
<input
:key="'pos-input-' + index"
name="position"
type="radio"
:value="pos"
v-model="sendObj.position"
/>
</template>
</div>
</span>
<span class="j-barrage-send-box-item input-box" v-if="showBtn">
<span
class="j-barrage-send-box-item-tools"
@click.stop="showToolsBox = !showToolsBox"
>A</span
>
<input
class="j-barrage-send-box-item-input"
v-model="sendObj.text"
@focus="showToolsBox = false"
@keydown.enter="sendBarrage"
/>
<span class="j-barrage-send-box-item-btn" @click="sendBarrage"
>发送</span
>
</span>
</div>
JavaScript
sendBarrage() {
const obj = this.formatData({ ...this.sendObj });
this.showBarrageDate.push(obj);
this.createBarrage(obj);
},
源码地址
代码已经开源,并且写了相关的文档对其进行了简单介绍,具体如下:
组件文档:
jvuewheel
来源:https://juejin.cn/post/7087599645387391012
标签:vue,封装,弹幕,组件
0
投稿
猜你喜欢
python数据结构之面向对象
2021-04-09 08:02:06
快速创建python 虚拟环境
2023-10-04 08:58:31
Oracle锁处理、解锁方法
2024-01-20 20:15:00
通过yum方式安装mySql数据库的全过程
2024-01-13 11:46:43
用Python写个新年贺卡生成器
2023-08-26 00:56:45
20个Javascript手风琴折叠菜单
2009-10-12 12:09:00
golang之JWT实现的示例代码
2024-01-30 03:35:30
Vue项目的网络请求代理到封装步骤详解
2024-04-30 10:23:55
python中添加模块导入路径的方法
2021-12-17 14:35:30
Python安装jieba库详细教程
2023-05-09 12:18:19
python解析命令行参数的三种方法详解
2023-12-26 04:05:38
MySQL查询优化
2009-03-09 14:41:00
DreamWeaver批处理提高篇
2007-12-03 11:34:00
go语言beego框架jwt身份认证实现示例
2024-04-25 15:15:21
解决pytorch读取自制数据集出现过的问题
2023-04-23 15:15:43
HTML转义字符&npsp;表示non-breaking space \\xa0
2022-07-11 05:55:35
Pytorch中Tensor与各种图像格式的相互转化详解
2023-05-23 01:46:54
MySQL主从复制的原理及配置方法(比较详细)
2024-01-28 18:21:02
Javascript中判断一个值是否为undefined的方法详解
2024-04-19 09:54:13
laravel学习教程之关联模型
2023-06-11 19:46:55