Add play/pause bezels to the video player
authorRigel Kent <sendmemail@rigelk.eu>
Wed, 18 Dec 2019 19:20:04 +0000 (20:20 +0100)
committerRigel Kent <sendmemail@rigelk.eu>
Wed, 18 Dec 2019 19:20:11 +0000 (20:20 +0100)
client/src/app/videos/+video-watch/video-watch.component.ts
client/src/assets/player/bezels/bezels-plugin.ts [new file with mode: 0644]
client/src/assets/player/peertube-player-manager.ts
client/src/sass/player/bezels.scss [new file with mode: 0644]
client/src/sass/player/index.scss
client/src/sass/player/upnext.scss

index 835e9e34a9cc6d5f9168f087d74e47a4c4ac3b05..9eae45fed912fab777c77595c04614a5347f6be7 100644 (file)
@@ -469,6 +469,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
     this.zone.runOutsideAngular(async () => {
       this.player = await PeertubePlayerManager.initialize(playerMode, playerOptions, player => this.player = player)
       this.player.focus()
+      this.player.bezels()
 
       this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))
 
diff --git a/client/src/assets/player/bezels/bezels-plugin.ts b/client/src/assets/player/bezels/bezels-plugin.ts
new file mode 100644 (file)
index 0000000..4317d60
--- /dev/null
@@ -0,0 +1,93 @@
+// @ts-ignore
+import * as videojs from 'video.js'
+import { VideoJSComponentInterface } from '../peertube-videojs-typings'
+
+function getPauseBezel () {
+  return `
+  <div class="vjs-bezels-pause">
+    <div class="vjs-bezel" role="status" aria-label="Pause">
+      <div class="vjs-bezel-icon">
+        <svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%">
+          <use class="vjs-svg-shadow" xlink:href="#vjs-id-1"></use>
+          <path class="vjs-svg-fill" d="M 12,26 16,26 16,10 12,10 z M 21,26 25,26 25,10 21,10 z" id="vjs-id-1"></path>
+        </svg>
+      </div>
+    </div>
+  </div>
+  `
+}
+
+function getPlayBezel () {
+  return `
+  <div class="vjs-bezels-play">
+    <div class="vjs-bezel" role="status" aria-label="Play">
+      <div class="vjs-bezel-icon">
+        <svg height="100%" version="1.1" viewBox="0 0 36 36" width="100%">
+          <use class="vjs-svg-shadow" xlink:href="#vjs-id-2"></use>
+          <path class="vjs-svg-fill" d="M 12,26 18.5,22 18.5,14 12,10 z M 18.5,22 25,18 25,18 18.5,14 z" id="ytp-id-2"></path>
+        </svg>
+      </div>
+    </div>
+  </div>
+  `
+}
+
+// @ts-ignore-start
+const Component = videojs.getComponent('Component')
+class PauseBezel extends Component {
+  options_: any
+  container: HTMLBodyElement
+
+  constructor (player: videojs.Player, options: any) {
+    super(player, options)
+    this.options_ = options
+
+    player.on('pause', (_: any) => {
+      if (player.seeking()) return
+      this.container.innerHTML = getPauseBezel()
+      this.showBezel()
+    })
+
+    player.on('play', (_: any) => {
+      if (player.seeking()) return
+      this.container.innerHTML = getPlayBezel()
+      this.showBezel()
+    })
+  }
+
+  createEl () {
+    const container = super.createEl('div', {
+      className: 'vjs-bezels-content'
+    })
+    this.container = container
+    container.style.display = 'none'
+
+    return container
+  }
+
+  showBezel () {
+    this.container.style.display = 'inherit'
+    setTimeout(() => {
+      this.container.style.display = 'none'
+    }, 500) // matching the animation duration
+  }
+}
+// @ts-ignore-end
+
+videojs.registerComponent('PauseBezel', PauseBezel)
+
+const Plugin: VideoJSComponentInterface = videojs.getPlugin('plugin')
+class BezelsPlugin extends Plugin {
+  constructor (player: videojs.Player, options: any = {}) {
+    super(player, options)
+
+    this.player.ready(() => {
+      player.addClass('vjs-bezels')
+    })
+
+    player.addChild('PauseBezel', options)
+  }
+}
+
+videojs.registerPlugin('bezels', BezelsPlugin)
+export { BezelsPlugin }
index b1551185a55b2c3431ac992a87b091caa6d10880..ac3609c04cef1e1fede4fb14a4f2367b9f272b5e 100644 (file)
@@ -6,6 +6,7 @@ import 'videojs-dock'
 import 'videojs-contextmenu-ui'
 import 'videojs-contrib-quality-levels'
 import './upnext/upnext-plugin'
+import './bezels/bezels-plugin'
 import './peertube-plugin'
 import './videojs-components/peertube-link-button'
 import './videojs-components/resolution-menu-button'
diff --git a/client/src/sass/player/bezels.scss b/client/src/sass/player/bezels.scss
new file mode 100644 (file)
index 0000000..f1b1dcb
--- /dev/null
@@ -0,0 +1,42 @@
+@keyframes bezels-fadeout {
+  from {
+    opacity: 1;
+  }
+  to {
+    opacity: 0;
+    transform: scale(2);
+  }
+}
+
+.vjs-bezel {
+       position: absolute;
+       left: 50%;
+       top: 50%;
+       width: 52px;
+       height: 52px;
+       z-index: 19;
+       margin-left: -26px;
+       margin-top: -26px;
+       background: rgba(0,0,0,.5);
+       border-radius: 26px;
+       animation: bezels-fadeout .5s linear 1 normal forwards;
+  pointer-events: none;
+}
+
+.vjs-bezel-icon {
+       width: 36px;
+       height: 36px;
+  margin: 8px;
+  
+  svg .vjs-svg-fill {
+    fill: #fff;
+  }
+}
+
+.video-js {
+
+  .vjs-bezel-content {
+
+  }
+
+}
\ No newline at end of file
index 886a7653600aa41120e060fa178617e075faa28a..58ce3ac96874e0d6816a1319dfe4e63c54af7e1a 100644 (file)
@@ -3,4 +3,5 @@
 @import './context-menu';
 @import './settings-menu';
 @import './spinner';
-@import './upnext';
\ No newline at end of file
+@import './upnext';
+@import './bezels.scss';
\ No newline at end of file
index ecce22aa80a63674facc15cfc00c2e2cb5f077a1..f1f2e0fe24e6866544b98ce08c5a1d38fd2d84ae 100644 (file)
@@ -95,8 +95,9 @@ $browser-context: 16;
     width: 98px;
     height: 98px;
     margin: -49px 0 0 -49px;
-    transition: stroke-dasharray 0.1s cubic-bezier(0.4,0,1,1);
     cursor: pointer;
+
+    @include transition(stroke-dasharray 0.1s cubic-bezier(0.4,0,1,1));
   }
 
 }