瀏覽代碼

Make youtube video interactable on game finish

Thomas Dy 4 年之前
父節點
當前提交
acca360211
共有 8 個文件被更改,包括 64 次插入37 次删除
  1. 3 1
      dist/index.html
  2. 42 2
      dist/style.css
  3. 5 5
      src/audio.ts
  4. 5 13
      src/background.ts
  5. 1 4
      src/game.ts
  6. 4 6
      src/game/typing.ts
  7. 2 2
      src/global.d.ts
  8. 2 4
      src/youtube.ts

+ 3 - 1
dist/index.html

@@ -7,7 +7,9 @@
   </head>
   <body>
     <div id="container" class="loading">
-      <div id="background"></div>
+      <div id="background">
+        <div id="video"></div>
+      </div>
       <div id="loading">Loading...</div>
 
       <template id="base-template">

+ 42 - 2
dist/style.css

@@ -13,6 +13,11 @@
   height: 100%;
 }
 
+#container div {
+  pointer-events: none;
+  user-select: none;
+}
+
 /* components {{{ */
 
 /* background switcher {{{ */
@@ -37,8 +42,19 @@
   opacity: 1;
 }
 
-#background div.instant {
+#background div#video {
+  transition: none;
+  height: 140%;
+  bottom: -20%;
+}
+
+#background div#video.settled {
   transition: none;
+  pointer-events: auto;
+  height: 75%;
+  width: 75%;
+  bottom: 0;
+  right: 0;
 }
 /* }}} */
 
@@ -108,6 +124,11 @@
   left: -31.25em;
 }
 
+#container #song-info div {
+  /* override default */
+  pointer-events: auto;
+}
+
 #song-list {
   grid-column: right / end;
   grid-row: top / bottom;
@@ -190,7 +211,7 @@
 #container.game #folder-info {
   opacity: 1;
   top: 0;
-  left: 0;
+  left: -31.25em;
 }
 
 #container.game #song-info {
@@ -218,6 +239,14 @@
   left: 0;
 }
 
+#container.game.game-finished #background div#video {
+  transition: height 0.5s, width 0.5s, bottom 0.5s;
+  height: 75%;
+  width: 75%;
+  bottom: 0;
+  right: 0;
+}
+
 /* }}} */
 
 /* }}} */
@@ -234,6 +263,12 @@
   align-items: center;
 }
 
+#folder-info .left,
+#folder-info .right {
+  /* override default */
+  pointer-events: auto;
+}
+
 #folder-info .left:hover,
 #folder-info .right:hover {
   text-shadow: 0em 0em 0.3125em var(--base-color);
@@ -298,6 +333,11 @@
   transition: margin-left 0.2s;
 }
 
+#container div.song-item {
+  /* override default */
+  pointer-events: auto;
+}
+
 .song-item div {
   white-space: nowrap;
   overflow: hidden;

+ 5 - 5
src/audio.ts

@@ -90,14 +90,11 @@ namespace audio {
       this.listeners.forEach(l => l(this, state));
     }
 
-    exit(): void {
-      this.clearListeners();
-    }
-
     abstract play(): void;
     abstract start(fromTime?: number, duration?: number): void;
     abstract pause(): void;
     abstract stop(): void;
+    abstract exit(): void;
     abstract getState(): PlayState;
     abstract getTime(): number;
     abstract getDuration(): number;
@@ -171,7 +168,6 @@ namespace audio {
     }
 
     exit(): void {
-      super.exit();
       this.stop();
     }
 
@@ -260,6 +256,10 @@ namespace audio {
       this.player.stopVideo();
     }
 
+    exit(): void {
+      // the element gets removed by the background manager and stops that way
+    }
+
     getState(): PlayState {
       return this.mapState(this.player.getPlayerState());
     }

+ 5 - 13
src/background.ts

@@ -9,9 +9,10 @@ namespace background {
     constructor(element: HTMLElement) {
       this.element = element;
       this.last = null;
-      this.video = document.createElement('div');
-      this.video.classList.add('instant');
-      this.element.appendChild(this.video);
+      this.video = util.getElement(element, '#video');
+      this.video.addEventListener('transitionend', () => {
+        this.video.classList.add('settled');
+      });
       this.next = document.createElement('div');
       this.element.appendChild(this.next);
     }
@@ -34,19 +35,10 @@ namespace background {
 
     setVideo(element: HTMLElement) {
       this.video.innerHTML = '';
+      this.video.classList.remove('settled');
       this.video.appendChild(element);
     }
 
-    onResize() {
-      const height = this.element.offsetHeight;
-      const width = this.element.offsetWidth;
-      const iframes = this.element.querySelectorAll('iframe');
-      iframes.forEach((iframe) => {
-        iframe.height = ""+height;
-        iframe.width  = ""+width;
-      });
-    }
-
     private setBackgroundActual(background: string) {
       if (background.indexOf('.') >= 0) {
         this.next.style.backgroundImage = `url(${background})`;

+ 1 - 4
src/game.ts

@@ -6,7 +6,6 @@
 
 namespace game {
   export class MainController extends ScreenManager {
-    bgManager: background.BackgroundManager;
     loadingScreen: Screen;
 
     constructor(container: HTMLElement, configUrl: string) {
@@ -15,11 +14,10 @@ namespace game {
 
       let self = this;
       let bgLayer: HTMLElement = util.getElement(container, '#background');
-      this.bgManager = new background.BackgroundManager(bgLayer);
       let gameContext: GameContext = {
         container: container,
         audioManager: new audio.AudioManager(),
-        bgManager: this.bgManager,
+        bgManager: new background.BackgroundManager(bgLayer),
         loadTemplate: (id: string) => util.loadTemplate(container, id),
         assets: null,
         config: null,
@@ -51,7 +49,6 @@ namespace game {
     onResize(): void {
       const fontSize = this.container.offsetHeight / 28.125;
       this.container.style.setProperty('--base-font-size', `${fontSize}px`);
-      this.bgManager.onResize();
     }
   }
 }

+ 4 - 6
src/game/typing.ts

@@ -115,9 +115,6 @@ namespace game {
                 if (state === audio.PlayState.PLAYING) {
                   this.context.bgManager.showVideo();
                 }
-                if (state === audio.PlayState.STOPPED) {
-                  this.context.bgManager.hideVideo();
-                }
               });
             });
           }
@@ -329,6 +326,7 @@ namespace game {
       this.romajiController.destroy();
       if (this.context.track !== null) {
         this.progressController!.destroy();
+        this.context.track.clearListeners();
       }
       this.scoreController.destroy();
     }
@@ -358,12 +356,12 @@ namespace game {
       }
     }
 
-    exit(): void {
+    exit(): void {}
+
+    transitionExit(): void {
       if (this.context.track !== null) {
         this.context.track.exit();
       }
     }
-
-    transitionExit(): void {}
   }
 }

+ 2 - 2
src/global.d.ts

@@ -5,8 +5,8 @@ declare var onYouTubeIframeAPIReady: () => void;
 
 declare namespace YT {
   interface PlayerOptions {
-    height: number;
-    width: number;
+    height: number | string;
+    width: number | string;
     videoId?: string;
     events?: Partial<PlayerEvents>;
     playerVars?: Partial<PlayerVars>;

+ 2 - 4
src/youtube.ts

@@ -23,8 +23,8 @@ namespace youtube {
     console.time('Loading YouTube player');
     return new Promise((resolve, reject) => {
       const player = new YT.Player(element, {
-        height: element.offsetHeight,
-        width: element.offsetWidth,
+        height: '100%',
+        width: '100%',
         events: {
           onReady: () => {
             console.timeEnd('Loading YouTube player');
@@ -35,9 +35,7 @@ namespace youtube {
           }
         },
         playerVars: {
-          controls: 0,
           disablekb: 1,
-          modestbranding: 1,
           rel: 0,
           iv_load_policy: 3,
           fs: 0