react实现弹幕滚动
React 实现弹幕滚动
弹幕是一种在屏幕上横向滚动的评论或消息,常见于视频直播或播放场景。以下是使用 React 实现弹幕滚动的几种方法。
使用 CSS 动画实现弹幕滚动
通过 CSS 的 @keyframes 和 animation 属性,可以实现弹幕的横向滚动效果。
import React, { useState, useEffect } from 'react';
import './Barrage.css';
const Barrage = () => {
const [messages, setMessages] = useState([]);
useEffect(() => {
const newMessage = {
id: Date.now(),
text: `弹幕消息 ${messages.length + 1}`,
top: Math.floor(Math.random() * 80) + 10, // 随机顶部位置
duration: Math.floor(Math.random() * 5) + 3, // 随机动画时长
};
setMessages([...messages, newMessage]);
const timer = setTimeout(() => {
setMessages(messages.filter(msg => msg.id !== newMessage.id));
}, newMessage.duration * 1000);
return () => clearTimeout(timer);
}, [messages]);
return (
<div className="barrage-container">
{messages.map(msg => (
<div
key={msg.id}
className="barrage-item"
style={{
top: `${msg.top}%`,
animation: `moveLeft ${msg.duration}s linear`,
}}
>
{msg.text}
</div>
))}
</div>
);
};
export default Barrage;
对应的 CSS 文件 Barrage.css:
.barrage-container {
position: relative;
width: 100%;
height: 100vh;
overflow: hidden;
}
.barrage-item {
position: absolute;
white-space: nowrap;
color: white;
font-size: 16px;
text-shadow: 1px 1px 2px black;
}
@keyframes moveLeft {
from {
transform: translateX(100%);
}
to {
transform: translateX(-100%);
}
}
使用 requestAnimationFrame 实现高性能弹幕
对于需要更高性能或更复杂控制的弹幕,可以使用 requestAnimationFrame 手动控制动画。
import React, { useState, useEffect, useRef } from 'react';
const Barrage = () => {
const [messages, setMessages] = useState([]);
const containerRef = useRef(null);
useEffect(() => {
const addMessage = () => {
const newMessage = {
id: Date.now(),
text: `弹幕消息 ${messages.length + 1}`,
top: Math.floor(Math.random() * 80) + 10,
left: 100, // 初始位置在右侧
speed: Math.random() * 2 + 1, // 随机速度
};
setMessages(prev => [...prev, newMessage]);
setTimeout(addMessage, Math.random() * 2000); // 随机间隔添加新弹幕
};
addMessage();
}, []);
useEffect(() => {
let animationId;
const animate = () => {
setMessages(prev =>
prev.map(msg => ({
...msg,
left: msg.left - msg.speed,
})).filter(msg => msg.left > -10) // 移除超出屏幕的弹幕
);
animationId = requestAnimationFrame(animate);
};
animationId = requestAnimationFrame(animate);
return () => cancelAnimationFrame(animationId);
}, []);
return (
<div ref={containerRef} style={{ position: 'relative', height: '100vh', overflow: 'hidden' }}>
{messages.map(msg => (
<div
key={msg.id}
style={{
position: 'absolute',
top: `${msg.top}%`,
left: `${msg.left}%`,
whiteSpace: 'nowrap',
color: 'white',
fontSize: '16px',
textShadow: '1px 1px 2px black',
}}
>
{msg.text}
</div>
))}
</div>
);
};
export default Barrage;
使用第三方库实现弹幕
如果需要更丰富的功能(如碰撞检测、暂停/播放等),可以使用第三方库如 rc-bullets。
安装:
npm install rc-bullets
使用示例:
import React, { useEffect } from 'react';
import { Bullet } from 'rc-bullets';
const Barrage = () => {
useEffect(() => {
const screen = new Bullet('.screen', {
trackHeight: 30,
onStart: () => console.log('弹幕开始'),
});
// 添加弹幕
screen.push('这是一条弹幕消息', { color: '#ff0000' });
// 定时添加弹幕
const timer = setInterval(() => {
screen.push(`随机弹幕 ${Math.random().toString(36).substring(7)}`);
}, 1000);
return () => {
clearInterval(timer);
screen.destroy();
};
}, []);
return <div className="screen" style={{ width: '100%', height: '300px', border: '1px solid #ccc' }} />;
};
export default Barrage;
弹幕功能扩展
- 自定义样式:为弹幕添加背景色、边框或阴影。
- 用户交互:允许用户点击暂停或发送弹幕。
- 性能优化:对于大量弹幕,使用虚拟滚动或对象池技术。
- 碰撞检测:避免弹幕重叠,通过调整轨道或速度。
以上方法可以根据实际需求选择或组合使用。CSS 动画适合简单场景,requestAnimationFrame 提供更细粒度控制,而第三方库能快速实现复杂功能。







