show danmaku
This commit is contained in:
parent
31a19e8920
commit
0eb803efbd
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"danmaku": [
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "0.4",
|
||||
"text": "比♂利比♂利爱1",
|
||||
"color": "#f00",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "0.8",
|
||||
"text": "比♂利比♂利比♂利爱1.2",
|
||||
"color": "#0f0",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "1.2",
|
||||
"text": "比♂利比♂利爱1.4比♂利比♂利爱1.4比♂利比♂利爱1.4比♂利比♂利爱1.4比♂利比♂利爱1.4比♂利比♂利爱1.4",
|
||||
"color": "#00f",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "1.6",
|
||||
"text": "比♂利比♂利爱1.6",
|
||||
"color": "#ff0",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "2.0",
|
||||
"text": "比♂利比♂利比♂利爱1.8",
|
||||
"color": "#f0f",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "2.4",
|
||||
"text": "比♂利比♂利比♂利爱2",
|
||||
"color": "#0ff",
|
||||
"type": "right"
|
||||
},
|
||||
{
|
||||
"author": "DIYgod",
|
||||
"time": "2.8",
|
||||
"text": "比♂利比♂利爱2.2",
|
||||
"color": "#f00",
|
||||
"type": "right"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -63,6 +63,9 @@
|
|||
video: {
|
||||
url: 'http://o6m1pq7od.bkt.clouddn.com/禁绝的边境线.mp4',
|
||||
pic: 'http://o6m1pq7od.bkt.clouddn.com/禁绝的边境线.jpg'
|
||||
},
|
||||
danmaku: {
|
||||
get: 'danmaku.json'
|
||||
}
|
||||
});
|
||||
dp.init();
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
137
src/DPlayer.js
137
src/DPlayer.js
|
|
@ -164,6 +164,8 @@
|
|||
// get this audio object
|
||||
this.audio = this.element.getElementsByClassName('dplayer-video')[0];
|
||||
|
||||
this.ptime = this.element.getElementsByClassName('dplayer-ptime')[0];
|
||||
|
||||
// hide controller if mouse stops for 2 seconds
|
||||
let hideTime = 0;
|
||||
const hideController = () => {
|
||||
|
|
@ -354,6 +356,7 @@
|
|||
this.loop = false;
|
||||
this.audio.loop = this.loop;
|
||||
}
|
||||
settingBox.classList.remove('dplayer-setting-box-open');
|
||||
});
|
||||
loopToggle.addEventListener('change', () => {
|
||||
if (loopToggle.checked) {
|
||||
|
|
@ -364,6 +367,7 @@
|
|||
this.loop = false;
|
||||
this.audio.loop = this.loop;
|
||||
}
|
||||
settingBox.classList.remove('dplayer-setting-box-open');
|
||||
});
|
||||
|
||||
// speed control
|
||||
|
|
@ -389,8 +393,8 @@
|
|||
</div>
|
||||
<div class="dplayer-setting-speed-item" data-speed="2">
|
||||
<span class="dplayer-label">2</span>
|
||||
</div>
|
||||
`;
|
||||
</div>`;
|
||||
|
||||
const speedItem = settingBox.getElementsByClassName('dplayer-setting-speed-item');
|
||||
for (let i = 0; i < speedItem.length; i++) {
|
||||
speedItem[i].addEventListener('click', () => {
|
||||
|
|
@ -400,6 +404,7 @@
|
|||
settingBox.innerHTML = settingBack;
|
||||
settingEvent();
|
||||
}, 300);
|
||||
settingBox.classList.remove('dplayer-setting-box-open');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -455,7 +460,7 @@
|
|||
this.trigger('canplay');
|
||||
});
|
||||
|
||||
// multiple music play
|
||||
// music end
|
||||
this.ended = false;
|
||||
this.audio.addEventListener('ended', () => {
|
||||
this.updateBar('played', 1, 'width');
|
||||
|
|
@ -477,14 +482,101 @@
|
|||
this.element.getElementsByClassName('dplayer-dtime')[0].innerHTML = this.audio.duration ? this.secondToTime(this.audio.duration) : '00:00';
|
||||
}
|
||||
|
||||
// autoplay
|
||||
if (this.option.autoplay && !this.isMobile) {
|
||||
this.play();
|
||||
}
|
||||
this.option.autoplay = true; // autoplay next music
|
||||
const danContainer = this.element.getElementsByClassName('dplayer-danmaku')[0];
|
||||
const danWidth = danContainer.offsetWidth;
|
||||
const danHeight = danContainer.offsetHeight;
|
||||
const itemHeight = 30;
|
||||
const itemY = danHeight / itemHeight;
|
||||
let danTunnel = {};
|
||||
window.danTunnel = danTunnel;
|
||||
|
||||
if (this.isMobile) {
|
||||
this.pause();
|
||||
const danItemRight = (ele) => {
|
||||
return danContainer.getBoundingClientRect().right - ele.getBoundingClientRect().right;
|
||||
};
|
||||
|
||||
const getTunnel = (ele) => {
|
||||
for (let i = 0; i <= itemY - 1; i++) {
|
||||
let item = danTunnel[i + ''];
|
||||
if (item && item.length) {
|
||||
for (let j = 0; j < item.length; j++) {
|
||||
if (danItemRight(item[j]) <= 0) {
|
||||
break;
|
||||
}
|
||||
if (j === item.length - 1) {
|
||||
danTunnel[i + ''].push(ele);
|
||||
ele.addEventListener('animationend', () => {
|
||||
danTunnel[i + ''].splice(0, 1);
|
||||
});
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
danTunnel[i + ''] = [ele];
|
||||
ele.addEventListener('animationend', () => {
|
||||
danTunnel[i + ''].splice(0, 1);
|
||||
});
|
||||
return i;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.danmakuIn = (text, color, type) => {
|
||||
let item = document.createElement(`div`);
|
||||
let content = document.createTextNode(text);
|
||||
item.classList.add(`dplayer-danmaku-item`);
|
||||
item.style.color = color;
|
||||
item.appendChild(content);
|
||||
|
||||
// insert
|
||||
danContainer.appendChild(item);
|
||||
|
||||
// adjust
|
||||
item.style.width = (item.offsetWidth + 1) + 'px';
|
||||
item.style.transform = `translateX(-${danWidth}px)`;
|
||||
item.style.top = itemHeight * getTunnel(item) + 'px';
|
||||
item.addEventListener('animationend', () => {
|
||||
danContainer.removeChild(item);
|
||||
});
|
||||
|
||||
// move
|
||||
item.classList.add(`dplayer-danmaku-move`);
|
||||
};
|
||||
|
||||
// danmaku
|
||||
if (this.option.danmaku) {
|
||||
this.danIndex = 0;
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
|
||||
this.dan = JSON.parse(xhr.responseText).danmaku;
|
||||
console.log(this.dan);
|
||||
|
||||
// autoplay
|
||||
if (this.option.autoplay && !this.isMobile) {
|
||||
this.play();
|
||||
}
|
||||
else if (this.isMobile) {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.log('Request was unsuccessful: ' + xhr.status);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.open('get', this.option.danmaku.get, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
else {
|
||||
// autoplay
|
||||
if (this.option.autoplay && !this.isMobile) {
|
||||
this.play();
|
||||
}
|
||||
else if (this.isMobile) {
|
||||
this.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -499,11 +591,26 @@
|
|||
if (this.playedTime) {
|
||||
clearInterval(this.playedTime);
|
||||
}
|
||||
this.playedTime = setInterval(() => {
|
||||
this.updateBar('played', this.audio.currentTime / this.audio.duration, 'width');
|
||||
this.element.getElementsByClassName('dplayer-ptime')[0].innerHTML = this.secondToTime(this.audio.currentTime);
|
||||
this.trigger('playing');
|
||||
}, 100);
|
||||
if (this.option.danmaku) {
|
||||
this.playedTime = setInterval(() => {
|
||||
this.updateBar('played', this.audio.currentTime / this.audio.duration, 'width');
|
||||
this.ptime.innerHTML = this.secondToTime(this.audio.currentTime);
|
||||
this.trigger('playing');
|
||||
|
||||
const item = this.dan[this.danIndex];
|
||||
if (item && this.audio.currentTime >= item.time) {
|
||||
this.danmakuIn(item.text, item.color, item.type);
|
||||
this.danIndex++;
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
else {
|
||||
this.playedTime = setInterval(() => {
|
||||
this.updateBar('played', this.audio.currentTime / this.audio.duration, 'width');
|
||||
this.ptime.innerHTML = this.secondToTime(this.audio.currentTime);
|
||||
this.trigger('playing');
|
||||
}, 100);
|
||||
}
|
||||
this.element.classList.add('dplayer-playing');
|
||||
this.trigger('play');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@
|
|||
opacity: 0;
|
||||
}
|
||||
|
||||
.dplayer-danmaku-move {
|
||||
animation-play-state: running !important;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.dplayer-controller-mask {
|
||||
opacity: 1;
|
||||
|
|
@ -36,6 +40,7 @@
|
|||
}
|
||||
|
||||
.dplayer-video-wrap {
|
||||
position: relative;
|
||||
background: #000;
|
||||
font-size: 0;
|
||||
width: 100%;
|
||||
|
|
@ -53,16 +58,39 @@
|
|||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
font-size: 24px;
|
||||
color: #fff;
|
||||
|
||||
.dplayer-danmaku-item {
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
transform: translateX(100%);
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
cursor: default;
|
||||
white-space: nowrap;
|
||||
|
||||
&.dplayer-danmaku-move {
|
||||
will-change: transform;
|
||||
animation: danmaku 5s linear;
|
||||
animation-play-state: paused;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes danmaku {
|
||||
from {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dplayer-controller-mask {
|
||||
background-repeat: repeat-x;
|
||||
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==) repeat-x bottom;
|
||||
height: 98px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background-position: bottom;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
|
@ -274,6 +302,7 @@
|
|||
&.dplayer-setting-box-narrow {
|
||||
width: 70px;
|
||||
height: 180px;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue