|
|
@@ -67,6 +67,7 @@ var config, |
|
|
|
externalEventListeners = {}, |
|
|
|
specifiedPhotoSphereExcludes = [], |
|
|
|
update = false, // Should we update when still to render dynamic content |
|
|
|
eps = 1e-6, |
|
|
|
hotspotsCreated = false; |
|
|
|
|
|
|
|
var defaultConfig = { |
|
|
@@ -91,6 +92,7 @@ var defaultConfig = { |
|
|
|
northOffset: 0, |
|
|
|
showFullscreenCtrl: true, |
|
|
|
dynamic: false, |
|
|
|
dynamicUpdate: false, |
|
|
|
doubleClickZoom: true, |
|
|
|
keyboardZoom: true, |
|
|
|
mouseZoom: true, |
|
|
@@ -107,6 +109,7 @@ var defaultConfig = { |
|
|
|
crossOrigin: 'anonymous', |
|
|
|
touchPanSpeedCoeffFactor: 1, |
|
|
|
capturedKeyNumbers: [16, 17, 27, 37, 38, 39, 40, 61, 65, 68, 83, 87, 107, 109, 173, 187, 189], |
|
|
|
friction: 0.15 |
|
|
|
}; |
|
|
|
|
|
|
|
// Translatable / configurable strings |
|
|
@@ -477,10 +480,10 @@ function onImageLoad() { |
|
|
|
if (config.doubleClickZoom) { |
|
|
|
dragFix.addEventListener('dblclick', onDocumentDoubleClick, false); |
|
|
|
} |
|
|
|
uiContainer.addEventListener('mozfullscreenchange', onFullScreenChange, false); |
|
|
|
uiContainer.addEventListener('webkitfullscreenchange', onFullScreenChange, false); |
|
|
|
uiContainer.addEventListener('msfullscreenchange', onFullScreenChange, false); |
|
|
|
uiContainer.addEventListener('fullscreenchange', onFullScreenChange, false); |
|
|
|
container.addEventListener('mozfullscreenchange', onFullScreenChange, false); |
|
|
|
container.addEventListener('webkitfullscreenchange', onFullScreenChange, false); |
|
|
|
container.addEventListener('msfullscreenchange', onFullScreenChange, false); |
|
|
|
container.addEventListener('fullscreenchange', onFullScreenChange, false); |
|
|
|
window.addEventListener('resize', onDocumentResize, false); |
|
|
|
window.addEventListener('orientationchange', onDocumentResize, false); |
|
|
|
if (!config.disableKeyboardCtrl) { |
|
|
@@ -658,8 +661,9 @@ function aboutMessage(event) { |
|
|
|
function mousePosition(event) { |
|
|
|
var bounds = container.getBoundingClientRect(); |
|
|
|
var pos = {}; |
|
|
|
pos.x = event.clientX - bounds.left; |
|
|
|
pos.y = event.clientY - bounds.top; |
|
|
|
// pageX / pageY needed for iOS |
|
|
|
pos.x = (event.clientX || event.pageX) - bounds.left; |
|
|
|
pos.y = (event.clientY || event.pageY) - bounds.top; |
|
|
|
return pos; |
|
|
|
} |
|
|
|
|
|
|
@@ -1245,19 +1249,19 @@ function keyRepeat() { |
|
|
|
// "Inertia" |
|
|
|
if (diff > 0 && !config.autoRotate) { |
|
|
|
// "Friction" |
|
|
|
var friction = 0.85; |
|
|
|
|
|
|
|
var slowDownFactor = 1 - config.friction; |
|
|
|
|
|
|
|
// Yaw |
|
|
|
if (!keysDown[4] && !keysDown[5] && !keysDown[8] && !keysDown[9] && !animatedMove.yaw) { |
|
|
|
config.yaw += speed.yaw * diff * friction; |
|
|
|
config.yaw += speed.yaw * diff * slowDownFactor; |
|
|
|
} |
|
|
|
// Pitch |
|
|
|
if (!keysDown[2] && !keysDown[3] && !keysDown[6] && !keysDown[7] && !animatedMove.pitch) { |
|
|
|
config.pitch += speed.pitch * diff * friction; |
|
|
|
config.pitch += speed.pitch * diff * slowDownFactor; |
|
|
|
} |
|
|
|
// Zoom |
|
|
|
if (!keysDown[0] && !keysDown[1] && !animatedMove.hfov) { |
|
|
|
setHfov(config.hfov + speed.hfov * diff * friction); |
|
|
|
setHfov(config.hfov + speed.hfov * diff * slowDownFactor); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@@ -1300,11 +1304,7 @@ function animateMove(axis) { |
|
|
|
t.endPosition === t.startPosition) { |
|
|
|
result = t.endPosition; |
|
|
|
speed[axis] = 0; |
|
|
|
var callback = animatedMove[axis].callback, |
|
|
|
callbackArgs = animatedMove[axis].callbackArgs; |
|
|
|
delete animatedMove[axis]; |
|
|
|
if (typeof callback == 'function') |
|
|
|
callback(callbackArgs); |
|
|
|
} |
|
|
|
config[axis] = result; |
|
|
|
} |
|
|
@@ -1329,7 +1329,7 @@ function onDocumentResize() { |
|
|
|
//animateInit(); |
|
|
|
|
|
|
|
// Kludge to deal with WebKit regression: https://bugs.webkit.org/show_bug.cgi?id=93525 |
|
|
|
onFullScreenChange(); |
|
|
|
onFullScreenChange('resize'); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -1372,6 +1372,7 @@ function animate() { |
|
|
|
} else if (renderer && (renderer.isLoading() || (config.dynamic === true && update))) { |
|
|
|
requestAnimationFrame(animate); |
|
|
|
} else { |
|
|
|
fireEvent('animatefinished', {pitch: _this.getPitch(), yaw: _this.getYaw(), hfov: _this.getHfov()}); |
|
|
|
animating = false; |
|
|
|
prevTime = undefined; |
|
|
|
var autoRotateStartTime = config.autoRotateInactivityDelay - |
|
|
@@ -1398,12 +1399,6 @@ function render() { |
|
|
|
var tmpyaw; |
|
|
|
|
|
|
|
if (loaded) { |
|
|
|
if (config.yaw > 180) { |
|
|
|
config.yaw -= 360; |
|
|
|
} else if (config.yaw < -180) { |
|
|
|
config.yaw += 360; |
|
|
|
} |
|
|
|
|
|
|
|
// Keep a tmp value of yaw for autoRotate comparison later |
|
|
|
tmpyaw = config.yaw; |
|
|
|
|
|
|
@@ -1438,6 +1433,12 @@ function render() { |
|
|
|
config.yaw = Math.max(minYaw, Math.min(maxYaw, config.yaw)); |
|
|
|
} |
|
|
|
|
|
|
|
if (config.yaw > 180) { |
|
|
|
config.yaw -= 360; |
|
|
|
} else if (config.yaw < -180) { |
|
|
|
config.yaw += 360; |
|
|
|
} |
|
|
|
|
|
|
|
// Check if we autoRotate in a limited by min and max yaw |
|
|
|
// If so reverse direction |
|
|
|
if (config.autoRotate !== false && tmpyaw != config.yaw && |
|
|
@@ -1783,10 +1784,12 @@ function destroyHotSpots() { |
|
|
|
if (hs) { |
|
|
|
for (var i = 0; i < hs.length; i++) { |
|
|
|
var current = hs[i].div; |
|
|
|
while(current.parentNode != renderContainer) { |
|
|
|
current = current.parentNode; |
|
|
|
if (current) { |
|
|
|
while (current.parentNode && current.parentNode != renderContainer) { |
|
|
|
current = current.parentNode; |
|
|
|
} |
|
|
|
renderContainer.removeChild(current); |
|
|
|
} |
|
|
|
renderContainer.removeChild(current); |
|
|
|
delete hs[i].div; |
|
|
|
} |
|
|
|
} |
|
|
@@ -2104,15 +2107,16 @@ function toggleFullscreen() { |
|
|
|
* Event handler for fullscreen changes. |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
function onFullScreenChange() { |
|
|
|
if (document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement) { |
|
|
|
function onFullScreenChange(resize) { |
|
|
|
if (document.fullscreenElement || document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen || document.msFullscreenElement) { |
|
|
|
controls.fullscreen.classList.add('pnlm-fullscreen-toggle-button-active'); |
|
|
|
fullscreenActive = true; |
|
|
|
} else { |
|
|
|
controls.fullscreen.classList.remove('pnlm-fullscreen-toggle-button-active'); |
|
|
|
fullscreenActive = false; |
|
|
|
} |
|
|
|
fireEvent('fullscreenchange', fullscreenActive); |
|
|
|
if (resize !== 'resize') |
|
|
|
fireEvent('fullscreenchange', fullscreenActive); |
|
|
|
// Resize renderer (deal with browser quirks and fixes #155) |
|
|
|
renderer.resize(); |
|
|
|
setHfov(config.hfov); |
|
|
@@ -2287,6 +2291,13 @@ function loadScene(sceneId, targetPitch, targetYaw, targetHfov, fadeDone) { |
|
|
|
} |
|
|
|
fireEvent('scenechange', sceneId); |
|
|
|
load(); |
|
|
|
|
|
|
|
// Properly handle switching to dynamic scenes |
|
|
|
update = config.dynamicUpdate === true; |
|
|
|
if (config.dynamic) { |
|
|
|
panoImage = config.panorama; |
|
|
|
onImageLoad(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@@ -2386,16 +2397,22 @@ this.getPitch = function() { |
|
|
|
* @returns {Viewer} `this` |
|
|
|
*/ |
|
|
|
this.setPitch = function(pitch, animated, callback, callbackArgs) { |
|
|
|
latestInteraction = Date.now(); |
|
|
|
if (Math.abs(pitch - config.pitch) <= eps) { |
|
|
|
if (typeof callback == 'function') |
|
|
|
callback(callbackArgs); |
|
|
|
return this; |
|
|
|
} |
|
|
|
animated = animated == undefined ? 1000: Number(animated); |
|
|
|
if (animated) { |
|
|
|
animatedMove.pitch = { |
|
|
|
'startTime': Date.now(), |
|
|
|
'startPosition': config.pitch, |
|
|
|
'endPosition': pitch, |
|
|
|
'duration': animated, |
|
|
|
'callback': callback, |
|
|
|
'callbackArgs': callbackArgs |
|
|
|
'duration': animated |
|
|
|
} |
|
|
|
if (typeof callback == 'function') |
|
|
|
setTimeout(function(){callback(callbackArgs)}, animated); |
|
|
|
} else { |
|
|
|
config.pitch = pitch; |
|
|
|
} |
|
|
@@ -2447,6 +2464,12 @@ this.getYaw = function() { |
|
|
|
* @returns {Viewer} `this` |
|
|
|
*/ |
|
|
|
this.setYaw = function(yaw, animated, callback, callbackArgs) { |
|
|
|
latestInteraction = Date.now(); |
|
|
|
if (Math.abs(yaw - config.yaw) <= eps) { |
|
|
|
if (typeof callback == 'function') |
|
|
|
callback(callbackArgs); |
|
|
|
return this; |
|
|
|
} |
|
|
|
animated = animated == undefined ? 1000: Number(animated); |
|
|
|
yaw = ((yaw + 180) % 360) - 180 // Keep in bounds |
|
|
|
if (animated) { |
|
|
@@ -2460,10 +2483,10 @@ this.setYaw = function(yaw, animated, callback, callbackArgs) { |
|
|
|
'startTime': Date.now(), |
|
|
|
'startPosition': config.yaw, |
|
|
|
'endPosition': yaw, |
|
|
|
'duration': animated, |
|
|
|
'callback': callback, |
|
|
|
'callbackArgs': callbackArgs |
|
|
|
'duration': animated |
|
|
|
} |
|
|
|
if (typeof callback == 'function') |
|
|
|
setTimeout(function(){callback(callbackArgs)}, animated); |
|
|
|
} else { |
|
|
|
config.yaw = yaw; |
|
|
|
} |
|
|
@@ -2515,16 +2538,22 @@ this.getHfov = function() { |
|
|
|
* @returns {Viewer} `this` |
|
|
|
*/ |
|
|
|
this.setHfov = function(hfov, animated, callback, callbackArgs) { |
|
|
|
latestInteraction = Date.now(); |
|
|
|
if (Math.abs(hfov - config.hfov) <= eps) { |
|
|
|
if (typeof callback == 'function') |
|
|
|
callback(callbackArgs); |
|
|
|
return this; |
|
|
|
} |
|
|
|
animated = animated == undefined ? 1000: Number(animated); |
|
|
|
if (animated) { |
|
|
|
animatedMove.hfov = { |
|
|
|
'startTime': Date.now(), |
|
|
|
'startPosition': config.hfov, |
|
|
|
'endPosition': constrainHfov(hfov), |
|
|
|
'duration': animated, |
|
|
|
'callback': callback, |
|
|
|
'callbackArgs': callbackArgs |
|
|
|
'duration': animated |
|
|
|
} |
|
|
|
if (typeof callback == 'function') |
|
|
|
setTimeout(function(){callback(callbackArgs)}, animated); |
|
|
|
} else { |
|
|
|
setHfov(hfov); |
|
|
|
} |
|
|
@@ -2570,16 +2599,20 @@ this.setHfovBounds = function(bounds) { |
|
|
|
*/ |
|
|
|
this.lookAt = function(pitch, yaw, hfov, animated, callback, callbackArgs) { |
|
|
|
animated = animated == undefined ? 1000: Number(animated); |
|
|
|
if (pitch !== undefined) { |
|
|
|
if (pitch !== undefined && Math.abs(pitch - config.pitch) > eps) { |
|
|
|
this.setPitch(pitch, animated, callback, callbackArgs); |
|
|
|
callback = undefined; |
|
|
|
} |
|
|
|
if (yaw !== undefined) { |
|
|
|
if (yaw !== undefined && Math.abs(yaw - config.yaw) > eps) { |
|
|
|
this.setYaw(yaw, animated, callback, callbackArgs); |
|
|
|
callback = undefined; |
|
|
|
} |
|
|
|
if (hfov !== undefined) |
|
|
|
if (hfov !== undefined && Math.abs(hfov - config.hfov) > eps) { |
|
|
|
this.setHfov(hfov, animated, callback, callbackArgs); |
|
|
|
callback = undefined; |
|
|
|
} |
|
|
|
if (typeof callback == 'function') |
|
|
|
callback(callbackArgs); |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
@@ -2683,6 +2716,16 @@ this.stopAutoRotate = function() { |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
|
* Stops all movement. |
|
|
|
* @memberof Viewer |
|
|
|
* @instance |
|
|
|
*/ |
|
|
|
this.stopMovement = function() { |
|
|
|
stopAnimation(); |
|
|
|
speed = {'yaw': 0, 'pitch': 0, 'hfov': 0}; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Returns the panorama renderer. |
|
|
|
* @memberof Viewer |
|
|
|
* @instance |
|
|
@@ -3007,14 +3050,10 @@ function fireEvent(type) { |
|
|
|
*/ |
|
|
|
this.destroy = function() { |
|
|
|
if (renderer) |
|
|
|
renderer.destroy() |
|
|
|
renderer.destroy(); |
|
|
|
if (listenersAdded) { |
|
|
|
dragFix.removeEventListener('mousedown', onDocumentMouseDown, false); |
|
|
|
dragFix.removeEventListener('dblclick', onDocumentDoubleClick, false); |
|
|
|
document.removeEventListener('mousemove', onDocumentMouseMove, false); |
|
|
|
document.removeEventListener('mouseup', onDocumentMouseUp, false); |
|
|
|
container.removeEventListener('mousewheel', onDocumentMouseWheel, false); |
|
|
|
container.removeEventListener('DOMMouseScroll', onDocumentMouseWheel, false); |
|
|
|
container.removeEventListener('mozfullscreenchange', onFullScreenChange, false); |
|
|
|
container.removeEventListener('webkitfullscreenchange', onFullScreenChange, false); |
|
|
|
container.removeEventListener('msfullscreenchange', onFullScreenChange, false); |
|
|
@@ -3025,18 +3064,9 @@ this.destroy = function() { |
|
|
|
container.removeEventListener('keyup', onDocumentKeyUp, false); |
|
|
|
container.removeEventListener('blur', clearKeys, false); |
|
|
|
document.removeEventListener('mouseleave', onDocumentMouseUp, false); |
|
|
|
dragFix.removeEventListener('touchstart', onDocumentTouchStart, false); |
|
|
|
dragFix.removeEventListener('touchmove', onDocumentTouchMove, false); |
|
|
|
dragFix.removeEventListener('touchend', onDocumentTouchEnd, false); |
|
|
|
dragFix.removeEventListener('pointerdown', onDocumentPointerDown, false); |
|
|
|
dragFix.removeEventListener('pointermove', onDocumentPointerMove, false); |
|
|
|
dragFix.removeEventListener('pointerup', onDocumentPointerUp, false); |
|
|
|
dragFix.removeEventListener('pointerleave', onDocumentPointerUp, false); |
|
|
|
} |
|
|
|
container.innerHTML = ''; |
|
|
|
container.classList.remove('pnlm-container'); |
|
|
|
uiContainer.classList.remove('pnlm-grab'); |
|
|
|
uiContainer.classList.remove('pnlm-grabbing'); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|