photo-sphere-viewer
Advanced tools
Comparing version 4.1.0 to 4.2.0-rc.1
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -116,2 +116,7 @@ * @copyright 2015-2021 Damien "Mistic" Sorel | ||
/** | ||
* @type {PSV.plugins.AutorotateKeypointsPlugin.Keypoints[]} keypoints | ||
*/ | ||
_this.keypoints = null; | ||
/** | ||
* @type {PSV.plugins.MarkersPlugin} | ||
@@ -136,2 +141,3 @@ * @private | ||
this.psv.off(photoSphereViewer.CONSTANTS.EVENTS.AUTOROTATE, this); | ||
delete this.markers; | ||
delete this.keypoints; | ||
@@ -138,0 +144,0 @@ delete this.state; |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -4,0 +4,0 @@ * @copyright 2015-2021 Damien "Mistic" Sorel |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -1931,3 +1931,5 @@ * @copyright 2015-2021 Damien "Mistic" Sorel | ||
_proto.__refreshUi = function __refreshUi() { | ||
var nbMarkers = this.getNbMarkers(); | ||
var nbMarkers = Object.values(this.markers).filter(function (m) { | ||
return !m.config.hideList; | ||
}).length; | ||
var markersButton = this.psv.navbar.getButton(MarkersButton.id, false); | ||
@@ -1934,0 +1936,0 @@ var markersListButton = this.psv.navbar.getButton(MarkersListButton.id, false); |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -66,3 +66,3 @@ * @copyright 2015-2021 Damien "Mistic" Sorel | ||
* @property {string} label | ||
* @property {string|string[]|PSV.Cubemap} panorama | ||
* @property {PSV.Panorama} panorama | ||
*/ | ||
@@ -69,0 +69,0 @@ |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -4,0 +4,0 @@ * @copyright 2015-2021 Damien "Mistic" Sorel |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -4,0 +4,0 @@ * @copyright 2015-2021 Damien "Mistic" Sorel |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -4,0 +4,0 @@ * @copyright 2015-2021 Damien "Mistic" Sorel |
/*! | ||
* Photo Sphere Viewer 4.1.0 | ||
* Photo Sphere Viewer 4.2.0-rc.1 | ||
* @copyright 2014-2015 Jérémy Heleine | ||
@@ -4,0 +4,0 @@ * @copyright 2015-2021 Damien "Mistic" Sorel |
{ | ||
"name": "photo-sphere-viewer", | ||
"version": "4.1.0", | ||
"version": "4.2.0-rc.1", | ||
"description": "A JavaScript library to display Photo Sphere panoramas", | ||
@@ -48,2 +48,3 @@ "homepage": "https://photo-sphere-viewer.js.org", | ||
"@rollup/plugin-inject": "^4.0.1", | ||
"@rollup/plugin-json": "^4.1.0", | ||
"@rollup/plugin-replace": "^2.3.1", | ||
@@ -80,2 +81,4 @@ "@vuepress/plugin-active-header-links": "^1.2.0", | ||
"vue-material": "^1.0.0-beta-11", | ||
"vue-slider-component": "^3.2.11", | ||
"vue-swatches": "^2.1.0", | ||
"vuepress": "^1.4.0", | ||
@@ -82,0 +85,0 @@ "vuepress-plugin-element-tabs": "^0.2.8" |
# Photo Sphere Viewer | ||
[![NPM version](https://img.shields.io/npm/v/photo-sphere-viewer?logo=npm)](https://www.npmjs.com/package/photo-sphere-viewer) | ||
[![NPM Downloads](https://img.shields.io/npm/dm/photo-sphere-viewer?color=f86036&label=npm&logo=npm)](https://www.npmjs.com/package/photo-sphere-viewer) | ||
[![jsDelivr Hits](https://img.shields.io/jsdelivr/npm/hm/photo-sphere-viewer?color=%23f86036&logo=jsdelivr)](https://www.jsdelivr.com/package/npm/photo-sphere-viewer) | ||
@@ -5,0 +6,0 @@ [![Build Status](https://img.shields.io/github/workflow/status/mistic100/Photo-Sphere-Viewer/CI?logo=github)](https://github.com/mistic100/Photo-Sphere-Viewer/actions) |
@@ -24,7 +24,3 @@ import { PSVError } from '../PSVError'; | ||
defaultLat : 0, | ||
sphereCorrection : { | ||
pan : 0, | ||
tilt: 0, | ||
roll: 0, | ||
}, | ||
sphereCorrection : null, | ||
moveSpeed : 1, | ||
@@ -44,2 +40,3 @@ zoomButtonIncrement: 2, | ||
panoData : null, | ||
canvasBackground : '#000', | ||
withCredentials : false, | ||
@@ -103,2 +100,6 @@ navbar : [ | ||
}, | ||
defaultLong : (defaultLong) => { | ||
// defaultLat is between 0 and PI | ||
return parseAngle(defaultLong); | ||
}, | ||
defaultLat : (defaultLat) => { | ||
@@ -105,0 +106,0 @@ // defaultLat is between -PI/2 and PI/2 |
@@ -0,1 +1,3 @@ | ||
import { PSVError } from '../PSVError'; | ||
/** | ||
@@ -9,6 +11,6 @@ * @summary General information about the system | ||
* @property {boolean} isWebGLSupported | ||
* @property {number} maxTextureWidth | ||
* @property {number} maxCanvasWidth | ||
* @property {string} mouseWheelEvent | ||
* @property {string} fullscreenEvent | ||
* @property {Function} getMaxCanvasWidth - Returns the max width of a canvas allowed by the browser | ||
* @property {Promise<boolean>} isTouchEnabled | ||
@@ -22,3 +24,2 @@ */ | ||
maxTextureWidth : 0, | ||
maxCanvasWidth : 0, | ||
mouseWheelEvent : null, | ||
@@ -40,3 +41,2 @@ fullscreenEvent : null, | ||
SYSTEM.maxTextureWidth = getMaxTextureWidth(ctx); | ||
SYSTEM.maxCanvasWidth = getMaxCanvasWidth(SYSTEM.maxTextureWidth); | ||
SYSTEM.mouseWheelEvent = getMouseWheelEvent(); | ||
@@ -47,2 +47,10 @@ SYSTEM.fullscreenEvent = getFullscreenEvent(); | ||
let maxCanvasWidth = null; | ||
SYSTEM.getMaxCanvasWidth = () => { | ||
if (maxCanvasWidth === null) { | ||
maxCanvasWidth = getMaxCanvasWidth(SYSTEM.maxTextureWidth); | ||
} | ||
return maxCanvasWidth; | ||
}; | ||
/** | ||
@@ -147,3 +155,3 @@ * @summary Tries to return a canvas webgl context | ||
return 0; | ||
throw new PSVError('Unable to detect system capabilities'); | ||
} | ||
@@ -150,0 +158,0 @@ |
@@ -85,2 +85,7 @@ import { Animation } from './Animation'; | ||
/** | ||
* @typedef {string|string[]|PSV.Cubemap} PSV.Panorama | ||
* @summary Definition of a single panorama | ||
*/ | ||
/** | ||
* @typedef {Object} PSV.Cubemap | ||
@@ -110,3 +115,3 @@ * @summary Object defining a cubemap | ||
* @property {PSV.SphereCorrection} [sphereCorrection] - new sphere correction to apply to the panorama | ||
* @property {PSV.PanoData | PSV.PanoDataProvider} [panoData] - new panorama data used for this panorama | ||
* @property {PSV.PanoData | PSV.PanoDataProvider} [panoData] - new data used for this panorama | ||
*/ | ||
@@ -129,3 +134,6 @@ | ||
* @property {number} croppedX | ||
* @property {number} croppedX | ||
* @property {number} croppedY | ||
* @property {number} poseHeading | ||
* @property {number} posePitch | ||
* @property {number} poseRoll | ||
*/ | ||
@@ -132,0 +140,0 @@ |
@@ -71,2 +71,7 @@ import { AbstractPlugin, CONSTANTS, PSVError, utils } from 'photo-sphere-viewer'; | ||
/** | ||
* @type {PSV.plugins.AutorotateKeypointsPlugin.Keypoints[]} keypoints | ||
*/ | ||
this.keypoints = null; | ||
/** | ||
* @type {PSV.plugins.MarkersPlugin} | ||
@@ -87,2 +92,3 @@ * @private | ||
delete this.markers; | ||
delete this.keypoints; | ||
@@ -89,0 +95,0 @@ delete this.state; |
@@ -974,3 +974,3 @@ import { AbstractPlugin, CONSTANTS, DEFAULTS, PSVError, registerButton, utils } from 'photo-sphere-viewer'; | ||
__refreshUi() { | ||
const nbMarkers = this.getNbMarkers(); | ||
const nbMarkers = Object.values(this.markers).filter(m => !m.config.hideList).length; | ||
const markersButton = this.psv.navbar.getButton(MarkersButton.id, false); | ||
@@ -977,0 +977,0 @@ const markersListButton = this.psv.navbar.getButton(MarkersListButton.id, false); |
@@ -13,3 +13,3 @@ import { AbstractPlugin, CONSTANTS, DEFAULTS, PSVError } from 'photo-sphere-viewer'; | ||
* @property {string} label | ||
* @property {string|string[]|PSV.Cubemap} panorama | ||
* @property {PSV.Panorama} panorama | ||
*/ | ||
@@ -16,0 +16,0 @@ |
@@ -81,2 +81,4 @@ import * as THREE from 'three'; | ||
// TODO apply the inverse transformation fro sphereCorrection/panoData[pose] | ||
return { | ||
@@ -142,2 +144,19 @@ longitude: relativeX >= Math.PI ? relativeX - Math.PI : relativeX + Math.PI, | ||
viewerCoordsToVector3(viewerPoint) { | ||
const sphereIntersect = this.getIntersection(viewerPoint, 'psvSphere'); | ||
if (sphereIntersect) { | ||
return sphereIntersect.point; | ||
} | ||
else { | ||
return null; | ||
} | ||
} | ||
/** | ||
* @summary Returns the first intersection with the cursor and having specific data | ||
* @param {PSV.Point} viewerPoint | ||
* @param {string} objectDataName | ||
* @return {external:THREE.Intersection} | ||
*/ | ||
getIntersection(viewerPoint, objectDataName) { | ||
const screen = new THREE.Vector2( | ||
@@ -150,10 +169,4 @@ 2 * viewerPoint.x / this.prop.size.width - 1, | ||
const intersects = this.psv.renderer.raycaster.intersectObjects(this.psv.renderer.scene.children); | ||
if (intersects.length === 1) { | ||
return intersects[0].point; | ||
} | ||
else { | ||
return null; | ||
} | ||
const intersects = this.psv.renderer.raycaster.intersectObjects(this.psv.renderer.scene.children, true); | ||
return intersects.find(i => i.object.userData?.[objectDataName]); | ||
} | ||
@@ -183,3 +196,3 @@ | ||
return [['x', 'y'], ['longitude', 'latitude']].some(([key1, key2]) => { | ||
return key1 in object && key2 in object; | ||
return object[key1] !== undefined && object[key2] !== undefined; | ||
}); | ||
@@ -194,3 +207,3 @@ } | ||
cleanPosition(position) { | ||
if ('x' in position && 'y' in position) { | ||
if (position.x !== undefined && position.y !== undefined) { | ||
return this.textureCoordsToSphericalCoords(position); | ||
@@ -207,3 +220,3 @@ } | ||
/** | ||
* @summary Ensure a SphereCorrection object is valide | ||
* @summary Ensure a SphereCorrection object is valid | ||
* @param {PSV.SphereCorrection} sphereCorrection | ||
@@ -210,0 +223,0 @@ * @returns {PSV.SphereCorrection} |
@@ -5,3 +5,3 @@ import * as THREE from 'three'; | ||
import { SYSTEM } from '../data/system'; | ||
import { logWarn } from '../utils'; | ||
import { isNil, logWarn } from '../utils'; | ||
import { AbstractService } from './AbstractService'; | ||
@@ -66,6 +66,7 @@ | ||
* @readonly | ||
* @protected | ||
* @package | ||
*/ | ||
this.canvasContainer = document.createElement('div'); | ||
this.canvasContainer.className = 'psv-canvas-container'; | ||
this.canvasContainer.style.background = this.psv.config.canvasBackground; | ||
this.canvasContainer.style.cursor = this.psv.config.mousemove ? 'move' : 'default'; | ||
@@ -207,14 +208,34 @@ this.psv.container.appendChild(this.canvasContainer); | ||
* @summary Apply a SphereCorrection to a Mesh | ||
* @param {PSV.SphereCorrection} sphereCorrection | ||
* @param {PSV.PanoData} [panoData] | ||
* @param {PSV.SphereCorrection} [sphereCorrection] | ||
* @param {external:THREE.Mesh} [mesh=this.mesh] | ||
* @package | ||
*/ | ||
setSphereCorrection(sphereCorrection, mesh = this.mesh) { | ||
const cleanCorrection = this.psv.dataHelper.cleanSphereCorrection(sphereCorrection); | ||
setSphereCorrection(panoData, sphereCorrection, mesh = this.mesh) { | ||
if (!isNil(panoData?.poseHeading) || !isNil(panoData?.posePitch) || !isNil(panoData?.poseRoll)) { | ||
// By Google documentation the angles are applied on the camera in order : heading, pitch, roll | ||
// here we apply the reverse transformation on the sphere | ||
mesh.rotation.set( | ||
-THREE.Math.degToRad(panoData?.posePitch || 0), | ||
-THREE.Math.degToRad(panoData?.poseHeading || 0), | ||
-THREE.Math.degToRad(panoData?.poseRoll || 0), | ||
'ZXY' | ||
); | ||
mesh.rotation.set( | ||
cleanCorrection.tilt, | ||
cleanCorrection.pan, | ||
cleanCorrection.roll | ||
); | ||
if (sphereCorrection) { | ||
logWarn('sphereCorrection was ignored because panoData already contains pose angles.'); | ||
} | ||
} | ||
else if (sphereCorrection) { | ||
const cleanCorrection = this.psv.dataHelper.cleanSphereCorrection(sphereCorrection); | ||
mesh.rotation.set( | ||
cleanCorrection.tilt, | ||
cleanCorrection.pan, | ||
cleanCorrection.roll | ||
); | ||
} | ||
else { | ||
mesh.rotation.set(0, 0, 0); | ||
} | ||
} | ||
@@ -229,3 +250,3 @@ | ||
this.renderer = new THREE.WebGLRenderer(); | ||
this.renderer = new THREE.WebGLRenderer({ alpha: true }); | ||
this.renderer.setSize(this.prop.size.width, this.prop.size.height); | ||
@@ -247,2 +268,4 @@ this.renderer.setPixelRatio(SYSTEM.pixelRatio); | ||
this.mesh.userData = { psvSphere: true }; | ||
this.scene.add(this.mesh); | ||
@@ -306,3 +329,3 @@ | ||
transition(textureData, options) { | ||
const { texture } = textureData; | ||
const { texture, panoData } = textureData; | ||
@@ -335,5 +358,3 @@ let positionProvided = this.psv.dataHelper.isExtendedPosition(options); | ||
if (options.sphereCorrection) { | ||
this.setSphereCorrection(options.sphereCorrection, mesh); | ||
} | ||
this.setSphereCorrection(panoData, options.sphereCorrection, mesh); | ||
} | ||
@@ -396,8 +417,5 @@ | ||
if (options.sphereCorrection) { | ||
this.setSphereCorrection(options.sphereCorrection); | ||
if (!this.prop.isCubemap) { | ||
this.setSphereCorrection(panoData, options.sphereCorrection); | ||
} | ||
else { | ||
this.setSphereCorrection({}); | ||
} | ||
@@ -404,0 +422,0 @@ // actually rotate the camera |
@@ -5,3 +5,3 @@ import * as THREE from 'three'; | ||
import { PSVError } from '../PSVError'; | ||
import { getXMPValue, logWarn, sum } from '../utils'; | ||
import { firstNonNull, getXMPValue, logWarn, sum } from '../utils'; | ||
import { AbstractService } from './AbstractService'; | ||
@@ -40,3 +40,3 @@ | ||
* @summary Loads the panorama texture(s) | ||
* @param {string|string[]|PSV.Cubemap} panorama | ||
* @param {PSV.Panorama} panorama | ||
* @param {PSV.PanoData | PSV.PanoDataProvider} [newPanoData] | ||
@@ -184,3 +184,2 @@ * @returns {Promise.<PSV.TextureData>} | ||
__loadEquirectangularTexture(panorama, newPanoData) { | ||
/* eslint no-shadow: ["error", {allow: ["newPanoData"]}] */ | ||
if (this.prop.isCubemap === true) { | ||
@@ -193,9 +192,9 @@ throw new PSVError('The viewer was initialized with an cubemap, cannot switch to equirectangular panorama.'); | ||
return ( | ||
newPanoData || !this.config.useXmpData | ||
!this.config.useXmpData | ||
? this.__loadImage(panorama, p => this.psv.loader.setProgress(p)) | ||
.then(img => ({ img, newPanoData })) | ||
.then(img => ({ img: img, xmpPanoData: null })) | ||
: this.__loadXMP(panorama, p => this.psv.loader.setProgress(p)) | ||
.then(newPanoData => this.__loadImage(panorama).then(img => ({ img, newPanoData }))) | ||
.then(xmpPanoData => this.__loadImage(panorama).then(img => ({ img, xmpPanoData }))) | ||
) | ||
.then(({ img, newPanoData }) => { | ||
.then(({ img, xmpPanoData }) => { | ||
if (typeof newPanoData === 'function') { | ||
@@ -206,9 +205,12 @@ // eslint-disable-next-line no-param-reassign | ||
const panoData = newPanoData || { | ||
fullWidth : img.width, | ||
fullHeight : img.height, | ||
croppedWidth : img.width, | ||
croppedHeight: img.height, | ||
croppedX : 0, | ||
croppedY : 0, | ||
const panoData = { | ||
fullWidth : firstNonNull(newPanoData?.fullWidth, xmpPanoData?.fullWidth, img.width), | ||
fullHeight : firstNonNull(newPanoData?.fullHeight, xmpPanoData?.fullHeight, img.height), | ||
croppedWidth : firstNonNull(newPanoData?.croppedWidth, xmpPanoData?.croppedWidth, img.width), | ||
croppedHeight: firstNonNull(newPanoData?.croppedHeight, xmpPanoData?.croppedHeight, img.height), | ||
croppedX : firstNonNull(newPanoData?.croppedX, xmpPanoData?.croppedX, 0), | ||
croppedY : firstNonNull(newPanoData?.croppedY, xmpPanoData?.croppedY, 0), | ||
poseHeading : firstNonNull(newPanoData?.poseHeading, xmpPanoData?.poseHeading), | ||
posePitch : firstNonNull(newPanoData?.posePitch, xmpPanoData?.posePitch), | ||
poseRoll : firstNonNull(newPanoData?.poseRoll, xmpPanoData?.poseRoll), | ||
}; | ||
@@ -242,21 +244,18 @@ | ||
const data = binary.substring(a, b); | ||
let panoData = null; | ||
if (a !== -1 && b !== -1 && data.indexOf('GPano:') !== -1) { | ||
panoData = { | ||
fullWidth : parseInt(getXMPValue(data, 'FullPanoWidthPixels'), 10), | ||
fullHeight : parseInt(getXMPValue(data, 'FullPanoHeightPixels'), 10), | ||
croppedWidth : parseInt(getXMPValue(data, 'CroppedAreaImageWidthPixels'), 10), | ||
croppedHeight: parseInt(getXMPValue(data, 'CroppedAreaImageHeightPixels'), 10), | ||
croppedX : parseInt(getXMPValue(data, 'CroppedAreaLeftPixels'), 10), | ||
croppedY : parseInt(getXMPValue(data, 'CroppedAreaTopPixels'), 10), | ||
return { | ||
fullWidth : getXMPValue(data, 'FullPanoWidthPixels'), | ||
fullHeight : getXMPValue(data, 'FullPanoHeightPixels'), | ||
croppedWidth : getXMPValue(data, 'CroppedAreaImageWidthPixels'), | ||
croppedHeight: getXMPValue(data, 'CroppedAreaImageHeightPixels'), | ||
croppedX : getXMPValue(data, 'CroppedAreaLeftPixels'), | ||
croppedY : getXMPValue(data, 'CroppedAreaTopPixels'), | ||
poseHeading : getXMPValue(data, 'PoseHeadingDegrees'), | ||
posePitch : getXMPValue(data, 'PosePitchDegrees'), | ||
poseRoll : getXMPValue(data, 'PoseRollDegrees'), | ||
}; | ||
if (!panoData.fullWidth || !panoData.fullHeight || !panoData.croppedWidth || !panoData.croppedHeight) { | ||
logWarn('invalid XMP data'); | ||
panoData = null; | ||
} | ||
} | ||
return panoData; | ||
return null; | ||
}); | ||
@@ -282,10 +281,12 @@ } | ||
const ratio = SYSTEM.maxCanvasWidth / panoData.fullWidth; | ||
const ratio = SYSTEM.getMaxCanvasWidth() / panoData.fullWidth; | ||
resizedPanoData.fullWidth *= ratio; | ||
resizedPanoData.fullHeight *= ratio; | ||
resizedPanoData.croppedWidth *= ratio; | ||
resizedPanoData.croppedHeight *= ratio; | ||
resizedPanoData.croppedX *= ratio; | ||
resizedPanoData.croppedY *= ratio; | ||
if (ratio < 1) { | ||
resizedPanoData.fullWidth *= ratio; | ||
resizedPanoData.fullHeight *= ratio; | ||
resizedPanoData.croppedWidth *= ratio; | ||
resizedPanoData.croppedHeight *= ratio; | ||
resizedPanoData.croppedX *= ratio; | ||
resizedPanoData.croppedY *= ratio; | ||
} | ||
@@ -361,3 +362,3 @@ const buffer = document.createElement('canvas'); | ||
const buffer = document.createElement('canvas'); | ||
const ratio = SYSTEM.maxCanvasWidth / img.width; | ||
const ratio = SYSTEM.getMaxCanvasWidth() / img.width; | ||
@@ -364,0 +365,0 @@ buffer.width = img.width * ratio; |
@@ -109,2 +109,23 @@ /** | ||
/** | ||
* @summary Gets the position of an element in the viewer without reflow | ||
* @description Will gives the same result as getBoundingClientRect() as soon as there are no CSS transforms | ||
* @memberOf PSV.utils | ||
* @param {HTMLElement} el | ||
* @return {{left: number, top: number}} | ||
*/ | ||
export function getPosition(el) { | ||
let left = 0; | ||
let top = 0; | ||
let test = el; | ||
while (test) { | ||
left += (test.offsetLeft - test.scrollLeft + test.clientLeft); | ||
top += (test.offsetTop - test.scrollTop + test.clientTop); | ||
test = test.offsetParent; | ||
} | ||
return { left, top }; | ||
} | ||
/** | ||
* @summary Map between keyboard events `keyCode|which` and `key` | ||
@@ -111,0 +132,0 @@ * @memberOf PSV.utils |
@@ -87,2 +87,3 @@ /** | ||
* Returns the distance between two points on a sphere of radius one | ||
* {@link http://www.movable-type.co.uk/scripts/latlong.html} | ||
* @memberOf PSV.utils | ||
@@ -101,1 +102,18 @@ * @param {number[]} p1 | ||
} | ||
/** | ||
* Returns the bearing between two points | ||
* {@link http://www.movable-type.co.uk/scripts/latlong.html} | ||
* @memberOf PSV.utils | ||
* @param {number[]} p1 | ||
* @param {number[]} p2 | ||
* @return {number} | ||
*/ | ||
export function bearing(p1, p2) { | ||
const [λ1, φ1] = p1; | ||
const [λ2, φ2] = p2; | ||
const y = Math.sin(λ2 - λ1) * Math.cos(φ2); | ||
const x = Math.cos(φ1) * Math.sin(φ2) - Math.sin(φ1) * Math.cos(φ2) * Math.cos(λ2 - λ1); | ||
return Math.atan2(y, x); | ||
} |
@@ -185,1 +185,26 @@ /** | ||
} | ||
/** | ||
* @summary Returns if a valu is null or undefined | ||
* @param {*} val | ||
* @return {boolean} | ||
*/ | ||
export function isNil(val) { | ||
return val === null || val === undefined; | ||
} | ||
/** | ||
* @summary Returns the first non null non undefined parameter | ||
* @memberOf PSV.utils | ||
* @param {*} values | ||
* @return {*} | ||
*/ | ||
export function firstNonNull(...values) { | ||
for (const val of values) { | ||
if (!isNil(val)) { | ||
return val; | ||
} | ||
} | ||
return undefined; | ||
} |
@@ -19,3 +19,3 @@ import * as THREE from 'three'; | ||
* @param {string} attr | ||
* @returns (string) | ||
* @returns (number) | ||
*/ | ||
@@ -26,3 +26,4 @@ export function getXMPValue(data, attr) { | ||
if (result !== null) { | ||
return result[1]; | ||
const val = parseInt(result[1], 10); | ||
return isNaN(val) ? null : val; | ||
} | ||
@@ -33,3 +34,4 @@ | ||
if (result !== null) { | ||
return result[1]; | ||
const val = parseInt(result[1], 10); | ||
return isNaN(val) ? null : val; | ||
} | ||
@@ -36,0 +38,0 @@ |
@@ -279,5 +279,8 @@ import assert from 'assert'; | ||
getXMPValue(data, 'CroppedAreaLeftPixels'), | ||
getXMPValue(data, 'CroppedAreaTopPixels') | ||
getXMPValue(data, 'CroppedAreaTopPixels'), | ||
getXMPValue(data, 'PoseHeadingDegrees'), | ||
getXMPValue(data, 'PosePitchDegrees'), | ||
getXMPValue(data, 'PoseRollDegrees'), | ||
], [ | ||
'5376', '2688', '5376', '2688', '0', '0' | ||
5376, 2688, 5376, 2688, 0, 0, 270, 0, 0 | ||
]) | ||
@@ -306,5 +309,8 @@ }); | ||
getXMPValue(data, 'CroppedAreaLeftPixels'), | ||
getXMPValue(data, 'CroppedAreaTopPixels') | ||
getXMPValue(data, 'CroppedAreaTopPixels'), | ||
getXMPValue(data, 'PoseHeadingDegrees'), | ||
getXMPValue(data, 'PosePitchDegrees'), | ||
getXMPValue(data, 'PoseRollDegrees'), | ||
], [ | ||
'5376', '2688', '5376', '2688', '0', '0' | ||
5376, 2688, 5376, 2688, 0, 0, 270, 0, 0 | ||
]) | ||
@@ -311,0 +317,0 @@ }); |
@@ -55,3 +55,3 @@ import * as THREE from 'three'; | ||
if (SYSTEM.maxCanvasWidth === 0 || SYSTEM.maxTextureWidth === 0) { | ||
if (SYSTEM.maxTextureWidth === 0) { | ||
throw new PSVError('Unable to detect system capabilities'); | ||
@@ -427,3 +427,3 @@ } | ||
* If another loading is already in progress it will be aborted. | ||
* @param {string|string[]|PSV.Cubemap} path - URL of the new panorama file | ||
* @param {PSV.Panorama} path - URL of the new panorama file | ||
* @param {PSV.PanoramaOptions} [options] | ||
@@ -437,2 +437,3 @@ * @returns {Promise} | ||
// apply default parameters on first load | ||
if (!this.prop.ready) { | ||
@@ -504,6 +505,4 @@ if (!('longitude' in options) && !this.prop.isCubemap) { | ||
this.renderer.setTexture(textureData); | ||
this.renderer.setSphereCorrection(textureData.panoData, options.sphereCorrection); | ||
if (options.sphereCorrection) { | ||
this.renderer.setSphereCorrection(options.sphereCorrection); | ||
} | ||
if (zoomProvided) { | ||
@@ -523,3 +522,3 @@ this.zoom(options.zoom); | ||
this.prop.loadingPromise = this.textureLoader.loadTexture(this.config.panorama) | ||
this.prop.loadingPromise = this.textureLoader.loadTexture(this.config.panorama, options.panoData) | ||
.then((textureData) => { | ||
@@ -568,3 +567,3 @@ this.loader.hide(); | ||
case 'sphereCorrection': | ||
this.renderer.setSphereCorrection(value); | ||
this.renderer.setSphereCorrection(this.prop.panoData, value); | ||
break; | ||
@@ -587,2 +586,6 @@ | ||
case 'canvasBackground': | ||
this.renderer.canvasContainer.style.background = this.config.canvasBackground; | ||
break; | ||
default: | ||
@@ -589,0 +592,0 @@ break; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Native code
Supply chain riskContains native code (e.g., compiled binaries or shared libraries). Including native code can obscure malicious behavior.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1447080
124
22959
20
46
1
1