DIYgod 9 vuotta sitten
vanhempi
commit
0eb803efbd
7 muutettua tiedostoa jossa 210 lisäystä ja 18 poistoa
  1. 53 0
      demo/danmaku.json
  2. 3 0
      demo/index.html
  3. 0 0
      dist/DPlayer.min.css
  4. 0 0
      dist/DPlayer.min.js
  5. 0 0
      dist/DPlayer.min.js.map
  6. 122 15
      src/DPlayer.js
  7. 32 3
      src/DPlayer.scss

+ 53 - 0
demo/danmaku.json

@@ -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"
+        }
+    ]
+}

+ 3 - 0
demo/index.html

@@ -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();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/DPlayer.min.css


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/DPlayer.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 0 - 0
dist/DPlayer.min.js.map


+ 122 - 15
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');
         }

+ 32 - 3
src/DPlayer.scss

@@ -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;
                     }
                 }
 

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä