综合说他们需要一个新年祈福弹幕墙, 安排一下. 今年疲于应付产品奇奇怪怪的需求, 年末能响应这么一个能立刻得到反馈的简单小功能还挺高兴.
需求及方案确定
弹幕播放:网上有一些成熟的方案或插件, 这里使用了较为简易的js操作dom实现. 两个细节要求:
弹幕不互相遮挡:网上暂停播放动画的方案都较为复杂. 我们记录每条泳道播放的结束时间即可, 每次向预计结束时间最早(已结束)的泳道装填.
尽量铺满屏幕:缩短每条弹幕装填间隙.
背景音乐:自动循环播放
热闹的动效: 使用了来自codepen的代码Countdown to New Year , 它包含
星光背景
塑料烟花: 使用canvas实现的烟花很炫, 但是在非暗黑背景时会有轨迹, 我们使用了这套html+css的方案
未实现的内容:扫码发送弹幕等
代码实现
项目目录
裸项目三件套:index.html script.js style.css
, 使用Jquery
插件
弹幕
读取文件
理论上应该写一套从Excel读取的方法, 但我手头没写过现成的工具方法. 就使用在线工具复制粘贴Excel转换成json, ,用的是bing搜索出来的第一个在线Excel转JSON工具 - UU在线工具
若有需要可参考
xlsx.core.min.js
转换出来的文件复制到
wish.js
中存储, vscode自动帮我把json转js了. 如果使用json存储的话需要写一个request获. 。弹幕播放
在
index.html
中添加barrage
块1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>新年许愿墙</title>
<link
href="https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap"
rel="stylesheet"
/>
<link rel="stylesheet" href="./style.css" />
</head>
<body>
<div class="copyright">xxxxxx技术支持</div>
<div id="barrage">
</div>
<!-- partial -->
<script src="./jquery.min.js"></script>
<script src="./wish.js"></script>
<script src="./script.js"></script>
</body>
</html>在
script.js
中, 执行弹幕装填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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104var barrageStrs = [];
function readWorkbookFromLocalFile() {
for (let i = 0; i < wishList.length; i++) {
barrageStrs.push(wishList[i].sum);
barrageStrs.push(wishList[i].content);
}
}
$(function () {
var $barrage = $('#barrage');
readWorkbookFromLocalFile();
var colors = [
'#F2EF8b',
'#f9cb8b',
'#DDF0ED',
'#ebb10d',
'#ffa60f',
'#f2e68b',
'#f9bd10',
'#f2ce2b',
'#fba414',
'#f0d695',
'#EEE8AB',
'#f09c5a',
'#fbb957',
'#DEA681',
'#f7c173',
'#f9e98b',
'#f9bd10',
'#f4ce69',
'#fca106',
];
var channelList = new Array(9).fill(0);
var secondCount = 0;
var timer = setInterval(() => {
/**
* 泳道计算, 减小碰撞.
* 如果有硬性完全不遮挡的要求, 这里改为index在channel<min的时候才取,
如果没有符合条件(index返回-1)的项,这一轮计时器结束,不进行后续操作
*/
index = channelList.findIndex((channel) => channel === Math.min(...channelList);
const str = barrageStrs[secondCount % barrageStrs.length];
channelList[index] = Math.ceil(secondCount + str.length / 5);
let barrage = new Barrage({
str: str,
x: window.innerHeight * 0.3 + 60 * index,
y: 0,
color: colors[random(0, colors.length - 1)],
parent: $barrage,
});
barrage.move();
secondCount++;
}, 600); // 调整每条新弹幕填充的时间
});
function Barrage({ str: str, x: x, y: y, color: color, parent: parent }) {
var that = this;
this.text = str;
this.pos = {
x: x + 500,
y: y,
};
this.state = false;
this.entity = $('<span>');
this.entity.text(str).css({
position: 'absolute',
top: x,
right: y,
color: color,
fontSize: random(24, 60) + 'px',
fontWeight: 'bold',
maxWidth: '10px',
whiteSpace: 'nowrap',
});
this.speed = 2;
parent.append(this.entity);
this.move = function () {
that.state = true;
this.show();
var timer = setInterval(() => {
var left = parseInt(that.entity.css('left'));
if (left < -6000) {
clearInterval(timer);
that.hide();
that.entity.remove();
}
var right = parseInt(that.entity.css('right'));
right += that.speed;
that.speed += 0.02;
that.entity.css({ right: right });
}, 25);
};
this.show = () => {
that.entity.show();
};
this.hide = () => {
that.entity.hide();
};
this.hide();
}
function random(min, max) {
return Math.floor(min + Math.random() * (max - min));
}
背景音乐
背景音乐播放需要注意的是
Chrome
会在用户未进行页面操作时禁止play()
的操作, 所以写了个傻瓜的循环计时器
index.html
1 |
|
1 |
|
其他动效
Countdown to New Year使用了haml和sass, 又学到一套模板html的写法 !
不需使用也别慌, 使用codepen export该项目, 傻瓜照搬dist目录下的原生三件套代码即可.
背景和其他
1 |
|
完成
祝大家2023新年快乐! 一切顺利!