From 8ace4ad19253ffa16064fc6f842a57a672e74c29 Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Thu, 31 May 2018 15:58:20 -0400 Subject: [PATCH 1/2] fix: player controls --- scripts/rollup-replace.js | 5 ++ src/canvas-player-controls.js | 131 ++++++++++++++++++++++++++++++++++ src/plugin.js | 8 +++ 3 files changed, 144 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..ea14f02d --- /dev/null +++ b/src/canvas-player-controls.js @@ -0,0 +1,131 @@ +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.controlBarMove = videojs.bind(this, this.controlBarMove); + + // 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.player.controlBar.on([ + 'mousedown', + 'mousemove', + 'mouseup', + 'touchstart', + 'touchmove', + 'touchend' + ], this.controlBarMove); + + this.shouldTogglePlay = false; + + this.oldUserActive_ = this.player.userActive; + this.player.userActive = (v) => { + if (typeof v === 'undefined') { + return this.oldUserActive_.call(this.player); + } + + if (v !== this.userActive_) { + return; + } + + return this.oldUserActive_.call(this.player, v); + }; + } + + userActive(v) { + this.userActive_ = v; + this.player.userActive(v); + } + + togglePlay() { + if (this.player.paused()) { + this.player.play(); + } else { + this.player.pause(); + } + } + + onMoveStart(e) { + this.userActive(false); + + // if the player does not have a controlbar do no toggle play + if (!this.player.controls()) { + this.shouldTogglePlay = false; + return; + } + + // if the move start was a mouse click but not left click + // do not toggle play + if (e.type === 'mousedown' && !videojs.dom.isSingleLeftClick(e)) { + this.shouldTogglePlay = false; + return; + } + + this.shouldTogglePlay = true; + } + + onMoveEnd(e) { + if (!this.shouldTogglePlay) { + this.userActive_ = false; + this.userActive(false); + return; + } + this.userActive(true); + this.togglePlay(); + } + + onMove(e) { + this.shouldTogglePlay = false; + this.userActive(false); + } + + controlBarMove(e) { + this.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.controlBarMove); + + this.player.userActive = this.oldUserActive_; + } +} + +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(); } From a7b6be12303345625ac68fe4ad901310dffcde30 Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Wed, 6 Jun 2018 11:20:45 -0400 Subject: [PATCH 2/2] better user activity blocking --- src/canvas-player-controls.js | 78 ++++++++++++++--------------------- 1 file changed, 31 insertions(+), 47 deletions(-) diff --git a/src/canvas-player-controls.js b/src/canvas-player-controls.js index ea14f02d..6d0e9886 100644 --- a/src/canvas-player-controls.js +++ b/src/canvas-player-controls.js @@ -8,8 +8,6 @@ import videojs from 'video.js'; * `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) { @@ -21,15 +19,7 @@ class CanvasPlayerControls extends videojs.EventTarget { this.onMoveEnd = videojs.bind(this, this.onMoveEnd); this.onMoveStart = videojs.bind(this, this.onMoveStart); this.onMove = videojs.bind(this, this.onMove); - this.controlBarMove = videojs.bind(this, this.controlBarMove); - - // 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.onControlBarMove = videojs.bind(this, this.onControlBarMove); this.player.controlBar.on([ 'mousedown', @@ -38,27 +28,24 @@ class CanvasPlayerControls extends videojs.EventTarget { 'touchstart', 'touchmove', 'touchend' - ], this.controlBarMove); + ], this.onControlBarMove); - this.shouldTogglePlay = false; + // 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 = () => {}; - this.oldUserActive_ = this.player.userActive; - this.player.userActive = (v) => { - if (typeof v === 'undefined') { - return this.oldUserActive_.call(this.player); - } - - if (v !== this.userActive_) { - return; - } - - return this.oldUserActive_.call(this.player, v); - }; - } + // 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); - userActive(v) { - this.userActive_ = v; - this.player.userActive(v); + this.shouldTogglePlay = false; } togglePlay() { @@ -70,41 +57,38 @@ class CanvasPlayerControls extends videojs.EventTarget { } onMoveStart(e) { - this.userActive(false); - // if the player does not have a controlbar do no toggle play - if (!this.player.controls()) { - this.shouldTogglePlay = false; - return; - } - - // if the move start was a mouse click but not left click - // do not toggle play - if (e.type === 'mousedown' && !videojs.dom.isSingleLeftClick(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) { - this.userActive_ = false; - this.userActive(false); return; } - this.userActive(true); 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; - this.userActive(false); } - controlBarMove(e) { - this.userActive(true); + onControlBarMove(e) { + this.player.userActive(true); } dispose() { @@ -122,9 +106,9 @@ class CanvasPlayerControls extends videojs.EventTarget { 'touchstart', 'touchmove', 'touchend' - ], this.controlBarMove); + ], this.onControlBarMove); - this.player.userActive = this.oldUserActive_; + this.player.reportUserActivity = this.oldReportUserActivity; } }