From 1083b59247057754800d79d6b8bbbad4742b160e Mon Sep 17 00:00:00 2001 From: Pierre Hourdille Date: Sun, 25 Mar 2018 13:30:06 +0200 Subject: [PATCH 01/11] Resolve: unable to scroll content panel on mobile device (#119) --- src/js/buttons/PSVNavBarZoomButton.js | 2 -- src/js/components/PSVPanel.js | 1 - 2 files changed, 3 deletions(-) diff --git a/src/js/buttons/PSVNavBarZoomButton.js b/src/js/buttons/PSVNavBarZoomButton.js index 092b7b7c4..ad8cd7f38 100644 --- a/src/js/buttons/PSVNavBarZoomButton.js +++ b/src/js/buttons/PSVNavBarZoomButton.js @@ -245,8 +245,6 @@ PSVNavBarZoomButton.prototype._changeZoomByTouch = function(evt) { if (!this.enabled) { return; } - - evt.preventDefault(); this._changeZoom(evt.changedTouches[0].clientX); }; diff --git a/src/js/components/PSVPanel.js b/src/js/components/PSVPanel.js index 22d6344a3..48d0be8dd 100644 --- a/src/js/components/PSVPanel.js +++ b/src/js/components/PSVPanel.js @@ -194,7 +194,6 @@ PSVPanel.prototype._onMouseMove = function(evt) { */ PSVPanel.prototype._onTouchMove = function(evt) { if (this.prop.mousedown) { - evt.stopPropagation(); this._resize(evt.touches[0]); } }; From 69488b2104f9ec59ade75482cf77ad889dc34d1b Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 25 Mar 2018 13:44:14 +0200 Subject: [PATCH 02/11] Fix blurry loader on high DPI, remove old reference to composer --- src/js/PhotoSphereViewer.events.js | 3 --- src/js/PhotoSphereViewer.public.js | 8 +------- src/js/components/PSVLoader.js | 10 ++++++---- src/scss/loader.scss | 2 ++ 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/src/js/PhotoSphereViewer.events.js b/src/js/PhotoSphereViewer.events.js index 645289482..4eceecc60 100644 --- a/src/js/PhotoSphereViewer.events.js +++ b/src/js/PhotoSphereViewer.events.js @@ -68,9 +68,6 @@ PhotoSphereViewer.prototype._onResize = function() { if (this.renderer) { this.renderer.setSize(this.prop.size.width, this.prop.size.height); - if (this.composer) { - this.composer.reset(new THREE.WebGLRenderTarget(this.prop.size.width, this.prop.size.height)); - } this.render(); } diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index b355a6ec0..148f60cf7 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -86,12 +86,7 @@ PhotoSphereViewer.prototype.render = function(updateDirection) { this.camera.fov = this.prop.vFov; this.camera.updateProjectionMatrix(); - if (this.composer) { - this.composer.render(); - } - else { - this.renderer.render(this.scene, this.camera); - } + this.renderer.render(this.scene, this.camera); /** * @event render @@ -164,7 +159,6 @@ PhotoSphereViewer.prototype.destroy = function() { delete this.tooltip; delete this.canvas_container; delete this.renderer; - delete this.composer; delete this.scene; delete this.camera; delete this.mesh; diff --git a/src/js/components/PSVLoader.js b/src/js/components/PSVLoader.js index 0931751ad..a6587b89a 100644 --- a/src/js/components/PSVLoader.js +++ b/src/js/components/PSVLoader.js @@ -38,6 +38,8 @@ PSVLoader.className = 'psv-loader-container'; PSVLoader.prototype.create = function() { PSVComponent.prototype.create.call(this); + var pixelRatio = PhotoSphereViewer.SYSTEM.pixelRatio; + this.loader = document.createElement('div'); this.loader.className = 'psv-loader'; this.container.appendChild(this.loader); @@ -45,11 +47,11 @@ PSVLoader.prototype.create = function() { this.canvas = document.createElement('canvas'); this.canvas.className = 'psv-loader-canvas'; - this.canvas.width = this.loader.clientWidth; - this.canvas.height = this.loader.clientWidth; + this.canvas.width = this.loader.clientWidth * pixelRatio; + this.canvas.height = this.loader.clientWidth * pixelRatio; this.loader.appendChild(this.canvas); - this.tickness = (this.loader.offsetWidth - this.loader.clientWidth) / 2; + this.tickness = (this.loader.offsetWidth - this.loader.clientWidth) / 2 * pixelRatio; var inner; if (this.psv.config.loading_img) { @@ -63,7 +65,7 @@ PSVLoader.prototype.create = function() { inner.innerHTML = this.psv.config.loading_txt; } if (inner) { - var a = Math.round(Math.sqrt(2 * Math.pow(this.canvas.width / 2 - this.tickness / 2, 2))); + var a = Math.round(Math.sqrt(2 * Math.pow((this.canvas.width / 2 - this.tickness / 2) / pixelRatio, 2))); inner.style.maxWidth = a + 'px'; inner.style.maxHeight = a + 'px'; this.loader.appendChild(inner); diff --git a/src/scss/loader.scss b/src/scss/loader.scss index fd5aa4920..110d7a0da 100644 --- a/src/scss/loader.scss +++ b/src/scss/loader.scss @@ -37,6 +37,8 @@ position: absolute; top: 0; left: 0; + width: 100%; + height: 100%; } &-text { From 155f0d0de3487140aecff84e1d8bde1f2fdb796b Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 25 Mar 2018 15:14:42 +0200 Subject: [PATCH 03/11] Close #105 Fix #100 Improve gyroscope controls - allow to move horizontally - keep start position --- src/js/PhotoSphereViewer.events.js | 32 +++++++++++++------------ src/js/PhotoSphereViewer.js | 2 ++ src/js/PhotoSphereViewer.public.js | 38 ++++++++++++++++++++---------- 3 files changed, 44 insertions(+), 28 deletions(-) diff --git a/src/js/PhotoSphereViewer.events.js b/src/js/PhotoSphereViewer.events.js index 4eceecc60..fe70a8431 100644 --- a/src/js/PhotoSphereViewer.events.js +++ b/src/js/PhotoSphereViewer.events.js @@ -190,11 +190,8 @@ PhotoSphereViewer.prototype._onTouchMove = function(evt) { * @private */ PhotoSphereViewer.prototype._startMove = function(evt) { - if (this.isGyroscopeEnabled()) { - return; - } - - this._stopAll(); + this.stopAutorotate(); + this.stopAnimation(); this.prop.mouse_x = this.prop.start_mouse_x = parseInt(evt.clientX); this.prop.mouse_y = this.prop.start_mouse_y = parseInt(evt.clientY); @@ -232,11 +229,6 @@ PhotoSphereViewer.prototype._stopMove = function(evt) { return; } - if (this.isGyroscopeEnabled()) { - this._click(evt); - return; - } - if (this.prop.moving) { // move threshold to trigger a click if (Math.abs(evt.clientX - this.prop.start_mouse_x) < PhotoSphereViewer.MOVE_THRESHOLD && Math.abs(evt.clientY - this.prop.start_mouse_y) < PhotoSphereViewer.MOVE_THRESHOLD) { @@ -244,7 +236,7 @@ PhotoSphereViewer.prototype._stopMove = function(evt) { this.prop.moving = false; } // inertia animation - else if (this.config.move_inertia) { + else if (this.config.move_inertia && !this.isGyroscopeEnabled()) { this._logMouseMove(evt); this._stopMoveInertia(evt); } @@ -366,10 +358,20 @@ PhotoSphereViewer.prototype._move = function(evt, log) { var x = parseInt(evt.clientX); var y = parseInt(evt.clientY); - this.rotate({ - longitude: this.prop.longitude - (x - this.prop.mouse_x) / this.prop.size.width * this.prop.move_speed * this.prop.hFov, - latitude: this.prop.latitude + (y - this.prop.mouse_y) / this.prop.size.height * this.prop.move_speed * this.prop.vFov - }); + var rotation = { + longitude: (x - this.prop.mouse_x) / this.prop.size.width * this.prop.move_speed * this.prop.hFov * PhotoSphereViewer.SYSTEM.pixelRatio, + latitude: (y - this.prop.mouse_y) / this.prop.size.height * this.prop.move_speed * this.prop.vFov * PhotoSphereViewer.SYSTEM.pixelRatio + }; + + if (this.isGyroscopeEnabled()) { + this.prop.gyro_alpha_offset += rotation.longitude; + } + else { + this.rotate({ + longitude: this.prop.longitude - rotation.longitude, + latitude: this.prop.latitude + rotation.latitude + }); + } this.prop.mouse_x = x; this.prop.mouse_y = y; diff --git a/src/js/PhotoSphereViewer.js b/src/js/PhotoSphereViewer.js index 84b1130a5..da164dbd3 100644 --- a/src/js/PhotoSphereViewer.js +++ b/src/js/PhotoSphereViewer.js @@ -332,6 +332,7 @@ function PhotoSphereViewer(options) { * @property {int} mouse_x - current x position of the cursor * @property {int} mouse_y - current y position of the cursor * @property {Array[]} mouse_history - list of latest positions of the cursor, [time, x, y] + * @property {int} gyro_alpha_offset - current alpha offset for gyroscope controls * @property {int} pinch_dist - distance between fingers when zooming * @property orientation_reqid - animationRequest id of the device orientation * @property autorotate_reqid - animationRequest id of the automatic rotation @@ -362,6 +363,7 @@ function PhotoSphereViewer(options) { mouse_x: 0, mouse_y: 0, mouse_history: [], + gyro_alpha_offset: 0, pinch_dist: 0, orientation_reqid: null, autorotate_reqid: null, diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index 148f60cf7..62301b757 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -73,11 +73,11 @@ PhotoSphereViewer.prototype.isFullscreenEnabled = function() { PhotoSphereViewer.prototype.render = function(updateDirection) { if (updateDirection !== false) { this.prop.direction = this.sphericalCoordsToVector3(this.prop); - - this.camera.position.set(0, 0, 0); - this.camera.lookAt(this.prop.direction); } + this.camera.position.set(0, 0, 0); + this.camera.lookAt(this.prop.direction); + if (this.config.fisheye) { this.camera.position.copy(this.prop.direction).multiplyScalar(this.config.fisheye / 2).negate(); } @@ -324,20 +324,32 @@ PhotoSphereViewer.prototype.startGyroscopeControl = function() { this._stopAll(); - var self = this; + // compute the alpha offset to keep the current orientation + this.doControls.alphaOffset = this.prop.longitude; + this.doControls.update(); + + var direction = this.camera.getWorldDirection(new THREE.Vector3()); + var sphericalCoords = this.vector3ToSphericalCoords(direction); + + this.prop.gyro_alpha_offset = sphericalCoords.longitude; + + var run = function() { + this.doControls.alphaOffset = this.prop.gyro_alpha_offset; + this.doControls.update(); + + this.camera.getWorldDirection(this.prop.direction); + this.prop.direction.multiplyScalar(PhotoSphereViewer.SPHERE_RADIUS); - (function run() { - self.doControls.update(); - self.prop.direction = self.camera.getWorldDirection(); + var sphericalCoords = this.vector3ToSphericalCoords(this.prop.direction); + this.prop.longitude = sphericalCoords.longitude; + this.prop.latitude = sphericalCoords.latitude; - var sphericalCoords = self.vector3ToSphericalCoords(self.prop.direction); - self.prop.longitude = sphericalCoords.longitude; - self.prop.latitude = sphericalCoords.latitude; + this.render(false); - self.render(false); + this.prop.orientation_reqid = window.requestAnimationFrame(run); + }.bind(this); - self.prop.orientation_reqid = window.requestAnimationFrame(run); - }()); + run(); /** * @event gyroscope-updated From 612e4a284012ecc473637c6bc19688752831a5f8 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 25 Mar 2018 15:50:37 +0200 Subject: [PATCH 04/11] Fix #184 add mousemove_hover option --- example/index.htm | 3 +- src/js/PhotoSphereViewer.defaults.js | 1 + src/js/PhotoSphereViewer.events.js | 61 +++++++++++++++++++++++++++- src/js/PhotoSphereViewer.public.js | 19 +-------- 4 files changed, 63 insertions(+), 21 deletions(-) diff --git a/example/index.htm b/example/index.htm index 294ff8142..7171259cc 100644 --- a/example/index.htm +++ b/example/index.htm @@ -133,7 +133,8 @@

Header Level 3

move_speed: 1.1, time_anim: false, gyroscope: true, - //webgl: true, +// mousemove_hover: true, +// webgl: false, navbar: [ 'autorotate', 'zoom', 'download', 'markers', 'spacer-1', diff --git a/src/js/PhotoSphereViewer.defaults.js b/src/js/PhotoSphereViewer.defaults.js index 4cc5cb889..96126de48 100644 --- a/src/js/PhotoSphereViewer.defaults.js +++ b/src/js/PhotoSphereViewer.defaults.js @@ -168,6 +168,7 @@ PhotoSphereViewer.DEFAULTS = { mousewheel: true, mousewheel_factor: 1, mousemove: true, + mousemove_hover: false, keyboard: true, gyroscope: false, move_inertia: true, diff --git a/src/js/PhotoSphereViewer.events.js b/src/js/PhotoSphereViewer.events.js index fe70a8431..8414f3460 100644 --- a/src/js/PhotoSphereViewer.events.js +++ b/src/js/PhotoSphereViewer.events.js @@ -8,10 +8,19 @@ PhotoSphereViewer.prototype._bindEvents = function() { // all interation events are binded to the HUD only if (this.config.mousemove) { this.hud.container.style.cursor = 'move'; - this.hud.container.addEventListener('mousedown', this); + + if (this.config.mousemove_hover) { + this.hud.container.addEventListener('mouseenter', this); + this.hud.container.addEventListener('mouseleave', this); + } + else { + this.hud.container.addEventListener('mousedown', this); + window.addEventListener('mouseup', this); + } + this.hud.container.addEventListener('touchstart', this); - window.addEventListener('mouseup', this); window.addEventListener('touchend', this); + this.hud.container.addEventListener('mousemove', this); this.hud.container.addEventListener('touchmove', this); } @@ -33,6 +42,35 @@ PhotoSphereViewer.prototype._bindEvents = function() { }); }; +/** + * @summary Removes all event listeners + * @private + */ +PhotoSphereViewer.prototype._unbindEvents = function() { + window.removeEventListener('resize', this); + + if (this.config.mousemove) { + this.hud.container.removeEventListener('mousedown', this); + this.hud.container.removeEventListener('mouseenter', this); + this.hud.container.removeEventListener('touchstart', this); + window.removeEventListener('mouseup', this); + window.removeEventListener('touchend', this); + this.hud.container.removeEventListener('mouseleave', this); + this.hud.container.removeEventListener('mousemove', this); + this.hud.container.removeEventListener('touchmove', this); + } + + if (PhotoSphereViewer.SYSTEM.fullscreenEvent) { + document.removeEventListener(PhotoSphereViewer.SYSTEM.fullscreenEvent, this); + } + + if (this.config.mousewheel) { + this.hud.container.removeEventListener(PhotoSphereViewer.SYSTEM.mouseWheelEvent, this); + } + + this.off('_side-reached'); +}; + /** * @summary Handles events * @param {Event} evt @@ -44,8 +82,10 @@ PhotoSphereViewer.prototype.handleEvent = function(evt) { case 'resize': PSVUtils.throttle(this._onResize(), 50); break; case 'keydown': this._onKeyDown(evt); break; case 'mousedown': this._onMouseDown(evt); break; + case 'mouseenter': this._onMouseDown(evt); break; case 'touchstart': this._onTouchStart(evt); break; case 'mouseup': this._onMouseUp(evt); break; + case 'mouseleave': this._onMouseUp(evt); break; case 'touchend': this._onTouchEnd(evt); break; case 'mousemove': this._onMouseMove(evt); break; case 'touchmove': this._onTouchMove(evt); break; @@ -143,6 +183,9 @@ PhotoSphereViewer.prototype._onMouseMove = function(evt) { evt.preventDefault(); this._move(evt); } + else if (this.config.mousemove_hover) { + this._moveAbsolute(evt); + } }; /** @@ -382,6 +425,20 @@ PhotoSphereViewer.prototype._move = function(evt, log) { } }; +/** + * @summary Performs movement absolute to cursor position in viewer + * @param {MouseEvent} evt + * @private + */ +PhotoSphereViewer.prototype._moveAbsolute = function(evt) { + if (this.prop.moving) { + this.rotate({ + longitude: ((evt.clientX - this.container.offsetLeft) / this.container.offsetWidth - 0.5) * PSVUtils.TwoPI, + latitude: -((evt.clientY - this.container.offsetTop) / this.container.offsetHeight - 0.5) * Math.PI + }); + } +}; + /** * @summary Perfoms zoom * @param {TouchEvent} evt diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index 62301b757..dcead0390 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -109,24 +109,7 @@ PhotoSphereViewer.prototype.destroy = function() { } // remove listeners - window.removeEventListener('resize', this); - - if (this.config.mousemove) { - this.hud.container.removeEventListener('mousedown', this); - this.hud.container.removeEventListener('touchstart', this); - window.removeEventListener('mouseup', this); - window.removeEventListener('touchend', this); - this.hud.container.removeEventListener('mousemove', this); - this.hud.container.removeEventListener('touchmove', this); - } - - if (PhotoSphereViewer.SYSTEM.fullscreenEvent) { - document.removeEventListener(PhotoSphereViewer.SYSTEM.fullscreenEvent, this); - } - - if (this.config.mousewheel) { - this.hud.container.removeEventListener(PhotoSphereViewer.SYSTEM.mouseWheelEvent, this); - } + this._unbindEvents(); // destroy components if (this.tooltip) this.tooltip.destroy(); From b5ad3aa005aaed3e181448ccda3c33fb0a8000d0 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Tue, 27 Mar 2018 10:03:34 +0200 Subject: [PATCH 05/11] Fix code issues --- src/js/PSVMarker.js | 28 +++++------ src/js/PSVUtils.js | 62 ++++++++++++++++++------ src/js/PhotoSphereViewer.core.js | 45 ++++++++--------- src/js/PhotoSphereViewer.events.js | 12 ++--- src/js/PhotoSphereViewer.js | 4 +- src/js/PhotoSphereViewer.public.js | 77 +++++++++++++++++------------- src/js/PhotoSphereViewer.utils.js | 4 +- src/js/components/PSVHUD.js | 22 ++++----- src/js/components/PSVNavBar.js | 14 ++++-- src/js/components/PSVPanel.js | 2 +- src/js/components/PSVTooltip.js | 24 +++++----- 11 files changed, 167 insertions(+), 127 deletions(-) diff --git a/src/js/PSVMarker.js b/src/js/PSVMarker.js index dddfe3cfb..70961082f 100644 --- a/src/js/PSVMarker.js +++ b/src/js/PSVMarker.js @@ -57,7 +57,7 @@ function PSVMarker(properties, psv) { get: function() { return _id; }, - set: function(value) { + set: function() { } }, /** @@ -72,7 +72,7 @@ function PSVMarker(properties, psv) { get: function() { return _type; }, - set: function(value) { + set: function() { } }, /** @@ -86,7 +86,7 @@ function PSVMarker(properties, psv) { get: function() { return $el; }, - set: function(value) { + set: function() { } }, /** @@ -172,7 +172,7 @@ PSVMarker.prototype.destroy = function() { * @returns {boolean} */ PSVMarker.prototype.isNormal = function() { - return this.type == 'image' || this.type == 'html'; + return this.type === 'image' || this.type === 'html'; }; /** @@ -188,7 +188,7 @@ PSVMarker.prototype.isPoly = function() { * @returns {boolean} */ PSVMarker.prototype.isPolygon = function() { - return this.type == 'polygon_px' || this.type == 'polygon_rad'; + return this.type === 'polygon_px' || this.type === 'polygon_rad'; }; /** @@ -196,7 +196,7 @@ PSVMarker.prototype.isPolygon = function() { * @returns {boolean} */ PSVMarker.prototype.isPolyline = function() { - return this.type == 'polyline_px' || this.type == 'polyline_rad'; + return this.type === 'polyline_px' || this.type === 'polyline_rad'; }; /** @@ -204,7 +204,7 @@ PSVMarker.prototype.isPolyline = function() { * @returns {boolean} */ PSVMarker.prototype.isSvg = function() { - return this.type == 'rect' || this.type == 'circle' || this.type == 'ellipse' || this.type == 'path'; + return this.type === 'rect' || this.type === 'circle' || this.type === 'ellipse' || this.type === 'path'; }; /** @@ -216,10 +216,10 @@ PSVMarker.prototype.getScale = function(zoomLevel) { if (Array.isArray(this.scale)) { return this.scale[0] + (this.scale[1] - this.scale[0]) * PSVUtils.animation.easings.inQuad(zoomLevel / 100); } - else if (typeof this.scale == 'function') { + else if (typeof this.scale === 'function') { return this.scale(zoomLevel); } - else if (typeof this.scale == 'number') { + else if (typeof this.scale === 'number') { return this.scale * PSVUtils.animation.easings.inQuad(zoomLevel / 100); } else { @@ -326,7 +326,7 @@ PSVMarker.prototype._updateSvg = function() { // set content switch (this.type) { case 'rect': - if (typeof this._def == 'number') { + if (typeof this._def === 'number') { this._def = { x: 0, y: 0, @@ -348,7 +348,7 @@ PSVMarker.prototype._updateSvg = function() { break; case 'circle': - if (typeof this._def == 'number') { + if (typeof this._def === 'number') { this._def = { cx: this._def, cy: this._def, @@ -368,7 +368,7 @@ PSVMarker.prototype._updateSvg = function() { break; case 'ellipse': - if (typeof this._def == 'number') { + if (typeof this._def === 'number') { this._def = { cx: this._def, cy: this._def, @@ -391,7 +391,7 @@ PSVMarker.prototype._updateSvg = function() { break; case 'path': - if (typeof this._def == 'string') { + if (typeof this._def === 'string') { this._def = { d: this._def }; @@ -449,7 +449,7 @@ PSVMarker.prototype._updatePoly = function(key_rad, key_px) { // fold arrays: [1,2,3,4] => [[1,2],[3,4]] [this[key_rad], this[key_px]].forEach(function(polygon) { - if (polygon && typeof polygon[0] != 'object') { + if (polygon && typeof polygon[0] !== 'object') { for (var i = 0; i < polygon.length; i++) { polygon.splice(i, 2, [polygon[i], polygon[i + 1]]); } diff --git a/src/js/PSVUtils.js b/src/js/PSVUtils.js index 576c982ed..a35c3a2b6 100644 --- a/src/js/PSVUtils.js +++ b/src/js/PSVUtils.js @@ -73,7 +73,7 @@ PSVUtils.getWebGLCtx = function() { if (names.some(function(name) { try { context = canvas.getContext(name); - return (context && typeof context.getParameter == 'function'); + return (context && typeof context.getParameter === 'function'); } catch (e) { return false; } @@ -102,6 +102,9 @@ PSVUtils.getMaxTextureWidth = function() { if (ctx !== null) { return ctx.getParameter(ctx.MAX_TEXTURE_SIZE); } + else { + return 0; + } }; /** @@ -212,7 +215,7 @@ PSVUtils.mouseWheelEvent = function() { }; /** - *@summary Gets the event name for fullscreen + * @summary Gets the event name for fullscreen * @returns {string} */ PSVUtils.fullscreenEvent = function() { @@ -224,8 +227,12 @@ PSVUtils.fullscreenEvent = function() { }; for (var exit in map) { - if (exit in document) return map[exit]; + if (map.hasOwnProperty(exit) && exit in document) { + return map[exit]; + } } + + return null; }; /** @@ -361,7 +368,7 @@ PSVUtils.parsePosition = function(value) { } } - var xFirst = tokens[1] != 'left' && tokens[1] != 'right' && tokens[0] != 'top' && tokens[0] != 'bottom'; + var xFirst = tokens[1] !== 'left' && tokens[1] !== 'right' && tokens[0] !== 'top' && tokens[0] !== 'bottom'; tokens = tokens.map(function(token) { return PSVUtils.parsePosition.positions[token] || token; @@ -393,7 +400,7 @@ PSVUtils.parsePosition.positions = { 'top': '0%', 'bottom': '100%', 'left': '0%' * @throws {PSVError} when the speed cannot be parsed */ PSVUtils.parseSpeed = function(speed) { - if (typeof speed == 'string') { + if (typeof speed === 'string') { speed = speed.toString().trim(); // Speed extraction @@ -547,7 +554,7 @@ PSVUtils.animation = function(options) { var defer = D(false); // alwaysAsync = false to allow immediate resolution of "cancel" var start = null; - if (!options.easing || typeof options.easing == 'string') { + if (!options.easing || typeof options.easing === 'string') { options.easing = PSVUtils.animation.easings[options.easing || 'linear']; } @@ -666,11 +673,15 @@ PSVUtils.throttle = function(func, wait) { previous = Date.now(); timeout = null; result = func.apply(self, args); - if (!timeout) self = args = null; + if (!timeout) { + self = args = null; + } }; return function() { var now = Date.now(); - if (!previous) previous = now; + if (!previous) { + previous = now; + } var remaining = wait - (now - previous); self = this; args = arguments; @@ -681,7 +692,9 @@ PSVUtils.throttle = function(func, wait) { } previous = now; result = func.apply(self, args); - if (!timeout) self = args = null; + if (!timeout) { + self = args = null; + } } else if (!timeout) { timeout = setTimeout(later, remaining); @@ -702,16 +715,16 @@ PSVUtils.throttle = function(func, wait) { */ PSVUtils.isPlainObject = function(obj) { // Basic check for Type object that's not null - if (typeof obj == 'object' && obj !== null) { + if (typeof obj === 'object' && obj !== null) { // If Object.getPrototypeOf supported, use it - if (typeof Object.getPrototypeOf == 'function') { + if (typeof Object.getPrototypeOf === 'function') { var proto = Object.getPrototypeOf(obj); return proto === Object.prototype || proto === null; } // Otherwise, use internal class // This should be reliable as if getPrototypeOf not supported, is pre-ES5 - return Object.prototype.toString.call(obj) == '[object Object]'; + return Object.prototype.toString.call(obj) === '[object Object]'; } // Not an object @@ -741,12 +754,12 @@ PSVUtils.deepmerge = function(target, src) { target[i] = merge(null, e); }); } - else if (typeof src == 'object') { + else if (typeof src === 'object') { if (!target || Array.isArray(target)) { target = {}; } Object.keys(src).forEach(function(key) { - if (typeof src[key] != 'object' || !src[key] || !PSVUtils.isPlainObject(src[key])) { + if (typeof src[key] !== 'object' || !src[key] || !PSVUtils.isPlainObject(src[key])) { target[key] = src[key]; } else if (src[key] != first) { @@ -811,7 +824,7 @@ PSVUtils.normalizeWheel = function(event) { if ('deltaX' in event) { pX = event.deltaX; } if ((pX || pY) && event.deltaMode) { - if (event.deltaMode == 1) { // delta in LINE units + if (event.deltaMode === 1) { // delta in LINE units pX *= LINE_HEIGHT; pY *= LINE_HEIGHT; } @@ -832,3 +845,22 @@ PSVUtils.normalizeWheel = function(event) { pixelY: pY }; }; + +/** + * @callback ForEach + * @param {*} value + * @param {string} key + */ + +/** + * Loops over enumerable properties of an object + * @param {object} object + * @param {ForEach} callback + */ +PSVUtils.forEach = function(object, callback) { + for (var key in object) { + if (object.hasOwnProperty(key)) { + callback(object[key], key); + } + } +}; diff --git a/src/js/PhotoSphereViewer.core.js b/src/js/PhotoSphereViewer.core.js index c7145b5b2..fc9f4f8d9 100644 --- a/src/js/PhotoSphereViewer.core.js +++ b/src/js/PhotoSphereViewer.core.js @@ -12,13 +12,12 @@ PhotoSphereViewer.prototype._loadXMP = function(panorama) { var defer = D(); var xhr = new XMLHttpRequest(); - var self = this; var progress = 0; xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200 || xhr.status === 201 || xhr.status === 202 || xhr.status === 0) { - self.loader.setProgress(100); + this.loader.setProgress(100); var binary = xhr.responseText; var a = binary.indexOf(''); @@ -48,29 +47,29 @@ PhotoSphereViewer.prototype._loadXMP = function(panorama) { } } else { - self.container.textContent = 'Cannot load image'; + this.container.textContent = 'Cannot load image'; throw new PSVError('Cannot load image'); } } else if (xhr.readyState === 3) { - self.loader.setProgress(progress += 10); + this.loader.setProgress(progress += 10); } - }; + }.bind(this); xhr.onprogress = function(e) { if (e.lengthComputable) { var new_progress = parseInt(e.loaded / e.total * 100); if (new_progress > progress) { progress = new_progress; - self.loader.setProgress(progress); + this.loader.setProgress(progress); } } - }; + }.bind(this); xhr.onerror = function() { - self.container.textContent = 'Cannot load image'; + this.container.textContent = 'Cannot load image'; throw new PSVError('Cannot load image'); - }; + }.bind(this); xhr.open('GET', panorama, true); xhr.send(null); @@ -100,7 +99,7 @@ PhotoSphereViewer.prototype._loadTexture = function(panorama) { } panorama = tempPanorama; } - else if (typeof panorama == 'object') { + else if (typeof panorama === 'object') { if (!PhotoSphereViewer.CUBE_HASHMAP.every(function(side) { return !!panorama[side]; })) { @@ -208,7 +207,7 @@ PhotoSphereViewer.prototype._loadEquirectangularTexture = function(panorama) { var ratio = Math.min(pano_data.full_width, PhotoSphereViewer.SYSTEM.maxTextureWidth) / pano_data.full_width; // resize image / fill cropped parts with black - if (ratio !== 1 || pano_data.cropped_width != pano_data.full_width || pano_data.cropped_height != pano_data.full_height) { + if (ratio !== 1 || pano_data.cropped_width !== pano_data.full_width || pano_data.cropped_height !== pano_data.full_height) { var resized_pano_data = PSVUtils.clone(pano_data); resized_pano_data.full_width *= ratio; @@ -525,8 +524,6 @@ PhotoSphereViewer.prototype._transition = function(texture, position) { throw new PSVError('Transition is not available with cubemap.'); } - var self = this; - // create a new sphere with the new texture var geometry = new THREE.SphereGeometry( PhotoSphereViewer.SPHERE_RADIUS * 0.9, @@ -564,20 +561,20 @@ PhotoSphereViewer.prototype._transition = function(texture, position) { properties: { opacity: { start: 0.0, end: 1.0 } }, - duration: self.config.transition.duration, + duration: this.config.transition.duration, easing: 'outCubic', onTick: function(properties) { material.opacity = properties.opacity; - self.render(); - } + this.render(); + }.bind(this) }) .then(function() { // remove temp sphere and transfer the texture to the main sphere - self.mesh.material.map.dispose(); - self.mesh.material.map = texture; + this.mesh.material.map.dispose(); + this.mesh.material.map = texture; - self.scene.remove(mesh); + this.scene.remove(mesh); mesh.geometry.dispose(); mesh.geometry = null; @@ -587,17 +584,17 @@ PhotoSphereViewer.prototype._transition = function(texture, position) { // actually rotate the camera if (position) { // FIXME: find a better way to handle ranges - if (self.config.latitude_range || self.config.longitude_range) { - self.config.longitude_range = self.config.latitude_range = null; + if (this.config.latitude_range || this.config.longitude_range) { + this.config.longitude_range = this.config.latitude_range = null; console.warn('PhotoSphereViewer: trying to perform transition with longitude_range and/or latitude_range, ranges cleared.'); } - self.rotate(position); + this.rotate(position); } else { - self.render(); + this.render(); } - }); + }.bind(this)); }; /** diff --git a/src/js/PhotoSphereViewer.events.js b/src/js/PhotoSphereViewer.events.js index 8414f3460..59fe0e9be 100644 --- a/src/js/PhotoSphereViewer.events.js +++ b/src/js/PhotoSphereViewer.events.js @@ -101,7 +101,7 @@ PhotoSphereViewer.prototype.handleEvent = function(evt) { * @private */ PhotoSphereViewer.prototype._onResize = function() { - if (this.container.clientWidth != this.prop.size.width || this.container.clientHeight != this.prop.size.height) { + if (this.container.clientWidth !== this.prop.size.width || this.container.clientHeight !== this.prop.size.height) { this.prop.size.width = parseInt(this.container.clientWidth); this.prop.size.height = parseInt(this.container.clientHeight); this.prop.aspect = this.prop.size.width / this.prop.size.height; @@ -299,8 +299,6 @@ PhotoSphereViewer.prototype._stopMove = function(evt) { * @private */ PhotoSphereViewer.prototype._stopMoveInertia = function(evt) { - var self = this; - var direction = { x: evt.clientX - this.prop.mouse_history[0][1], y: evt.clientY - this.prop.mouse_history[0][2] @@ -316,12 +314,12 @@ PhotoSphereViewer.prototype._stopMoveInertia = function(evt) { duration: norm * PhotoSphereViewer.INERTIA_WINDOW / 100, easing: 'outCirc', onTick: function(properties) { - self._move(properties, false); - } + this._move(properties, false); + }.bind(this) }) .ensure(function() { - self.prop.moving = false; - }); + this.prop.moving = false; + }.bind(this)); }; /** diff --git a/src/js/PhotoSphereViewer.js b/src/js/PhotoSphereViewer.js index da164dbd3..af739be56 100644 --- a/src/js/PhotoSphereViewer.js +++ b/src/js/PhotoSphereViewer.js @@ -223,7 +223,7 @@ function PhotoSphereViewer(options) { * @member {HTMLElement} * @readonly */ - this.parent = (typeof options.container == 'string') ? document.getElementById(options.container) : options.container; + this.parent = (typeof options.container === 'string') ? document.getElementById(options.container) : options.container; /** * @summary Main container @@ -392,7 +392,7 @@ function PhotoSphereViewer(options) { if (!this.config.templates[tpl]) { this.config.templates[tpl] = PhotoSphereViewer.TEMPLATES[tpl]; } - if (typeof this.config.templates[tpl] == 'string') { + if (typeof this.config.templates[tpl] === 'string') { this.config.templates[tpl] = doT.template(this.config.templates[tpl]); } }, this); diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index dcead0390..450f266a8 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -112,12 +112,24 @@ PhotoSphereViewer.prototype.destroy = function() { this._unbindEvents(); // destroy components - if (this.tooltip) this.tooltip.destroy(); - if (this.hud) this.hud.destroy(); - if (this.loader) this.loader.destroy(); - if (this.navbar) this.navbar.destroy(); - if (this.panel) this.panel.destroy(); - if (this.doControls) this.doControls.disconnect(); + if (this.tooltip) { + this.tooltip.destroy(); + } + if (this.hud) { + this.hud.destroy(); + } + if (this.loader) { + this.loader.destroy(); + } + if (this.navbar) { + this.navbar.destroy(); + } + if (this.panel) { + this.panel.destroy(); + } + if (this.doControls) { + this.doControls.disconnect(); + } // destroy ThreeJS view if (this.scene) { @@ -168,7 +180,7 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { throw new PSVError('Loading already in progress'); } - if (typeof position == 'boolean') { + if (typeof position === 'boolean') { transition = position; position = undefined; } @@ -185,8 +197,6 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { this.config.panorama = path; - var self = this; - if (!transition || !this.config.transition || !this.scene) { this.loader.show(); if (this.canvas_container) { @@ -195,18 +205,18 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { this.prop.loading_promise = this._loadTexture(this.config.panorama) .then(function(texture) { - self._setTexture(texture); + this._setTexture(texture); if (position) { - self.rotate(position); + this.rotate(position); } - }) + }.bind(this)) .ensure(function() { - self.loader.hide(); - self.canvas_container.style.opacity = 1; + this.loader.hide(); + this.canvas_container.style.opacity = 1; - self.prop.loading_promise = null; - }) + this.prop.loading_promise = null; + }.bind(this)) .rethrow(); } else { @@ -216,15 +226,15 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { this.prop.loading_promise = this._loadTexture(this.config.panorama) .then(function(texture) { - self.loader.hide(); + this.loader.hide(); - return self._transition(texture, position); - }) + return this._transition(texture, position); + }.bind(this)) .ensure(function() { - self.loader.hide(); + this.loader.hide(); - self.prop.loading_promise = null; - }) + this.prop.loading_promise = null; + }.bind(this)) .rethrow(); } @@ -238,23 +248,24 @@ PhotoSphereViewer.prototype.setPanorama = function(path, position, transition) { PhotoSphereViewer.prototype.startAutorotate = function() { this._stopAll(); - var self = this; - var last = null; - var elapsed = null; + var last; + var elapsed; - (function run(timestamp) { + var run = function run(timestamp) { if (timestamp) { - elapsed = last === null ? 0 : timestamp - last; + elapsed = last === undefined ? 0 : timestamp - last; last = timestamp; - self.rotate({ - longitude: self.prop.longitude + self.config.anim_speed * elapsed / 1000, - latitude: self.prop.latitude - (self.prop.latitude - self.config.anim_lat) / 200 + this.rotate({ + longitude: this.prop.longitude + this.config.anim_speed * elapsed / 1000, + latitude: this.prop.latitude - (this.prop.latitude - this.config.anim_lat) / 200 }); } - self.prop.autorotate_reqid = window.requestAnimationFrame(run); - }(null)); + this.prop.autorotate_reqid = window.requestAnimationFrame(run); + }.bind(this); + + run(); /** * @event autorotate @@ -427,7 +438,7 @@ PhotoSphereViewer.prototype.animate = function(position, duration) { this.trigger.bind(this, '_side-reached') ); - if (!duration && typeof duration != 'number') { + if (!duration && typeof duration !== 'number') { // desired radial speed duration = duration ? PSVUtils.parseSpeed(duration) : this.config.anim_speed; // get the angle between current position and target diff --git a/src/js/PhotoSphereViewer.utils.js b/src/js/PhotoSphereViewer.utils.js index c3d6c9325..17a361c16 100644 --- a/src/js/PhotoSphereViewer.utils.js +++ b/src/js/PhotoSphereViewer.utils.js @@ -46,7 +46,9 @@ PhotoSphereViewer._deviceOrientationListener = function(event) { PhotoSphereViewer.prototype._setViewerSize = function(size) { ['width', 'height'].forEach(function(dim) { if (size[dim]) { - if (/^[0-9.]+$/.test(size[dim])) size[dim] += 'px'; + if (/^[0-9.]+$/.test(size[dim])) { + size[dim] += 'px'; + } this.parent.style[dim] = size[dim]; } }, this); diff --git a/src/js/components/PSVHUD.js b/src/js/components/PSVHUD.js index ee2ea212d..436959747 100644 --- a/src/js/components/PSVHUD.js +++ b/src/js/components/PSVHUD.js @@ -223,7 +223,7 @@ PSVHUD.prototype.removeMarker = function(marker, render) { this.svgContainer.removeChild(marker.$el); } - if (this.hoveringMarker == marker) { + if (this.hoveringMarker === marker) { this.psv.tooltip.hideTooltip(); } @@ -316,9 +316,9 @@ PSVHUD.prototype.toggleMarkersList = function() { */ PSVHUD.prototype.showMarkersList = function() { var markers = []; - for (var id in this.markers) { - markers.push(this.markers[id]); - } + PSVUtils.forEach(this.markers, function(marker) { + markers.push(marker); + }); /** * @event filter:render-markers-list @@ -353,8 +353,7 @@ PSVHUD.prototype.hideMarkersList = function() { PSVHUD.prototype.renderMarkers = function() { var rotation = !this.psv.isGyroscopeEnabled() ? 0 : THREE.Math.radToDeg(this.psv.camera.rotation.z); - for (var id in this.markers) { - var marker = this.markers[id]; + PSVUtils.forEach(this.markers, function(marker) { var isVisible = marker.visible; if (isVisible && marker.isPoly()) { @@ -364,10 +363,9 @@ PSVHUD.prototype.renderMarkers = function() { if (isVisible) { marker.position2D = this._getPolyDimensions(marker, positions); - var points = ''; - positions.forEach(function(pos) { - points += pos.x + ',' + pos.y + ' '; - }); + var points = positions.map(function(pos) { + return pos.x + ',' + pos.y; + }).join(' '); marker.$el.setAttributeNS(null, 'points', points); } @@ -397,7 +395,7 @@ PSVHUD.prototype.renderMarkers = function() { } PSVUtils.toggleClass(marker.$el, 'psv-marker--visible', isVisible); - } + }.bind(this)); }; /** @@ -650,7 +648,7 @@ PSVHUD.prototype._onMouseMove = function(e) { } } else if (this.hoveringMarker && this.hoveringMarker.isPoly()) { - this.psv.trigger('leave-marker', marker); + this.psv.trigger('leave-marker', this.hoveringMarker); this.hoveringMarker = null; diff --git a/src/js/components/PSVNavBar.js b/src/js/components/PSVNavBar.js index fcc176605..28975f837 100644 --- a/src/js/components/PSVNavBar.js +++ b/src/js/components/PSVNavBar.js @@ -27,7 +27,7 @@ function PSVNavBar(psv) { this.config = PSVUtils.clone(PhotoSphereViewer.DEFAULTS.navbar); } // space separated list - else if (typeof this.config == 'string') { + else if (typeof this.config === 'string') { this.config = this.config.split(' '); } // migration from object @@ -36,11 +36,12 @@ function PSVNavBar(psv) { var config = this.config; this.config = []; - for (var key in config) { - if (config[key]) { + + PSVUtils.forEach(config, function(enabled, key) { + if (enabled) { this.config.push(key); } - } + }.bind(this)); this.config.sort(function(a, b) { return PhotoSphereViewer.DEFAULTS.navbar.indexOf(a) - PhotoSphereViewer.DEFAULTS.navbar.indexOf(b); @@ -64,7 +65,7 @@ PSVNavBar.prototype.create = function() { PSVComponent.prototype.create.call(this); this.config.forEach(function(button) { - if (typeof button == 'object') { + if (typeof button === 'object') { this.items.push(new PSVNavBarCustomButton(this, button)); } else { @@ -144,6 +145,9 @@ PSVNavBar.prototype.getNavbarButton = function(id, silent) { button = item; return true; } + else { + return false; + } }); if (!button && !silent) { diff --git a/src/js/components/PSVPanel.js b/src/js/components/PSVPanel.js index 48d0be8dd..22e4bcd40 100644 --- a/src/js/components/PSVPanel.js +++ b/src/js/components/PSVPanel.js @@ -113,7 +113,7 @@ PSVPanel.prototype.showPanel = function(content, noMargin) { this.content.scrollTop = 0; this.container.classList.add('psv-panel--open'); - PSVUtils.toggleClass(this.content, 'psv-panel-content--no-margin', !!noMargin); + PSVUtils.toggleClass(this.content, 'psv-panel-content--no-margin', noMargin === true); this.prop.opened = true; diff --git a/src/js/components/PSVTooltip.js b/src/js/components/PSVTooltip.js index 9e84c1df4..84a1144ef 100644 --- a/src/js/components/PSVTooltip.js +++ b/src/js/components/PSVTooltip.js @@ -130,13 +130,13 @@ PSVTooltip.prototype.showTooltip = function(config) { var tempPos = PSVUtils.parsePosition(config.position); if (!(tempPos.left in PSVTooltip.leftMap) || !(tempPos.top in PSVTooltip.topMap)) { - throw new PSVError('unable to parse tooltip position "' + tooltip.position + '"'); + throw new PSVError('unable to parse tooltip position "' + config.position + '"'); } config.position = [PSVTooltip.topMap[tempPos.top], PSVTooltip.leftMap[tempPos.left]]; } - if (config.position[0] == 'center' && config.position[1] == 'center') { + if (config.position[0] === 'center' && config.position[1] === 'center') { throw new PSVError('unable to parse tooltip position "center center"'); } @@ -144,7 +144,7 @@ PSVTooltip.prototype.showTooltip = function(config) { // Remove every other classes (Firefox does not implements forEach) for (var i = t.classList.length - 1; i >= 0; i--) { var item = t.classList.item(i); - if (item != 'psv-tooltip' && item != 'psv-tooltip--visible') { + if (item !== 'psv-tooltip' && item !== 'psv-tooltip--visible') { t.classList.remove(item); } } @@ -209,18 +209,17 @@ PSVTooltip.prototype.showTooltip = function(config) { // delay for correct transition between the two classes if (!isUpdate) { - var self = this; this.prop.timeout = window.setTimeout(function() { t.classList.add('psv-tooltip--visible'); - self.prop.timeout = null; + this.prop.timeout = null; /** * @event show-tooltip * @memberof module:components.PSVTooltip * @summary Trigered when the tooltip is shown */ - self.psv.trigger('show-tooltip'); - }, this.config.delay); + this.psv.trigger('show-tooltip'); + }.bind(this), this.config.delay); } }; @@ -237,13 +236,12 @@ PSVTooltip.prototype.hideTooltip = function() { if (this.isTooltipVisible()) { this.container.classList.remove('psv-tooltip--visible'); - var self = this; this.prop.timeout = window.setTimeout(function() { - self.content.innerHTML = null; - self.container.style.top = '-1000px'; - self.container.style.left = '-1000px'; - self.prop.timeout = null; - }, this.config.delay); + this.content.innerHTML = null; + this.container.style.top = '-1000px'; + this.container.style.left = '-1000px'; + this.prop.timeout = null; + }.bind(this), this.config.delay); /** * @event hide-tooltip From 44b947be1eeced3a78c575d32d17a6c3c022d828 Mon Sep 17 00:00:00 2001 From: "greenkeeper[bot]" Date: Tue, 1 May 2018 10:09:58 +0200 Subject: [PATCH 06/11] chore(package): update foodoc to version 0.0.9 (#194) --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 796d21aa7..1cd0d6c87 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "dot": ">=1.0.3" }, "devDependencies": { - "foodoc": "^0.0.8", + "foodoc": "^0.0.9", "grunt": "^1.0.0", "grunt-banner": "^0.6.0", "grunt-contrib-clean": "^1.0.0", From dab207b5d38d843dd3aa4def1fff85d02dc8fc81 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Thu, 3 May 2018 20:31:01 +0200 Subject: [PATCH 07/11] HTTPS everywhere --- .travis.yml | 3 --- Gruntfile.js | 2 +- LICENSE | 2 +- README.md | 9 ++++----- bower.json | 4 ++-- package.json | 4 ++-- 6 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1a3cce54..542faf55e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,3 @@ node_js: - "8" before_install: - npm install -g grunt-cli - - npm install -g bower -before_script: - - bower install diff --git a/Gruntfile.js b/Gruntfile.js index f27dc4671..8acee85c2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -28,7 +28,7 @@ module.exports = function(grunt) { ' * Photo Sphere Viewer <%= grunt.option("tag") || pkg.version %>\n' + ' * Copyright (c) 2014-2015 Jérémy Heleine\n' + ' * Copyright (c) 2015-<%= grunt.template.today("yyyy") %> Damien "Mistic" Sorel\n' + - ' * Licensed under MIT (http://opensource.org/licenses/MIT)\n' + + ' * Licensed under MIT (https://opensource.org/licenses/MIT)\n' + ' */', concat: { diff --git a/LICENSE b/LICENSE index dcb773e19..3bd68692c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ The MIT License (MIT) Copyright (c) 2015 Jérémy Heleine -Copyright (c) 2016 Damien Sorel +Copyright (c) 2016-2018 Damien Sorel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index cbacf9872..fad2f58b9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,5 @@ # Photo Sphere Viewer -[![Bower version](https://img.shields.io/bower/v/Photo-Sphere-Viewer.svg?style=flat-square)](http://photo-sphere-viewer.js.org) [![NPM version](https://img.shields.io/npm/v/photo-sphere-viewer.svg?style=flat-square)](https://www.npmjs.com/package/photo-sphere-viewer) [![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/photo-sphere-viewer/badge)](https://www.jsdelivr.com/package/npm/photo-sphere-viewer) [![Build Status](https://img.shields.io/travis/mistic100/Photo-Sphere-Viewer/master.svg?style=flat-square)](https://travis-ci.org/mistic100/Photo-Sphere-Viewer) @@ -11,13 +10,13 @@ Photo Sphere Viewer is a JavaScript library that allows you to display 360×180 Forked from [JeremyHeleine/Photo-Sphere-Viewer](https://github.com/JeremyHeleine/Photo-Sphere-Viewer). ## Documentation -[photo-sphere-viewer.js.org](http://photo-sphere-viewer.js.org) +[photo-sphere-viewer.js.org](https://photo-sphere-viewer.js.org) ## Dependencies - * [three.js](http://threejs.org) - * [doT.js](http://olado.github.io/doT) + * [three.js](https://threejs.org) + * [doT.js](https://olado.github.io/doT) * [uEvent](https://github.com/mistic100/uEvent) - * [D.js](http://malko.github.io/D.js) + * [D.js](https://malko.github.io/D.js) ## Install diff --git a/bower.json b/bower.json index c4fde4498..6d9deae9f 100644 --- a/bower.json +++ b/bower.json @@ -9,11 +9,11 @@ { "name": "Damien \"Mistic\" Sorel", "email": "contact@git.strangeplanet.fr", - "homepage": "http://www.strangeplanet.fr" + "homepage": "https://www.strangeplanet.fr" } ], "description": "A JavaScript library to display Photo Sphere panoramas", - "homepage": "https://github.com/mistic100/Photo-Sphere-Viewer", + "homepage": "https://photo-sphere-viewer.js.org", "main": [ "dist/photo-sphere-viewer.js", "dist/photo-sphere-viewer.css" diff --git a/package.json b/package.json index 1cd0d6c87..1029a4277 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ { "name": "Damien \"Mistic\" Sorel", "email": "contact@git.strangeplanet.fr", - "homepage": "http://www.strangeplanet.fr" + "homepage": "https://www.strangeplanet.fr" } ], "description": "A JavaScript library to display Photo Sphere panoramas", - "homepage": "http://mistic100.github.io/Photo-Sphere-Viewer", + "homepage": "https://photo-sphere-viewer.js.org", "dependencies": { "three": ">= 0.85.0", "d.js": "~0.7.3", From 3e66468fa157d8c394c7e1388f0d6736aa9d6875 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 6 May 2018 11:15:45 +0200 Subject: [PATCH 08/11] Fix #196 Fix #189 not able to animate on "ready" event The initial "render" once was not completed thus not removed from the events manager, producing a events loop between "render" and "ready" --- src/js/PhotoSphereViewer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/PhotoSphereViewer.js b/src/js/PhotoSphereViewer.js index af739be56..350163b52 100644 --- a/src/js/PhotoSphereViewer.js +++ b/src/js/PhotoSphereViewer.js @@ -477,7 +477,7 @@ function PhotoSphereViewer(options) { * @memberof PhotoSphereViewer * @summary Triggered when the panorama image has been loaded and the viewer is ready to perform the first render */ - this.trigger('ready'); + setTimeout(this.trigger.bind(this, 'ready'), 0); }.bind(this)); } From a2717d7423f4a9c17727eaad98579e212af4e5df Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 6 May 2018 11:41:00 +0200 Subject: [PATCH 09/11] Fix #189 Prevent errors when forcing gyroscope on desktop --- src/js/PSVUtils.js | 35 ++++++++++++++++++++++ src/js/PhotoSphereViewer.public.js | 19 ++++++++++-- src/js/PhotoSphereViewer.utils.js | 26 +--------------- src/js/buttons/PSVNavBarGyroscopeButton.js | 2 +- 4 files changed, 54 insertions(+), 28 deletions(-) diff --git a/src/js/PSVUtils.js b/src/js/PSVUtils.js index a35c3a2b6..d224a6f19 100644 --- a/src/js/PSVUtils.js +++ b/src/js/PSVUtils.js @@ -93,6 +93,41 @@ PSVUtils.isWebGLSupported = function() { return !!window.WebGLRenderingContext && PSVUtils.getWebGLCtx() !== null; }; +/** + * @summary Detects if device orientation is supported + * @description We can only be sure device orientation is supported once received an event with coherent data + * @returns {Promise} + */ +PSVUtils.isDeviceOrientationSupported = function() { + var defer = D(); + + if ('DeviceOrientationEvent' in window) { + var listener = function(event) { + if (event && event.alpha !== null && !isNaN(event.alpha)) { + defer.resolve(); + } + else { + defer.reject(); + } + + window.removeEventListener('deviceorientation', listener); + }; + + window.addEventListener('deviceorientation', listener, false); + + setTimeout(function() { + if (defer.promise.isPending()) { + listener(null); + } + }, 2000); + } + else { + defer.reject(); + } + + return defer.promise; +}; + /** * @summary Gets max texture width in WebGL context * @returns {int} diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index 450f266a8..1d1f50dba 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -307,15 +307,30 @@ PhotoSphereViewer.prototype.toggleAutorotate = function() { }; /** - * @summary Enables the gyroscope navigation + * @summary Enables the gyroscope navigation if available * @fires PhotoSphereViewer.gyroscope-updated */ PhotoSphereViewer.prototype.startGyroscopeControl = function() { - if (!this.doControls || !this.doControls.enabled || !this.doControls.deviceOrientation) { + if (!this.doControls || !this.doControls.enabled) { console.warn('PhotoSphereViewer: gyroscope disabled'); return; } + PhotoSphereViewer.SYSTEM.deviceOrientationSupported.then( + PhotoSphereViewer.prototype._startGyroscopeControl.bind(this), + function() { + console.warn('PhotoSphereViewer: gyroscope not available'); + } + ); +}; + +/** + * @summary Immediately enables the gyroscope navigation + * @description Do not call this method directly, call `startGyroscopeControl` instead + * @fires PhotoSphereViewer.gyroscope-updated + * @private + */ +PhotoSphereViewer.prototype._startGyroscopeControl = function() { this._stopAll(); // compute the alpha offset to keep the current orientation diff --git a/src/js/PhotoSphereViewer.utils.js b/src/js/PhotoSphereViewer.utils.js index 17a361c16..c72ff9a6f 100644 --- a/src/js/PhotoSphereViewer.utils.js +++ b/src/js/PhotoSphereViewer.utils.js @@ -11,31 +11,7 @@ PhotoSphereViewer._loadSystem = function() { S.maxTextureWidth = S.isWebGLSupported ? PSVUtils.getMaxTextureWidth() : 4096; S.mouseWheelEvent = PSVUtils.mouseWheelEvent(); S.fullscreenEvent = PSVUtils.fullscreenEvent(); - S.deviceOrientationSupported = D(); - - if ('DeviceOrientationEvent' in window) { - window.addEventListener('deviceorientation', PhotoSphereViewer._deviceOrientationListener, false); - } - else { - S.deviceOrientationSupported.reject(); - } -}; - -/** - * @summary Resolve or reject SYSTEM.deviceOrientationSupported - * @description We can only be sure device orientation is supported once received an event with coherent data - * @param {DeviceOrientationEvent} event - * @private - */ -PhotoSphereViewer._deviceOrientationListener = function(event) { - if (event.alpha !== null && !isNaN(event.alpha)) { - PhotoSphereViewer.SYSTEM.deviceOrientationSupported.resolve(); - } - else { - PhotoSphereViewer.SYSTEM.deviceOrientationSupported.reject(); - } - - window.removeEventListener('deviceorientation', PhotoSphereViewer._deviceOrientationListener); + S.deviceOrientationSupported = PSVUtils.isDeviceOrientationSupported(); }; /** diff --git a/src/js/buttons/PSVNavBarGyroscopeButton.js b/src/js/buttons/PSVNavBarGyroscopeButton.js index 173730d2e..7752732a6 100644 --- a/src/js/buttons/PSVNavBarGyroscopeButton.js +++ b/src/js/buttons/PSVNavBarGyroscopeButton.js @@ -25,7 +25,7 @@ PSVNavBarGyroscopeButton.icon = 'compass.svg'; PSVNavBarGyroscopeButton.prototype.create = function() { PSVNavBarButton.prototype.create.call(this); - PhotoSphereViewer.SYSTEM.deviceOrientationSupported.promise.then( + PhotoSphereViewer.SYSTEM.deviceOrientationSupported.then( this._onAvailabilityChange.bind(this, true), this._onAvailabilityChange.bind(this, false) ); From 9d968ca1f0bc68f45db2aa86d1624bdd7591162d Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 6 May 2018 11:55:19 +0200 Subject: [PATCH 10/11] Fix #197 Allow camelCase for marker svgStyle --- example/index.htm | 16 ++++++++-------- src/js/PSVMarker.js | 4 ++-- src/js/PSVUtils.js | 12 ++++++++++++ tests/utils/index.js | 10 ++++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/example/index.htm b/example/index.htm index 7171259cc..528913cb8 100644 --- a/example/index.htm +++ b/example/index.htm @@ -232,7 +232,7 @@

Header Level 3

svgStyle: { fill: 'url(#points)', //'rgba(255,0,0,0.3)', stroke: 'rgba(255, 0, 50, 0.8)', - 'stroke-width': '2px' + strokeWidth: '2px' }, tooltip: { content: 'This is a mountain', @@ -245,9 +245,9 @@

Header Level 3

polyline_rad: [5.924, 0.064, 5.859, -0.061, 5.710, -0.132, 5.410, -0.287, 4.329, -0.490, 3.838, -0.370, 3.725, -0.241], svgStyle: { stroke: 'rgba(80, 100, 50, 0.8)', - 'stroke-linecap': 'round', - 'stroke-linejoin': 'round', - 'stroke-width': '10px' + strokeLinecap: 'round', + strokeLinejoin: 'round', + strokeWidth: '10px' }, tooltip: 'This is a track' }); @@ -300,7 +300,7 @@

Header Level 3

svgStyle: { fill: 'rgba(255,255,0,0.3)', stroke: 'yellow', - 'stroke-width': '2px' + strokeWidth: '2px' }, longitude: -0.5, latitude: -0.28, @@ -314,7 +314,7 @@

Header Level 3

svgStyle: { fill: 'rgba(255,255,0,0.3)', stroke: 'yellow', - 'stroke-width': '2px' + strokeWidth: '2px' }, longitude: -0.5, latitude: -0.28, @@ -328,7 +328,7 @@

Header Level 3

svgStyle: { fill: 'rgba(255,255,0,0.3)', stroke: 'yellow', - 'stroke-width': '2px' + strokeWidth: '2px' }, longitude: -0.5, latitude: -0.38, @@ -342,7 +342,7 @@

Header Level 3

svgStyle: { fill: 'rgba(255,255,0,0.3)', stroke: 'yellow', - 'stroke-width': '2px' + strokeWidth: '2px' }, longitude: -0.5, latitude: -0.38, diff --git a/src/js/PSVMarker.js b/src/js/PSVMarker.js index 70961082f..d0043b26d 100644 --- a/src/js/PSVMarker.js +++ b/src/js/PSVMarker.js @@ -406,7 +406,7 @@ PSVMarker.prototype._updateSvg = function() { // set style if (this.svgStyle) { Object.getOwnPropertyNames(this.svgStyle).forEach(function(prop) { - this.$el.setAttributeNS(null, prop, this.svgStyle[prop]); + this.$el.setAttributeNS(null, PSVUtils.dasherize(prop), this.svgStyle[prop]); }, this); } else { @@ -432,7 +432,7 @@ PSVMarker.prototype._updatePoly = function(key_rad, key_px) { // set style if (this.svgStyle) { Object.getOwnPropertyNames(this.svgStyle).forEach(function(prop) { - this.$el.setAttributeNS(null, prop, this.svgStyle[prop]); + this.$el.setAttributeNS(null, PSVUtils.dasherize(prop), this.svgStyle[prop]); }, this); if (this.isPolyline() && !this.svgStyle.fill) { diff --git a/src/js/PSVUtils.js b/src/js/PSVUtils.js index d224a6f19..f4bd2983c 100644 --- a/src/js/PSVUtils.js +++ b/src/js/PSVUtils.js @@ -302,6 +302,18 @@ PSVUtils.sum = function(array) { }, 0); }; +/** + * @summary Transforms a string to dash-case + * {@link https://github.com/shahata/dasherize} + * @param {string} str + * @returns {string} + */ +PSVUtils.dasherize = function(str) { + return str.replace(/[A-Z](?:(?=[^A-Z])|[A-Z]*(?=[A-Z][^A-Z]|$))/g, function(s, i) { + return (i > 0 ? '-' : '') + s.toLowerCase(); + }); +}; + /** * @summary Returns the value of a given attribute in the panorama metadata * @param {string} data diff --git a/tests/utils/index.js b/tests/utils/index.js index eefcf7639..1f41a03ae 100644 --- a/tests/utils/index.js +++ b/tests/utils/index.js @@ -354,3 +354,13 @@ describe('PSVUtils::getXMPValue', function() { }); }); + +describe('PSVUtils::dasherize', function() { + it('should dasherize from camelCase', function() { + assert.equal(PSVUtils.dasherize('strokeWidth'), 'stroke-width'); + }); + + it('should not change existing dash-case', function() { + assert.equal(PSVUtils.dasherize('stroke-width'), 'stroke-width'); + }); +}); From af99e90efd7ded4f3168fc3e9a853e358bdfae65 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Sun, 6 May 2018 12:29:38 +0200 Subject: [PATCH 11/11] Fix : autorotate not working --- src/js/PhotoSphereViewer.public.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/PhotoSphereViewer.public.js b/src/js/PhotoSphereViewer.public.js index 1d1f50dba..9e9877542 100644 --- a/src/js/PhotoSphereViewer.public.js +++ b/src/js/PhotoSphereViewer.public.js @@ -251,7 +251,7 @@ PhotoSphereViewer.prototype.startAutorotate = function() { var last; var elapsed; - var run = function run(timestamp) { + var run = function (timestamp) { if (timestamp) { elapsed = last === undefined ? 0 : timestamp - last; last = timestamp;