From b78e256f6c0f3b9b92d27fc22a20de465e84f131 Mon Sep 17 00:00:00 2001 From: Wensheng Yan Date: Thu, 29 Jun 2017 01:30:43 -0400 Subject: [PATCH] let hotspot also work on VR Mode. --- src/scripts/Components/Marker.js | 37 ++++--------- src/scripts/Components/MarkerContainer.js | 66 +++++++++++++++++++++++ src/scripts/Components/MarkerGroup.js | 50 ++++++++++++++--- src/scripts/Components/TwoDVideo.js | 20 +++---- src/scripts/Panorama.js | 24 +++------ src/styles/plugin.scss | 31 +++++++++++ 6 files changed, 169 insertions(+), 59 deletions(-) create mode 100644 src/scripts/Components/MarkerContainer.js diff --git a/src/scripts/Components/Marker.js b/src/scripts/Components/Marker.js index 243182e..553f870 100644 --- a/src/scripts/Components/Marker.js +++ b/src/scripts/Components/Marker.js @@ -3,6 +3,7 @@ import type { Player, MarkerSettings, Point } from '../types'; import THREE from "three"; import Component from './Component'; +import BaseCanvas from './BaseCanvas'; import { mergeOptions } from '../utils'; const defaults = { @@ -11,7 +12,6 @@ const defaults = { }; class Marker extends Component{ - _canvas: Component; _position: THREE.Vector3; _enable: boolean; @@ -35,7 +35,6 @@ class Marker extends Component{ super(player, options); this._options = mergeOptions({}, defaults, options); - this._canvas = player.getComponent("VideoCanvas"); let phi = THREE.Math.degToRad( 90 - options.location.lat ); let theta = THREE.Math.degToRad( options.location.lon ); this._position = new THREE.Vector3( @@ -43,46 +42,32 @@ class Marker extends Component{ options.radius * Math.cos( phi ), options.radius * Math.sin( phi ) * Math.sin( theta ), ); - if(this.options.keyPoint > 0){ - let timeupdate; - this.player.on("timeupdate", timeupdate = () => { - let currentTime = this.player.getVideoEl().currentTime * 1000; - if(this.options.duration > 0){ - (this.options.keyPoint <= currentTime && currentTime < this.options.keyPoint + this.options.duration)? - !this._enable && this.attachEvents() : this._enable && this.detachEvents(); - }else{ - (this.options.keyPoint <= currentTime)? - !this._enable && this.attachEvents() : this._enable && this.detachEvents(); - } - }); - }else{ - this.attachEvents(); + if(this.options.keyPoint < 0){ + this.enableMarker(); } - } - attachEvents(){ + enableMarker(){ this._enable = true; this.addClass("vjs-marker--enable"); - this._canvas.addListener("render", this.render.bind(this)); } - detachEvents(){ + disableMarker(){ this._enable = false; this.removeClass("vjs-marker--enable"); - this._canvas.removeListener("render", this.render.bind(this)); } - render(){ - let angle = this._position.angleTo(this._canvas._camera.target); + render(canvas: BaseCanvas, camera: THREE.PerspectiveCamera){ + let angle = this._position.angleTo(camera.target); if(angle > Math.PI * 0.4){ this.addClass("vjs-marker--backside"); }else{ this.removeClass("vjs-marker--backside"); - let vector = this._position.clone().project(this._canvas._camera); + let vector = this._position.clone().project(camera); + let width = canvas.VRMode? canvas._width / 2: canvas._width; let point: Point = { - x: (vector.x + 1) / 2 * this._canvas._width, - y: - (vector.y - 1) / 2 * this._canvas._height + x: (vector.x + 1) / 2 * width, + y: - (vector.y - 1) / 2 * canvas._height }; this.el().style.left = `${point.x}px`; this.el().style.top = `${point.y}px`; diff --git a/src/scripts/Components/MarkerContainer.js b/src/scripts/Components/MarkerContainer.js new file mode 100644 index 0000000..bdf4a1d --- /dev/null +++ b/src/scripts/Components/MarkerContainer.js @@ -0,0 +1,66 @@ +// @flow + +import BaseCanvas from './BaseCanvas'; +import Component from './Component'; +import MarkerGroup from './MarkerGroup'; +import type { Player, MarkerSettings } from '../types'; + +class MarkerContainer extends Component{ + _canvas: BaseCanvas; + + constructor(player: Player, options: { + canvas: BaseCanvas; + markers: MarkerSettings[]; + VREnable: boolean; + }){ + super(player, options); + this.el().classList.add("vjs-marker-container"); + this._canvas = this.options.canvas; + + if(this.options.VREnable){ + let leftMarkerGroup = new MarkerGroup(this.player, { + id: "left_group", + canvas: this._canvas, + markers: this.options.markers, + camera: this._canvas._camera + }); + let rightMarkerGroup = new MarkerGroup(this.player, { + id: "right_group", + canvas: this._canvas, + markers: this.options.markers, + camera: this._canvas._camera + }); + this.addChild("leftMarkerGroup", leftMarkerGroup); + this.addChild("rightMarkerGroup", rightMarkerGroup); + + leftMarkerGroup.attachEvents(); + if(this._canvas.VRMode){ + rightMarkerGroup.attachEvents(); + } + + this.player.on("VRModeOn", ()=>{ + this.el().classList.add("vjs-marker-container--VREnable"); + leftMarkerGroup.camera = this._canvas._cameraL; + rightMarkerGroup.camera = this._canvas._cameraR; + rightMarkerGroup.attachEvents(); + }); + + this.player.on("VRModeOff", ()=>{ + this.el().classList.remove("vjs-marker-container--VREnable"); + leftMarkerGroup.camera = this._canvas._camera; + rightMarkerGroup.detachEvents(); + }); + }else{ + let markerGroup = new MarkerGroup(this.player, { + id: "group", + canvas: this._canvas, + markers: this.options.Markers, + camera: this._canvas._camera + }); + this.addChild("markerGroup", markerGroup); + markerGroup.attachEvents(); + } + } +} + +export default MarkerContainer; diff --git a/src/scripts/Components/MarkerGroup.js b/src/scripts/Components/MarkerGroup.js index 652676d..c78fe32 100644 --- a/src/scripts/Components/MarkerGroup.js +++ b/src/scripts/Components/MarkerGroup.js @@ -3,20 +3,28 @@ import THREE from "three"; import type { Player, MarkerSettings } from '../types'; import Component from './Component'; +import BaseCanvas from './BaseCanvas'; import Marker from './Marker'; class MarkerGroup extends Component{ + //save total markers enable to generate marker id _totalMarkers: number; - _markers: Marker; + _markers: Marker[]; _camera: THREE.PerspectiveCamera; + _canvas: BaseCanvas; constructor(player: Player, options: { id: string; - markers: MarkerSettings[] + markers: MarkerSettings[], + canvas: BaseCanvas, + camera: THREE.PerspectiveCamera }){ super(player, options); this._totalMarkers = 0; - this.el().classList.add("vjs-markergroup"); + this._markers = []; + this._camera = options.camera; + this.el().classList.add("vjs-marker-group"); + this._canvas = options.canvas; this.options.markers.forEach((markSetting)=>{ this.addMarker(markSetting); @@ -24,27 +32,57 @@ class MarkerGroup extends Component{ } attachEvents(){ + this.el().classList.add("vjs-marker-group--enable"); + this.player.on("timeupdate", this.updateMarkers.bind(this)); + this._canvas.addListener("render", this.renderMarkers.bind(this)); + } + detachEvents(){ + this.el().classList.remove("vjs-marker-group--enable"); + this.player.off("timeupdate", this.updateMarkers.bind(this)); + this._canvas.removeListener("render", this.renderMarkers.bind(this)); } addMarker(markSetting: any): Marker{ this._totalMarkers++; - markSetting.id= (markSetting.id? markSetting.id : `marker_${this._totalMarkers}`) + `_${this.options.id}`; + markSetting.id= `${this.options.id}_` + (markSetting.id? markSetting.id : `marker_${this._totalMarkers}`); let marker = new Marker(this.player, markSetting); this.addChild(markSetting.id, marker); this._markers.push(marker); return marker; } + removeMarker(markerId: string): void{ + this.removeChild(markerId); + } + updateMarkers(){ let currentTime = this.player.getVideoEl().currentTime * 1000; this._markers.forEach((marker)=>{ - if(marker.options.duration > 0){ - + //only check keypoint greater and equal zero + if(marker.options.keyPoint >= 0){ + if(marker.options.duration > 0){ + (marker.options.keyPoint <= currentTime && currentTime < marker.options.keyPoint + marker.options.duration)? + !marker.enable && marker.enableMarker() : marker.enable && marker.disableMarker(); + }else{ + (marker.options.keyPoint <= currentTime)? + !marker.enable && marker.enableMarker() : marker.enable && marker.disableMarker(); + } } + }); + } + renderMarkers(){ + this._markers.forEach((marker)=>{ + if(marker.enable){ + marker.render(this._canvas, this._camera); + } }); } + + set camera(camera: THREE.PerspectiveCamera){ + this._camera = camera; + } } export default MarkerGroup; \ No newline at end of file diff --git a/src/scripts/Components/TwoDVideo.js b/src/scripts/Components/TwoDVideo.js index dc6a9e0..bb6b8ee 100644 --- a/src/scripts/Components/TwoDVideo.js +++ b/src/scripts/Components/TwoDVideo.js @@ -37,6 +37,8 @@ class TwoDVideo extends BaseCanvas{ this._cameraL = new THREE.PerspectiveCamera(this._camera.fov, this._width / 2 / this._height, 1, 2000); this._cameraR = new THREE.PerspectiveCamera(this._camera.fov, this._width / 2 / this._height, 1, 2000); + this._cameraL.target = new THREE.Vector3( 0, 0, 0 ); + this._cameraR.target = new THREE.Vector3( 0, 0, 0 ); } disableVR(){ @@ -115,16 +117,16 @@ class TwoDVideo extends BaseCanvas{ let thetaL = THREE.Math.degToRad( lonL ); let thetaR = THREE.Math.degToRad( lonR ); - //deep copy target value - let targetL = mergeOptions({}, this._camera.target); - targetL.x = 500 * Math.sin( this._phi ) * Math.cos( thetaL ); - targetL.z = 500 * Math.sin( this._phi ) * Math.sin( thetaL ); - this._cameraL.lookAt(targetL); - let targetR = mergeOptions({}, this._camera.target); - targetR.x = 500 * Math.sin( this._phi ) * Math.cos( thetaR ); - targetR.z = 500 * Math.sin( this._phi ) * Math.sin( thetaR ); - this._cameraR.lookAt(targetR); + this._cameraL.target.x = 500 * Math.sin( this._phi ) * Math.cos( thetaL ); + this._cameraL.target.y = this._camera.target.y; + this._cameraL.target.z = 500 * Math.sin( this._phi ) * Math.sin( thetaL ); + this._cameraL.lookAt(this._cameraL.target); + + this._cameraR.target.x = 500 * Math.sin( this._phi ) * Math.cos( thetaR ); + this._cameraR.target.y = this._camera.target.y; + this._cameraR.target.z = 500 * Math.sin( this._phi ) * Math.sin( thetaR ); + this._cameraR.lookAt(this._cameraR.target); } // render left eye this._renderer.setViewport( 0, 0, viewPortWidth, viewPortHeight ); diff --git a/src/scripts/Panorama.js b/src/scripts/Panorama.js index eda5a0a..0e6c994 100644 --- a/src/scripts/Panorama.js +++ b/src/scripts/Panorama.js @@ -11,7 +11,7 @@ import ThreeDVideo from './Components/ThreeDVideo'; import Notification from './Components/Notification'; import Thumbnail from './Components/Thumbnail'; import VRButton from './Components/VRButton'; -import Marker from './Components/Marker'; +import MarkerContainer from './Components/MarkerContainer'; import { Detector, webGLErrorMessage, crossDomainWarning, transitionEvent, mergeOptions, mobileAndTabletcheck, isIos, isRealIphone, warning } from './utils'; const runOnMobile = mobileAndTabletcheck(); @@ -107,8 +107,6 @@ class Panorama extends EventEmitter{ _player: Player; _videoCanvas: BaseCanvas; _thumbnailCanvas: BaseCanvas | null; - //save total markers enable to generate marker id - _totalMarkers: number; /** * check legacy option settings and produce warning message if user use legacy options, automatically set it to new options. @@ -214,7 +212,6 @@ class Panorama extends EventEmitter{ Panorama.checkOptions(options); this._options = mergeOptions({}, defaults, options); this._player = player; - this._totalMarkers = 0; this.player.addClass("vjs-panorama"); @@ -319,9 +316,12 @@ class Panorama extends EventEmitter{ //initial markers if(this.options.Markers){ - this.options.Markers.forEach((markSetting: any)=>{ - this.addMarker(markSetting); + let markerContainer = new MarkerContainer(this.player, { + canvas: this.videoCanvas, + markers: this.options.Markers, + VREnable: this.options.VREnable }); + this.player.addComponent("markerContainer", markerContainer); } //detect black screen @@ -388,18 +388,6 @@ class Panorama extends EventEmitter{ } } - addMarker(markSetting: any): Marker{ - this._totalMarkers++; - markSetting.id = markSetting.id? markSetting.id : `marker_${this._totalMarkers}`; - let marker = new Marker(this.player, markSetting); - this.player.addComponent(markSetting.id, marker); - return marker; - } - - removeMarker(markerId: string): void{ - this.player.removeComponent(markerId); - } - get thumbnailCanvas(): BaseCanvas | null{ return this._thumbnailCanvas; } diff --git a/src/styles/plugin.scss b/src/styles/plugin.scss index 42c7795..362ac46 100644 --- a/src/styles/plugin.scss +++ b/src/styles/plugin.scss @@ -132,12 +132,43 @@ -webkit-animation-delay: 0.44s; animation-delay: 0.44s; } + .vjs-marker-container{ + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: flex; + align-items: stretch; + align-content: stretch; + pointer-events: none; + + .vjs-marker-group{ + display: none; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; + + &.vjs-marker-group--enable{ + display: block; + } + + &.vjs-marker-container--VREnable{ + width: 50%; + } + } + + + } + .vjs-marker{ position: absolute; display: none; &.vjs-marker--enable{ display: block!important; + pointer-events: auto; } &.vjs-marker--backside{