eplayer 1.5.14 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/danmaku.js +289 -0
- package/docs/eplayer.js +40 -48
- package/docs/index.html +36 -58
- package/package.json +1 -1
package/docs/danmaku.js
ADDED
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
const SPEED_ARG = 0.009
|
|
2
|
+
|
|
3
|
+
const defaultDanmakuData = {
|
|
4
|
+
msg: '',
|
|
5
|
+
fontSize: 24,
|
|
6
|
+
fontColor: '#ffffff',
|
|
7
|
+
rollTime: 0,
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
class Danmaku {
|
|
11
|
+
constructor(options) {
|
|
12
|
+
this._container = options.container
|
|
13
|
+
this._totalWidth = null
|
|
14
|
+
this._totalHeight = null
|
|
15
|
+
this._trackSize = 12
|
|
16
|
+
this._renderTimer = null
|
|
17
|
+
this._queue = []
|
|
18
|
+
this._tracks = null
|
|
19
|
+
this._autoId = 0
|
|
20
|
+
this._paused = true
|
|
21
|
+
this.resize()
|
|
22
|
+
this._resetTracks()
|
|
23
|
+
console.log(this._container)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
resize() {
|
|
27
|
+
this._totalWidth = this._container.offsetWidth
|
|
28
|
+
this._totalHeight = this._container.offsetHeight
|
|
29
|
+
this.clearScreen()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
clearScreen() {
|
|
33
|
+
this._clearDanmakuNodes()
|
|
34
|
+
this._resetTracks()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_resetTracks() {
|
|
38
|
+
const count = Math.floor(this._totalHeight / this._trackSize / 3)
|
|
39
|
+
this._tracks = new Array(count)
|
|
40
|
+
for (let i = 0; i < count; i++) {
|
|
41
|
+
this._tracks[i] = []
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 循环弹幕节点
|
|
46
|
+
_eachDanmakuNode(fn) {
|
|
47
|
+
let child = this._container.firstChild
|
|
48
|
+
let id, y
|
|
49
|
+
while (child) {
|
|
50
|
+
if (child.nodeType === 1) {
|
|
51
|
+
y = child.getAttribute('data-y')
|
|
52
|
+
id = child.getAttribute('data-id')
|
|
53
|
+
if (y && id) { fn(child, Number(y), Number(id)) }
|
|
54
|
+
}
|
|
55
|
+
child = child.nextSibling
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
_clearDanmakuNodes() {
|
|
60
|
+
const nodes = []
|
|
61
|
+
this._eachDanmakuNode((node) => {
|
|
62
|
+
nodes.push(node)
|
|
63
|
+
})
|
|
64
|
+
nodes.forEach((node) => {
|
|
65
|
+
this._container.removeChild(node)
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_parseData(data) {
|
|
70
|
+
return Object.assign({
|
|
71
|
+
autoId: ++this._autoId,
|
|
72
|
+
fontSize: Math.floor(Math.random() * 20) + 20
|
|
73
|
+
}, defaultDanmakuData, data)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
add(data) {
|
|
77
|
+
this._queue.push(this._parseData(data))
|
|
78
|
+
// 如果队列轮询已经停止,则启动
|
|
79
|
+
if (!this._renderTimer) { this._render() }
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 把弹幕数据加到合适的轨道
|
|
83
|
+
_addToTrack(data) {
|
|
84
|
+
// 单条轨道
|
|
85
|
+
let track
|
|
86
|
+
// 轨道的最后一项弹幕数据
|
|
87
|
+
let lastItem
|
|
88
|
+
// 弹幕已经走的路程
|
|
89
|
+
let distance
|
|
90
|
+
// 弹幕数据最终坐落的轨道索引
|
|
91
|
+
// 有些弹幕会占多条轨道,所以 y 是个数组
|
|
92
|
+
let y = []
|
|
93
|
+
|
|
94
|
+
const now = Date.now()
|
|
95
|
+
|
|
96
|
+
for (let i = 0; i < this._tracks.length; i++) {
|
|
97
|
+
track = this._tracks[i]
|
|
98
|
+
|
|
99
|
+
if (track.length) {
|
|
100
|
+
// 轨道被占用,要计算是否会重叠
|
|
101
|
+
// 只需要跟轨道最后一条弹幕比较即可
|
|
102
|
+
lastItem = track[track.length - 1]
|
|
103
|
+
|
|
104
|
+
// 计算已滚动距离
|
|
105
|
+
distance = lastItem.rollSpeed * (now - lastItem.startTime) / 1000
|
|
106
|
+
|
|
107
|
+
// 通过速度差,计算最后一条弹幕全部消失前,是否会与新增弹幕重叠
|
|
108
|
+
// 如果不会重叠,则可以使用当前轨道
|
|
109
|
+
if (
|
|
110
|
+
(distance > lastItem.width) &&
|
|
111
|
+
(
|
|
112
|
+
(data.rollSpeed <= lastItem.rollSpeed) ||
|
|
113
|
+
((distance - lastItem.width) / (data.rollSpeed - lastItem.rollSpeed) >
|
|
114
|
+
(this._totalWidth + lastItem.width - distance) / lastItem.rollSpeed)
|
|
115
|
+
)
|
|
116
|
+
) {
|
|
117
|
+
y.push(i)
|
|
118
|
+
} else {
|
|
119
|
+
y = []
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
} else {
|
|
123
|
+
// 轨道未被占用
|
|
124
|
+
y.push(i)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// 有足够的轨道可以用时,就可以新增弹幕了,否则等下一次轮询
|
|
128
|
+
if (y.length >= data.useTracks) {
|
|
129
|
+
data.y = y
|
|
130
|
+
y.forEach((i) => {
|
|
131
|
+
this._tracks[i].push(data)
|
|
132
|
+
})
|
|
133
|
+
break
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// (弹幕飘到尽头后)从轨道中移除对应数据
|
|
139
|
+
_removeFromTrack(y, id) {
|
|
140
|
+
y.forEach((i) => {
|
|
141
|
+
const track = this._tracks[i]
|
|
142
|
+
for (let j = 0; j < track.length; j++) {
|
|
143
|
+
if (track[j].autoId === id) {
|
|
144
|
+
track.splice(j, 1)
|
|
145
|
+
break
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 通过 y 和 id 获取弹幕数据
|
|
152
|
+
_findData(y, id) {
|
|
153
|
+
const track = this._tracks[y]
|
|
154
|
+
for (let j = 0; j < track.length; j++) {
|
|
155
|
+
if (track[j].autoId === id) {
|
|
156
|
+
return track[j]
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 轮询渲染
|
|
162
|
+
_render() {
|
|
163
|
+
if (this._paused) { return }
|
|
164
|
+
try {
|
|
165
|
+
this._renderToDOM()
|
|
166
|
+
} finally {
|
|
167
|
+
this._renderEnd()
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
_renderToDOM() {
|
|
172
|
+
let count = Math.floor(this._tracks.length / 3), i = 0
|
|
173
|
+
|
|
174
|
+
while (count && i < this._queue.length) {
|
|
175
|
+
const data = this._queue[i]
|
|
176
|
+
let node = data.node
|
|
177
|
+
|
|
178
|
+
if (!node) {
|
|
179
|
+
// 弹幕节点基本样式
|
|
180
|
+
data.node = node = document.createElement('div')
|
|
181
|
+
node.innerText = data.msg
|
|
182
|
+
node.style.position = 'absolute'
|
|
183
|
+
node.style.left = '100%'
|
|
184
|
+
node.style.whiteSpace = 'nowrap'
|
|
185
|
+
node.style.color = data.fontColor
|
|
186
|
+
node.style.fontSize = data.fontSize + 'px'
|
|
187
|
+
node.style.willChange = 'transform'
|
|
188
|
+
this._container.appendChild(node)
|
|
189
|
+
|
|
190
|
+
data.useTracks = Math.ceil(node.offsetHeight / this._trackSize)
|
|
191
|
+
// 占用的轨道数多于轨道总数,则忽略此数据
|
|
192
|
+
if (data.useTracks > this._tracks.length) {
|
|
193
|
+
this._queue.splice(i, 1)
|
|
194
|
+
this._container.removeChild(node)
|
|
195
|
+
continue
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
data.width = node.offsetWidth
|
|
199
|
+
data.totalDistance = data.width + this._totalWidth
|
|
200
|
+
data.rollTime = data.rollTime ||
|
|
201
|
+
Math.floor(data.totalDistance * SPEED_ARG * (Math.random() * 0.3 + 0.7))
|
|
202
|
+
data.rollSpeed = data.totalDistance / data.rollTime
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
this._addToTrack(data)
|
|
206
|
+
|
|
207
|
+
if (data.y) {
|
|
208
|
+
this._queue.splice(i, 1)
|
|
209
|
+
|
|
210
|
+
node.setAttribute('data-id', data.autoId)
|
|
211
|
+
node.setAttribute('data-y', data.y[0])
|
|
212
|
+
node.style.top = data.y[0] * this._trackSize + 'px'
|
|
213
|
+
node.style.transition = `transform ${data.rollTime}s linear`
|
|
214
|
+
node.style.transform = `translateX(-${data.totalDistance}px)`
|
|
215
|
+
node.addEventListener('transitionstart', () => {
|
|
216
|
+
data.startTime = Date.now()
|
|
217
|
+
}, false)
|
|
218
|
+
node.addEventListener('transitionend', () => {
|
|
219
|
+
this._removeFromTrack(data.y, data.autoId)
|
|
220
|
+
this._container.removeChild(node)
|
|
221
|
+
this._queue = this._queue.filter(item => item.autoId != data.autoId)
|
|
222
|
+
}, false)
|
|
223
|
+
|
|
224
|
+
data.startTime = Date.now() + 80
|
|
225
|
+
|
|
226
|
+
} else {
|
|
227
|
+
// 当前弹幕要排队,继续处理下一条
|
|
228
|
+
i++
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
count--
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
// 轮询结束后,根据队列长度继续执行或停止执行
|
|
237
|
+
_renderEnd() {
|
|
238
|
+
if (this._queue.length > 0) {
|
|
239
|
+
this._renderTimer = requestAnimationFrame(() => {
|
|
240
|
+
this._render()
|
|
241
|
+
})
|
|
242
|
+
} else {
|
|
243
|
+
this._renderTimer = null
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
pause() {
|
|
248
|
+
if (this._resumeTimer) { clearTimeout(this._resumeTimer) }
|
|
249
|
+
if (this._renderTimer) {
|
|
250
|
+
clearTimeout(this._renderTimer)
|
|
251
|
+
this._renderTimer = null
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (this._paused) { return }
|
|
255
|
+
this._paused = true
|
|
256
|
+
|
|
257
|
+
this._eachDanmakuNode((node, y, id) => {
|
|
258
|
+
const data = this._findData(y, id)
|
|
259
|
+
if (data) {
|
|
260
|
+
// 获取已滚动距离
|
|
261
|
+
data.rolledDistance = -getTranslateX(node)
|
|
262
|
+
|
|
263
|
+
// 移除动画,计算出弹幕所在的位置,固定样式
|
|
264
|
+
node.style.transition = ''
|
|
265
|
+
node.style.transform = `translateX(-${data.rolledDistance}px)`
|
|
266
|
+
}
|
|
267
|
+
})
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// 继续滚动弹幕
|
|
271
|
+
resume() {
|
|
272
|
+
if (!this._paused) { return }
|
|
273
|
+
|
|
274
|
+
this._eachDanmakuNode((node, y, id) => {
|
|
275
|
+
const data = this._findData(y, id)
|
|
276
|
+
if (data) {
|
|
277
|
+
data.startTime = Date.now()
|
|
278
|
+
// 重新计算滚完剩余距离需要多少时间
|
|
279
|
+
data.rollTime = (data.totalDistance - data.rolledDistance) / data.rollSpeed
|
|
280
|
+
node.style.transition = `transform ${data.rollTime}s linear`
|
|
281
|
+
node.style.transform = `translateX(-${data.totalDistance}px)`
|
|
282
|
+
}
|
|
283
|
+
})
|
|
284
|
+
|
|
285
|
+
this._paused = false
|
|
286
|
+
|
|
287
|
+
if (!this._renderTimer) { this._render() }
|
|
288
|
+
}
|
|
289
|
+
}
|
package/docs/eplayer.js
CHANGED
|
@@ -4,34 +4,43 @@ class Eplayer extends HTMLElement {
|
|
|
4
4
|
this.doms = {}
|
|
5
5
|
this.src = this.getAttribute('src')
|
|
6
6
|
this.type = this.getAttribute('type')
|
|
7
|
-
this.beatmap = this.getAttribute('beatmap')
|
|
8
|
-
this.height = this.getAttribute('height')
|
|
9
7
|
this.live = JSON.parse(this.getAttribute('live'))
|
|
8
|
+
this.danmaku = null
|
|
10
9
|
|
|
11
10
|
this.init()
|
|
12
11
|
this.stream()
|
|
13
12
|
}
|
|
14
13
|
|
|
15
14
|
static get observedAttributes() {
|
|
16
|
-
return ['src', 'type', '
|
|
15
|
+
return ['src', 'type', 'danma', 'live']
|
|
17
16
|
}
|
|
18
17
|
|
|
19
|
-
attributeChangedCallback(name,
|
|
20
|
-
if (name === 'src')
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
attributeChangedCallback(name, oldVal, newVal) {
|
|
19
|
+
if (name === 'src') {
|
|
20
|
+
this.src = this.$('.video').src = newVal
|
|
21
|
+
this.stream()
|
|
22
|
+
this.video.load()
|
|
23
|
+
}
|
|
24
|
+
if (name === 'type') {
|
|
25
|
+
this.type = newVal
|
|
26
|
+
this.stream()
|
|
27
|
+
this.video.load()
|
|
28
|
+
}
|
|
24
29
|
if (name === 'live') {
|
|
25
30
|
this.live = JSON.parse(newVal)
|
|
26
31
|
if (this.live) {
|
|
27
32
|
this.$('.progress').style.display = 'none'
|
|
28
33
|
this.$('.time').style.display = 'none'
|
|
34
|
+
} else {
|
|
35
|
+
this.$('.progress').style.display = 'block'
|
|
36
|
+
this.$('.time').style.display = 'inline-block'
|
|
29
37
|
}
|
|
30
38
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
if (name === 'danma') {
|
|
40
|
+
this.danmaku.add({
|
|
41
|
+
msg: newVal
|
|
42
|
+
})
|
|
43
|
+
}
|
|
35
44
|
}
|
|
36
45
|
|
|
37
46
|
$(key) {
|
|
@@ -44,22 +53,6 @@ class Eplayer extends HTMLElement {
|
|
|
44
53
|
this.$('.mark').classList.add('loading')
|
|
45
54
|
}
|
|
46
55
|
|
|
47
|
-
startMug() {
|
|
48
|
-
if (!this.beatmap) return
|
|
49
|
-
this.$('.mug').innerHTML = '' // 先清空
|
|
50
|
-
this.$('.mug').style.display = 'block'
|
|
51
|
-
this.$('.mug').style.height = this.height + 'px'
|
|
52
|
-
this.$('.mug').style.width = (this.height / 8 * 5) + 'px'
|
|
53
|
-
this.$('.ep-video').style.display = 'none'
|
|
54
|
-
this.$('.controls').style.display = 'none'
|
|
55
|
-
if (!this.beatmap) return
|
|
56
|
-
const beats = this.beatmap.split('|').map(item => {
|
|
57
|
-
const [fps, button] = item.split(':')
|
|
58
|
-
return { fps, button }
|
|
59
|
-
})
|
|
60
|
-
new Mug(beats, this.$('.mug'), this.video)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
56
|
stream() {
|
|
64
57
|
switch (this.type) {
|
|
65
58
|
case 'hls':
|
|
@@ -73,7 +66,6 @@ class Eplayer extends HTMLElement {
|
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
mark() {
|
|
76
|
-
if (this.beatmap) return
|
|
77
69
|
clearTimeout(this.timer)
|
|
78
70
|
this.timer = setTimeout(() => this.play(), 200)
|
|
79
71
|
}
|
|
@@ -86,13 +78,14 @@ class Eplayer extends HTMLElement {
|
|
|
86
78
|
}
|
|
87
79
|
|
|
88
80
|
play() {
|
|
89
|
-
if (this.beatmap) return
|
|
90
81
|
if (this.video.paused) {
|
|
91
82
|
this.video.play()
|
|
83
|
+
this.danmaku.resume()
|
|
92
84
|
this.$('.ep-video').style.display = 'none'
|
|
93
85
|
this.$('.is-play').classList.replace('ep-play', 'ep-pause')
|
|
94
86
|
} else {
|
|
95
87
|
this.video.pause()
|
|
88
|
+
this.danmaku.play()
|
|
96
89
|
this.$('.ep-video').style.display = 'block'
|
|
97
90
|
this.$('.is-play').classList.replace('ep-pause', 'ep-play')
|
|
98
91
|
}
|
|
@@ -241,7 +234,6 @@ class Eplayer extends HTMLElement {
|
|
|
241
234
|
}
|
|
242
235
|
|
|
243
236
|
init() {
|
|
244
|
-
// console.log(this.beatmap)
|
|
245
237
|
let html = `
|
|
246
238
|
<style>
|
|
247
239
|
@import "https://at.alicdn.com/t/c/font_836948_ro9xopmggai.css";
|
|
@@ -265,7 +257,6 @@ class Eplayer extends HTMLElement {
|
|
|
265
257
|
overflow: hidden;
|
|
266
258
|
}
|
|
267
259
|
.controls{
|
|
268
|
-
display:${this.beatmap ? 'none' : 'block'};
|
|
269
260
|
position:absolute;
|
|
270
261
|
left:0;
|
|
271
262
|
right:0;
|
|
@@ -413,7 +404,6 @@ class Eplayer extends HTMLElement {
|
|
|
413
404
|
}
|
|
414
405
|
.ep-video {
|
|
415
406
|
position: absolute;
|
|
416
|
-
display:${this.beatmap ? 'none' : 'block'};
|
|
417
407
|
bottom: 25px;
|
|
418
408
|
right: 20px;
|
|
419
409
|
font-size:40px;
|
|
@@ -452,24 +442,24 @@ class Eplayer extends HTMLElement {
|
|
|
452
442
|
margin-left:-10px;
|
|
453
443
|
display:inline-block;
|
|
454
444
|
}
|
|
455
|
-
|
|
456
|
-
height: ${this.height}px;
|
|
457
|
-
width: ${this.height / 8 * 5}px;
|
|
458
|
-
position: absolute;
|
|
459
|
-
z-index: 999;
|
|
460
|
-
/* pointer-events: none; */
|
|
461
|
-
transform: translate(-50%, -50%);
|
|
462
|
-
left: 50%;
|
|
463
|
-
top: 50%;
|
|
464
|
-
opacity: 0.95;
|
|
465
|
-
display: ${this.beatmap ? 'block' : 'none'}
|
|
466
|
-
}
|
|
445
|
+
|
|
467
446
|
.wrap{
|
|
468
447
|
position: relative;
|
|
469
448
|
}
|
|
449
|
+
|
|
450
|
+
.danmaku {
|
|
451
|
+
position: absolute;
|
|
452
|
+
top: 0;
|
|
453
|
+
left: 0;
|
|
454
|
+
right: 0;
|
|
455
|
+
bottom: 0;
|
|
456
|
+
pointer-events: none;
|
|
457
|
+
overflow: hidden;
|
|
458
|
+
z-index: 999;
|
|
459
|
+
}
|
|
470
460
|
</style>
|
|
471
461
|
<div class="wrap">
|
|
472
|
-
<div class="
|
|
462
|
+
<div class="danmaku"></div>
|
|
473
463
|
<div class="eplayer">
|
|
474
464
|
<video id="video" class="video" src="${this.src || ''}"></video>
|
|
475
465
|
<div class="mark loading"></div>
|
|
@@ -537,7 +527,7 @@ class Eplayer extends HTMLElement {
|
|
|
537
527
|
'.panel',
|
|
538
528
|
'.speed',
|
|
539
529
|
'.pip',
|
|
540
|
-
'.
|
|
530
|
+
'.danmaku'
|
|
541
531
|
]
|
|
542
532
|
|
|
543
533
|
for (const key of doms) {
|
|
@@ -577,8 +567,10 @@ class Eplayer extends HTMLElement {
|
|
|
577
567
|
|
|
578
568
|
mount() {
|
|
579
569
|
this.video = this.$('.video')
|
|
580
|
-
this.mug = this.$('.mug')
|
|
581
570
|
this.video.volume = 0.5
|
|
571
|
+
this.danmaku = new Danmaku({
|
|
572
|
+
container: this.$('.danmaku')
|
|
573
|
+
})
|
|
582
574
|
// setVolume(this.video.volume * 10, this.$('.line'))
|
|
583
575
|
this.video.onwaiting = this.waiting.bind(this)
|
|
584
576
|
this.video.oncanplay = this.canplay.bind(this)
|
package/docs/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
8
8
|
<title>eplayer</title>
|
|
9
9
|
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/pixi.js/4.5.2/pixi.min.js"></script>
|
|
10
|
-
<script src="./
|
|
10
|
+
<script src="./danmaku.js"></script>
|
|
11
11
|
</head>
|
|
12
12
|
|
|
13
13
|
<body>
|
|
@@ -22,12 +22,13 @@
|
|
|
22
22
|
transform: translate(-50%, -50%);
|
|
23
23
|
left: 50%;
|
|
24
24
|
top: 50%;
|
|
25
|
+
height: 450px;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
@media screen and (max-width: 500px) {
|
|
28
29
|
.wrapper {
|
|
29
30
|
width: 100%;
|
|
30
|
-
transform: translate(-50%, 0)!important;
|
|
31
|
+
transform: translate(-50%, 0) !important;
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
|
|
@@ -55,61 +56,11 @@
|
|
|
55
56
|
background: #1ea6e9;
|
|
56
57
|
}
|
|
57
58
|
</style>
|
|
58
|
-
<a href="https://github.com/132yse/eplayer" class="github-corner" aria-label="View source on GitHub"><svg width="80"
|
|
59
|
-
height="80" viewBox="0 0 250 250"
|
|
60
|
-
style="fill:#64CEAA; color:#fff; position: absolute; top: 0; border: 0; right: 0;" aria-hidden="true">
|
|
61
|
-
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
|
62
|
-
<path
|
|
63
|
-
d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
|
64
|
-
fill="currentColor" style="transform-origin: 130px 106px;" class="octo-arm"></path>
|
|
65
|
-
<path
|
|
66
|
-
d="M115.0,115.0 C114.9,115.1 118.7,116.5 119.8,115.4 L133.7,101.6 C136.9,99.2 139.9,98.4 142.2,98.6 C133.8,88.0 127.5,74.4 143.8,58.0 C148.5,53.4 154.0,51.2 159.7,51.0 C160.3,49.4 163.2,43.6 171.4,40.1 C171.4,40.1 176.1,42.5 178.8,56.2 C183.1,58.6 187.2,61.8 190.9,65.4 C194.5,69.0 197.7,73.2 200.1,77.6 C213.8,80.2 216.3,84.9 216.3,84.9 C212.7,93.1 206.9,96.0 205.4,96.6 C205.1,102.4 203.0,107.8 198.3,112.5 C181.9,128.9 168.3,122.5 157.7,114.1 C157.9,116.9 156.7,120.9 152.7,124.9 L141.0,136.5 C139.8,137.7 141.6,141.9 141.8,141.8 Z"
|
|
67
|
-
fill="currentColor" class="octo-body"></path>
|
|
68
|
-
</svg></a>
|
|
69
|
-
<style>
|
|
70
|
-
.github-corner:hover .octo-arm {
|
|
71
|
-
animation: octocat-wave 560ms ease-in-out;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
@keyframes octocat-wave {
|
|
75
|
-
|
|
76
|
-
0%,
|
|
77
|
-
100% {
|
|
78
|
-
transform: rotate(0);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
20%,
|
|
82
|
-
60% {
|
|
83
|
-
transform: rotate(-25deg);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
40%,
|
|
87
|
-
80% {
|
|
88
|
-
transform: rotate(10deg);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
@media (max-width: 500px) {
|
|
93
|
-
.github-corner:hover .octo-arm {
|
|
94
|
-
animation: none;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
.github-corner .octo-arm {
|
|
98
|
-
animation: octocat-wave 560ms ease-in-out;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
</style>
|
|
102
|
-
<script>
|
|
103
|
-
setTimeout(() => {
|
|
104
|
-
document.querySelector('e-player').setAttribute('height', '450')
|
|
105
59
|
|
|
106
|
-
document.querySelector('e-player').setAttribute('beatmap', '')
|
|
107
|
-
}, 1000)
|
|
108
|
-
</script>
|
|
109
60
|
<div class="wrapper">
|
|
110
|
-
|
|
111
|
-
<e-player id="ep"
|
|
112
|
-
|
|
61
|
+
<div class="container"></div>
|
|
62
|
+
<e-player id="ep"
|
|
63
|
+
src="https://a1.alibabausercontent.com/prod/feupload/user/edos8/2f0e7af0-29f1-11ef-b3cd-818e64ac843d.mp4">
|
|
113
64
|
</e-player>
|
|
114
65
|
|
|
115
66
|
<a href="https://github.com/132yse/eplayer">github</a>
|
|
@@ -120,9 +71,36 @@
|
|
|
120
71
|
<script src="https://unpkg.com/hls.js"></script>
|
|
121
72
|
<script src="./eplayer.js"></script>
|
|
122
73
|
<script>
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
74
|
+
const container = document.querySelector('.container')
|
|
75
|
+
const messages = [
|
|
76
|
+
'来了来了',
|
|
77
|
+
'沙发~',
|
|
78
|
+
'准时到达',
|
|
79
|
+
'发个弹幕见证一下',
|
|
80
|
+
'c站招募投稿君',
|
|
81
|
+
'c站招募主播',
|
|
82
|
+
'up主威武',
|
|
83
|
+
'c站发光发热',
|
|
84
|
+
'发一下弹幕菊花有不会坏',
|
|
85
|
+
'有人在吗',
|
|
86
|
+
'兄弟们又见面了',
|
|
87
|
+
'哈哈哈哈哈',
|
|
88
|
+
'呵呵呵',
|
|
89
|
+
'嘻嘻'
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
function init(danmaku) {
|
|
94
|
+
for (let i = 0; i < 100; i++) {
|
|
95
|
+
// danmaku.add({
|
|
96
|
+
// msg: messages[parseInt(Math.random() * messages.length)],
|
|
97
|
+
// fontSize: Math.floor(Math.random() * 20) + 20
|
|
98
|
+
// })
|
|
99
|
+
document.querySelector('e-player').setAttribute('danma', messages[parseInt(Math.random() * messages.length)])
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
init()
|
|
126
104
|
</script>
|
|
127
105
|
<!-- <script src="./pic.js"></script> -->
|
|
128
106
|
</body>
|