数据格式
弹幕一般用在直播或者视频播放的场景中,是评论的一种变形;按照我的理解,它的数据格式应该是:
1
2
3
4
5
|
{
[时间戳/视频对应的秒数]: [对应时间点的弹幕列表],
31415926: [{name: "张三", content: "哈哈哈哈哈"}, {}, {}...],
...
}
|
发布弹幕
当用户发布弹幕时,获取当前视频的时间点,将弹幕插入到弹幕列表中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
addBarrage = () => {
let barrage = inputEle.value;
if (barrage && barrage.trim().length > 0) {
let now = this.getCurrentTime();
let content = barrage.trim();
if (this.barrages[now]) {
this.barrages[now].push({
name: '麻辣个鸡', // 当前用户的用户名
content
});
} else {
this.barrages[now] = [
{
name: '麻辣个鸡',
content
}
];
}
inputEle.value = '';
}
};
|
弹幕展示
实时获取视频的播放状态,当视频播放时,获取视频播放位置;当播放时间等于弹幕时间时,展示对应弹幕:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
// 这个函数要放到计时器里执行
appendBarrage = () => {
let list = this.barrages[this.getCurrentTime()] || null;
if (Array.isArray(list)) {
list.forEach((item, index) => {
this.id = this.id + 1;
let id = this.id;
let node = this.generateSpan(item, index, id); // 生成每条弹幕的容器
sectioner.append(node);
// 弹幕最短的运动长度就是视频窗口宽度加上弹幕本身的长度了
let temp = document.querySelector(`[data-id="${id}"]`);
let where = temp.dataset.where;
// 使用 transform 性能比较好
temp.style.transform = `translate3D(-${temp.clientWidth}px, ${
where * 20
}px, 0)`;
// 当弹幕弹出屏幕时,可将弹幕移除 DOM 提升性能
temp.addEventListener(
'transitionend',
function () {
this.remove(true);
},
{ once: true }
);
});
}
};
|
怎么展示弹幕呢?可以根据视频的高度和弹幕的高度,设置相应的弹幕轨道:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 计算轨道数
setFloors = () => {
this.floor = Math.floor(videoEle.clientHeight / 20) - 1;
};
generateSpan = (item, index, id) => {
let where = 0;
let span = document.createElement('span');
where = this.where;
// 分层摆放每条弹幕
if (this.where > this.floor - 1) {
this.where = 0;
} else {
this.where++;
}
span.innerText = `${item.name}: ${item.content}`;
span.dataset.id = `${id}`;
span.dataset.where = `${where}`;
span.style.zIndex = `${index}`;
span.style.transform = `translate3D(${videoEle.clientWidth}px, ${
where * 20
}px, 0)`;
return span;
};
|
未完待续
DEMO 在
这里
,暂停视频时当前时间对应的弹幕停止滚动还没想好怎么实现(初步想法是使用 animation 替换 transform,因为 animation-play-state 可以控制动画的状态)。