移动端 B 站弹幕功能实现​

移动端 B 站弹幕功能实现​

移动端 B 站弹幕功能实现 ​ 更新: 11/26/2025字数: 0 字 时长: 0 分钟

在现代网页中,弹幕(Barrage)是一种非常流行的用户互动方式,尤其在直播、短视频和互动课堂中广泛使用。下面讲解如何使用原生 HTML5 Canvas + JavaScript 实现一个高密度弹幕系统,支持图标背景、动画效果、暂停/隐藏功能。

效果展示 ​弹幕自动随机出现,颜色随机支持用户输入发送自定义弹幕支持暂停/恢复和隐藏/显示弹幕弹幕背景带圆角矩形,实现图标/文字区分弹幕密集且不遮挡底部输入框如图所示:

HTML 结构 ​HTML 部分主要包括三个区域:

Canvas 渲染区:用于绘制弹幕。控制按钮:暂停/恢复和隐藏/显示弹幕。输入区域:用于发送自定义弹幕。html

1234567891011canvas 是绘制弹幕的核心区域。

controls 包含两个按钮:

暂停/恢复:暂停弹幕移动,但仍显示已存在弹幕。隐藏/显示:隐藏或显示弹幕,但不影响位置更新。input-area 用于输入用户自定义弹幕。

样式设计 ​CSS 样式确保弹幕在全屏显示,且输入区域固定在底部,不被弹幕遮挡。

cssbody {

margin: 0;

background: #000;

overflow: hidden;

height: 100vh;

font-family: sans-serif;

}

canvas {

position: absolute;

top: 0;

left: 0;

}

.input-area {

position: fixed;

bottom: 10px;

left: 50%;

transform: translateX(-50%);

width: 90%;

display: flex;

gap: 8px;

z-index: 10;

}

.controls {

position: fixed;

top: 12px;

right: 12px;

display: flex;

flex-direction: column;

gap: 10px;

z-index: 20;

}12345678910111213141516171819202122232425262728293031323334canvas 使用绝对定位,覆盖整个页面。input-area 使用 fixed 固定在底部,并保证弹幕不会遮挡输入框。controls 固定在右上角,并加入半透明和模糊效果,提高视觉层次。Canvas 与弹幕逻辑 ​1. 初始化 Canvas ​jsconst canvas = document.getElementById("barrageCanvas");

const ctx = canvas.getContext("2d");

function resizeCanvas() {

canvas.width = window.innerWidth;

canvas.height = window.innerHeight;

updateLineCount();

}

window.addEventListener("resize", resizeCanvas);

resizeCanvas();12345678910resizeCanvas 保证弹幕在屏幕大小变化时自适应。使用 updateLineCount 动态计算可用弹幕行数,避免弹幕覆盖输入框。2. 弹幕行数计算 ​jsconst inputHeight = 80;

const topMargin = 20;

const lineHeight = 28;

let lineCount;

function updateLineCount() {

lineCount = Math.floor((canvas.height - inputHeight - topMargin) / lineHeight);

}12345678lineHeight 决定每条弹幕在纵向的间距。lineCount 用于随机选择弹幕所在的行。3. 弹幕类 Barrage ​jsclass Barrage {

constructor(text, lineIndex) {

this.text = text;

this.color = `hsl(${Math.random() * 360},80%,60%)`;

this.fontSize = 18;

this.x = canvas.width;

this.lineIndex = lineIndex;

this.y = topMargin + lineHeight * (lineIndex + 1);

this.speed = 1.5 + Math.random() * 2.5;

this.padding = 8;

}

draw() {

ctx.font = `${this.fontSize}px sans-serif`;

const textWidth = ctx.measureText(this.text).width;

// 绘制半透明圆角矩形背景

ctx.fillStyle = "rgba(0,0,0,0.4)";

ctx.beginPath();

ctx.roundRect(this.x - this.padding / 2, this.y - this.fontSize, textWidth + this.padding, this.fontSize + 8, 8);

ctx.fill();

// 绘制文本

ctx.fillStyle = this.color;

ctx.fillText(this.text, this.x, this.y);

}

update() {

this.x -= this.speed;

}

}12345678910111213141516171819202122232425262728293031draw() 负责渲染文字和背景矩形,背景矩形带圆角,实现图标/文字区分。update() 负责弹幕移动。弹幕颜色随机,增加视觉丰富度。弹幕的 speed 随机,避免所有弹幕移动速度一致。4. 弹幕管理 ​jsconst barrages = [];

const preset = ["太精彩了🔥", "前排打卡", "哈哈哈哈哈", "好顶赞👍", "稳了!", "无敌!", "冲啊~", "哇塞好炫", "牛啊哥们"];

let isPaused = false;

let isHidden = false;1234barrages 存储当前页面所有弹幕。preset 是随机弹幕库。isPaused 和 isHidden 控制暂停与隐藏状态。5. 自动发射弹幕 ​jssetInterval(() => {

if (isPaused) return;

const count = Math.floor(Math.random() * 3) + 1;

for (let i = 0; i < count; i++) {

const text = preset[Math.floor(Math.random() * preset.length)];

const lineIndex = Math.floor(Math.random() * lineCount);

barrages.push(new Barrage(text, lineIndex));

}

}, 300);123456789每 300ms 自动生成 1~3 条弹幕。随机选择文字和行号。暂停时不会生成新弹幕。6. 用户发送弹幕 ​jssendBtn.onclick = () => {

const text = input.value.trim();

if (text) {

const lineIndex = Math.floor(Math.random() * lineCount);

barrages.push(new Barrage(text, lineIndex));

input.value = "";

}

};12345678用户输入后随机选择行显示。清空输入框,方便连续发送。7. 控制按钮逻辑 ​jstogglePause.onclick = () => {

isPaused = !isPaused;

togglePause.textContent = isPaused ? "▶ 恢复弹幕" : "⏸ 暂停弹幕";

};

toggleHide.onclick = () => {

isHidden = !isHidden;

toggleHide.textContent = isHidden ? "🚫 隐藏弹幕" : "👁 显示弹幕";

};123456789暂停弹幕时,已存在弹幕仍显示,但不移动。隐藏弹幕时,仍在计算位置,但不渲染。8. 渲染循环 ​jsfunction render() {

ctx.clearRect(0, 0, canvas.width, canvas.height);

for (let i = barrages.length - 1; i >= 0; i--) {

const b = barrages[i];

if (!isHidden) b.draw();

if (!isPaused) b.update();

if (b.x + ctx.measureText(b.text).width < 0) barrages.splice(i, 1);

}

requestAnimationFrame(render);

}

render();1234567891011清空画布,重新绘制所有弹幕。遍历弹幕数组,从后往前遍历,方便删除已移出屏幕的弹幕。requestAnimationFrame 保证动画平滑。案例源码 ​html

高密度弹幕(图标+动画+暂停优化)

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199

关键点

移动端 B 站弹幕功能实现 ​ 更新: 11/26/2025字数: 0 字 时长: 0 分钟 在现代网页中,弹幕(Barrage)是一种非常流行的用户互动方式,尤其在直播、

相关文章

自由禁区

自由禁区

365买球平台下载 08-27
手机万年历app排行榜推荐

手机万年历app排行榜推荐

365彩票还能玩吗 07-22