Danmaku
danmaku把观众弹幕分轨飘过画面,互不重叠
用法
基础用法
叠在视频上的弹幕层(absolute inset-0)。items 受控、只增不改,新增项自动入场并按轨道防重叠飘过。
直播画面
tsx
<div className="relative aspect-video">
<video ... />
<Danmaku
items={[
{ id: "x1", text: "弹幕飘过~" },
{ id: "x2", text: "主播好飒!", color: "var(--color-chart-1)", bold: true },
]}
tracks={4}
speed={100}
/>
</div>顶部停留弹幕
mode='top' 的弹幕居中停留在顶部一段时间(非滚动),适合公告/置顶。
直播画面
tsx
<Danmaku
items={[
{ id: "y0", text: "今晚 8 点抽奖,关注不迷路", mode: "top", bold: true },
{ id: "y1", text: "前排围观" },
]}
tracks={4}
/>高密度 · 快速
density='high' 时无空闲轨道也强挤(不丢弹幕);speed 提速、tracks 加轨道。
直播画面
tsx
<Danmaku items={items} density="high" speed={160} tracks={6} />何时用
直播/视频画面上覆盖飘动弹幕。绝对定位铺满父容器且 pointer-events 穿透,配合 LivePlayer 的 overlay 插槽使用。要弹幕就用本组件;要消息列表/公屏滚动用 LiveChat。
导入
ts
import { Danmaku, allocateTrack, densityGap, estimateWidth, leastBusyTrack, scrollDuration, trackFreeTime } from "@hulianui/ui"Props
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| items* | DanmakuItem[] | - | 受控弹幕流,只增不改既有项;新增项自动入场(内部按 item.id 去重,仅对未上屏的入场) |
| tracks | number | 4 | 滚动轨道数 |
| speed | number | 100 | 滚动速度 px/s |
| density | "low" | "normal" | "high" | "normal" | 密度:决定轨道安全间隙 + 无空闲轨道时是否强挤 |
| area | number | 1 | 弹幕占用容器高度比 0-1,1=满屏 |
| opacity | number | 1 | 整体不透明度 |
| paused | boolean | false | 暂停所有动画 |
| className | string | - | 容器自定义类 |
DanmakuItem
| 名称 | 类型 | 默认 | 说明 |
|---|---|---|---|
| id * | string | - | 去重键:内部按它判断该条是否已上屏,只对未上屏的做入场 |
| text * | ReactNode | - | 弹幕内容 |
| mode | "scroll" | "top" | "bottom" | "scroll" | 滚动 / 顶部悬停 / 底部悬停 |
| color | string | 继承前景 token | 文字色 |
| size | "sm" | "md" | "lg" | "md" | 字号档 |
| bold | boolean | false | 加粗 |
禁忌 / 坑
items是只增受控流:组件内部记录已上屏 id,只对「新增且未上屏」的项入场。改写既有项不会重新触发动画;要让同一条再飞一次须换新id。- 长直播务必裁剪
items(如slice(-60)),否则数组无限膨胀;组件只对新项做动画,旧项留在数组不影响渲染但占内存。 - 组件铺满父容器且
pointer-events: none穿透,父容器需position: relative+overflow: hidden。
相关
Table · Book3D · ProTable · PricingTable · JsonViewer · EditableTable
Playground
直播画面
<div className="relative aspect-video">
<video ... />
<Danmaku items={items} tracks={4} speed={100} density="normal" />
</div>