react实现弹幕
React 实现弹幕功能
弹幕功能通常用于视频播放或直播场景,允许用户发送实时评论并显示在屏幕上。以下是使用 React 实现弹幕功能的几种方法:
使用 CSS 动画实现弹幕
通过 CSS 的 @keyframes 和 transform 实现弹幕的横向移动效果:
import React, { useState, useEffect, useRef } from 'react';
const Danmu = () => {
const [messages, setMessages] = useState([]);
const [inputValue, setInputValue] = useState('');
const containerRef = useRef(null);
const handleSend = () => {
if (inputValue.trim()) {
setMessages([...messages, { text: inputValue, id: Date.now() }]);
setInputValue('');
}
};
return (
<div className="danmu-container" ref={containerRef}>
<div className="danmu-input">
<input
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
placeholder="输入弹幕内容"
/>
<button onClick={handleSend}>发送</button>
</div>
<div className="danmu-display">
{messages.map((msg) => (
<div key={msg.id} className="danmu-item">
{msg.text}
</div>
))}
</div>
</div>
);
};
export default Danmu;
对应的 CSS 样式:
.danmu-container {
position: relative;
width: 100%;
height: 300px;
overflow: hidden;
background-color: #000;
}
.danmu-display {
position: relative;
height: 100%;
}
.danmu-item {
position: absolute;
color: #fff;
white-space: nowrap;
animation: move linear 10s;
}
@keyframes move {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
使用 WebSocket 实现实时弹幕
如果需要实现多人实时弹幕,可以结合 WebSocket:

import React, { useState, useEffect } from 'react';
const DanmuWithWebSocket = () => {
const [messages, setMessages] = useState([]);
const [inputValue, setInputValue] = useState('');
const [socket, setSocket] = useState(null);
useEffect(() => {
const ws = new WebSocket('wss://your-websocket-server');
ws.onmessage = (event) => {
setMessages((prev) => [...prev, { text: event.data, id: Date.now() }]);
};
setSocket(ws);
return () => ws.close();
}, []);
const handleSend = () => {
if (inputValue.trim() && socket) {
socket.send(inputValue);
setInputValue('');
}
};
return (
<div className="danmu-container">
{/* 同上 */}
</div>
);
};
export default DanmuWithWebSocket;
使用第三方库
如果需要更复杂的弹幕功能,可以考虑以下库:
rc-bullets: 专为 React 设计的弹幕组件库danmaku: 通用的 JavaScript 弹幕库
安装 rc-bullets 示例:

npm install rc-bullets
使用示例:
import React from 'react';
import BulletScreen from 'rc-bullets';
const App = () => {
const screenRef = useRef(null);
useEffect(() => {
const screen = new BulletScreen(screenRef.current, { trackCount: 5 });
screen.push('Hello Danmu!');
}, []);
return <div ref={screenRef} style={{ width: '100%', height: '300px' }} />;
};
性能优化建议
弹幕数量较多时,需要注意性能优化:
- 使用
requestAnimationFrame替代 CSS 动画 - 对弹幕进行虚拟滚动,只渲染可视区域内的弹幕
- 定期清理已经移出屏幕的弹幕 DOM 节点
- 使用 Canvas 渲染代替 DOM 渲染(适用于超大量弹幕)
Canvas 实现示例:
const DanmuCanvas = () => {
const canvasRef = useRef(null);
const [messages, setMessages] = useState([]);
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext('2d');
const animate = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制所有弹幕
messages.forEach((msg) => {
ctx.fillStyle = msg.color || '#fff';
ctx.font = '16px Arial';
ctx.fillText(msg.text, msg.x, msg.y);
msg.x -= 2; // 移动速度
});
requestAnimationFrame(animate);
};
animate();
}, [messages]);
// 添加弹幕逻辑...
};
以上方法可以根据具体需求选择或组合使用,CSS 动画适合简单场景,WebSocket 实现实时互动,Canvas 则适合高性能要求。






