vue封装一个弹幕组件详解
作者:JYeontu??????? 发布时间:2024-05-09 15:28:38
标签:vue,封装,弹幕,组件
前言
现在很多地方都有使用到弹幕,最近在捣鼓自己的个人博客网站,也想着在里面加入一个弹幕模块,所以在这里封装了一个可复用的弹幕组件,目前已经实现了基本的功能,可能还会有存在缺陷,后续会继续优化。这里给大家介绍分享一下实现的过程。
功能实现
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


猜你喜欢
- 压缩复制删除文件基于python语言怎么操作呢,压缩文件有四种格式:zip、rar、tar、tar.gz,在压缩过程中也容易出现很多问题,今
- python等待10秒执行下一命令的方法:首先导入时间(time)模块;然后在需要等待执行的命令前调用sleep()方法,并在方法的括号里将
- 1.下载PyQt官方网站:http://www.riverbankcomputing.com/software/pyqt/download5
- 本文实例为大家分享了javascript实现tab切换特效代码,供大家参考,具体内容如下效果图:实现代码:<!DOCTYPE html
- 前言利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰
- 一、注意你的Python版本Python官方网站为http://www.python.org/,当前最新稳定版本为3.6.5,在3.0版本时
- 前几天和一个小伙伴交流了一下nodejs中epoll和处理请求的一些知识,今天简单来聊一下nodejs处理请求的逻辑。我们从listen函数
- 一、架构介绍Scrapy一个开源和协作的框架,其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的,使用它可以以快速、简单、可扩展的方
- 拉取网易蜂巢的mysql-server:5.6docker pull hub.c.163.com/nce2/mysql:5.6创建mysql
- 0.前置知识Go中的struct。mysql、Gin框架。Web基础。1.架构使用mysql作为数据库,Gin作为Web框架。2.功能模块1
- 众所周知,binlog日志对于mysql数据库来说是十分重要的。在数据丢失的紧急情况下,我们往往会想到用binlog日志功能进行数据恢复(定
- 本文实例讲述了Python操作MySQL数据库。分享给大家供大家参考,具体如下:1、安装通过Python连接MySQL数据库有很多库,这里使
- 写在前面Omi框架可以通过在组件上声明 data-* 把属性传递给子节点。Omi从设计之初,就是往标准的DOM标签的标准传递方式靠齐。比如:
- 软件版本及平台:MySQL-5.7.17-winx64,win7家庭版一、下载安装包https://cdn.mysql.com//Downl
- javascript cookie的基本操作(添加和删除)1.添加一个cookie:response.addCookie(Cookie c)
- 万物皆对象这篇博客的内容主要是针对Python中万物皆对象的理解,对Python的类型、对象体系做一个整体的梳理。在Python中,一切皆为
- 目前在网络上多是单个条形图堆叠,没看到一组的条形图堆叠。代码如下:import numpy as npimport pandas as pd
- 一个很普通的网页中显示LOGO图像,按照以往的页面制作经验,基本是在页面中插入图像即可(<img src="logo.gif
- @keyup.enter失效问题情况一(我遇到的情况)@keyup.enter外部存在form表单,并且form表单里只有一个input原因
- 暂时性死区只要块级作用域存在let命令,它所声明的变量就“绑定”这个区域,不再受外部的影响。这么说可能有些抽象,举个例子:var