From 21b66cadd728c46be2596884c8e90b62f63473ff Mon Sep 17 00:00:00 2001 From: Brandon Casey Date: Fri, 8 Jun 2018 10:58:20 -0400 Subject: [PATCH] fix: hide control bar while moving, allow clicking to play/pause, allow right click (#96) --- scripts/rollup-replace.js | 5 ++ src/canvas-player-controls.js | 115 ++++++++++++++++++++++++++++++++++ src/plugin.js | 8 +++ 3 files changed, 128 insertions(+) create mode 100644 src/canvas-player-controls.js diff --git a/scripts/rollup-replace.js b/scripts/rollup-replace.js index 421224f5..7ec25aee 100644 --- a/scripts/rollup-replace.js +++ b/scripts/rollup-replace.js @@ -39,6 +39,11 @@ export default function(options) { code = globalReplace(code, 'rotateLeft', 'scope.rotateLeft'); code = globalReplace(code, 'rotateUp', 'scope.rotateUp'); + // comment out the context menu prevent default line... + code = globalReplace(code, + "scope.domElement.addEventListener\\( 'contextmenu'", + "\/\/scope.domElement.addEventListener\\( 'contextmenu'" + ); } }); return code; diff --git a/src/canvas-player-controls.js b/src/canvas-player-controls.js new file mode 100644 index 00000000..6d0e9886 --- /dev/null +++ b/src/canvas-player-controls.js @@ -0,0 +1,115 @@ +import videojs from 'video.js'; +/** + * This class reacts to interactions with the canvas and + * triggers appropriate functionality on the player. Right now + * it does two things: + * + * 1. A `mousedown`/`touchstart` followed by `touchend`/`mouseup` without any + * `touchmove` or `mousemove` toggles play/pause on the player + * 2. Only moving on/clicking the control bar or toggling play/pause should + * show the control bar. Moving around the scene in the canvas should not. + */ +class CanvasPlayerControls extends videojs.EventTarget { + constructor(player, canvas) { + super(); + + this.player = player; + this.canvas = canvas; + + this.onMoveEnd = videojs.bind(this, this.onMoveEnd); + this.onMoveStart = videojs.bind(this, this.onMoveStart); + this.onMove = videojs.bind(this, this.onMove); + this.onControlBarMove = videojs.bind(this, this.onControlBarMove); + + this.player.controlBar.on([ + 'mousedown', + 'mousemove', + 'mouseup', + 'touchstart', + 'touchmove', + 'touchend' + ], this.onControlBarMove); + + // we have to override these here because + // video.js listens for user activity on the video element + // and makes the user active when the mouse moves. + // We don't want that for 3d videos + this.oldReportUserActivity = this.player.reportUserActivity; + this.player.reportUserActivity = () => {}; + + // canvas movements + this.canvas.addEventListener('mousedown', this.onMoveStart); + this.canvas.addEventListener('touchstart', this.onMoveStart); + this.canvas.addEventListener('mousemove', this.onMove); + this.canvas.addEventListener('touchmove', this.onMove); + this.canvas.addEventListener('mouseup', this.onMoveEnd); + this.canvas.addEventListener('touchend', this.onMoveEnd); + + this.shouldTogglePlay = false; + } + + togglePlay() { + if (this.player.paused()) { + this.player.play(); + } else { + this.player.pause(); + } + } + + onMoveStart(e) { + + // if the player does not have a controlbar or + // the move was a mouse click but not left click do not + // toggle play. + if (!this.player.controls() || (e.type === 'mousedown' && !videojs.dom.isSingleLeftClick(e))) { + this.shouldTogglePlay = false; + return; + } + + this.shouldTogglePlay = true; + this.touchMoveCount_ = 0; + } + + onMoveEnd(e) { + if (!this.shouldTogglePlay) { + return; + } + this.togglePlay(); + } + + onMove(e) { + // its hard to tap without a touchmove, if there have been less + // than one, we should still toggle play + if (e.type === 'touchmove' && this.touchMoveCount_ < 1) { + this.touchMoveCount_++; + return; + } + this.shouldTogglePlay = false; + } + + onControlBarMove(e) { + this.player.userActive(true); + } + + dispose() { + this.canvas.removeEventListener('mousedown', this.onMoveStart); + this.canvas.removeEventListener('touchstart', this.onMoveStart); + this.canvas.removeEventListener('mousemove', this.onMove); + this.canvas.removeEventListener('touchmove', this.onMove); + this.canvas.removeEventListener('mouseup', this.onMoveEnd); + this.canvas.removeEventListener('touchend', this.onMoveEnd); + + this.player.controlBar.off([ + 'mousedown', + 'mousemove', + 'mouseup', + 'touchstart', + 'touchmove', + 'touchend' + ], this.onControlBarMove); + + this.player.reportUserActivity = this.oldReportUserActivity; + } +} + +export default CanvasPlayerControls; diff --git a/src/plugin.js b/src/plugin.js index 7b75fb70..3f10f62b 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -8,6 +8,7 @@ import VRControls from 'three/examples/js/controls/VRControls.js'; import VREffect from 'three/examples/js/effects/VREffect.js'; import OrbitOrientationContols from './orbit-orientation-controls.js'; import * as utils from './utils'; +import CanvasPlayerControls from './canvas-player-controls'; // import controls so they get regisetered with videojs import './cardboard-button'; @@ -497,7 +498,9 @@ class VR extends Plugin { canvas: this.renderedCanvas, orientation: videojs.browser.IS_IOS || videojs.browser.IS_ANDROID || false }); + this.canvasPlayerControls = new CanvasPlayerControls(this.player_, this.renderedCanvas); } + this.animationFrameId_ = this.requestAnimationFrame(this.animate_); }); } else if (window.navigator.getVRDevices) { @@ -533,6 +536,11 @@ class VR extends Plugin { if (this.controls3d) { this.controls3d.dispose(); } + + if (this.canvasPlayerControls) { + this.canvasPlayerControls.dispose(); + } + if (this.effect) { this.effect.dispose(); }