Open mpetroff opened 5 years ago
Hi Matthew
This would be a great feature.
Within my tours I written a script to make three consecutive zooms. The first focus the view in the right general direction, the next zooms in to around an HFOV of say 55, the final zoom to a HFOV of say 15, which may also move the focus left or right, up or down. It's good for conveying the impression of moving along a path, for example.
mhh, zoom in for transitions in walkthroughs would be nice. I've implemented some kind of workaround, to get a feeling of moving in....
The main idea is after clicking a hotspot:
But there is some work to be done in advance.
here a brief sketch of my way (for details, just ask):
set all scenes initally to Hfov: 120, we zoom in with sceneLoadListener () later
all HotSpots must not contain "sceneId," instead add "clickHandlerFunc": onHotSpotClicked, "clickHandlerArgs" : {target:sSceneID} to the hotspot --- to prevent autoload, sSceneID is the id where the hotspot leads to
add hotspot listener function:
var onHotSpotClicked = function(e, clickHandlerArgs)
{
setTimeout(function(){LookAndWait(viewer.getHfov(), dTimeLookAtHotSpot);},10); //--- first look directly at the hotspot
LookAndWait(50, dTimeZoomInHotSpot); //--- then zoom in
setTimeout(function(){viewer.loadScene(clickHandlerArgs.target, dLastPitch, dLastYaw, 120);}, dTimeToLoad); // then load the new scene
};
you need a need some function to wait for finished animations:
function LookAndWait(dHfov, dTime) // Initiate LookAt / Zoom
{
var pZ = dLastPitch; // Or other pan angle to Zoom in on.
var yZ = dLastYaw ; // Or other yaw angle to Zoom in on.
var vZ = dHfov ; // Or other Hfov angle to Zoom in on.
var pS = dTime ; // Or other zoom speed
viewer.lookAt(pZ, yZ, vZ, pS);
setTimeout(function(){wait_for_view(dLastPitch, dLastYaw, vZ);},1000);
console.log("LookAndWait(): pZ: "+pZ +" yZ: " +yZ + " vZ:" +vZ + " pS: " + pS);
}
and
function wait_for_view(dPitch, dYaw, dHfov)
{
var iCnt = 0;
pI=Math.round(viewer.getPitch()); // get actual pitch and round
yI=Math.round(viewer.getYaw()); // get actual yaw and round
vI=Math.round(viewer.getHfov()); // get actual Hfov and round
if(yI>180){yI=yI-360;viewer.setYaw(yI,0);}
if(yI<-180){yI=yI+360;viewer.setYaw(yI,0);}
if (pI===dPitch && yI===dYaw && vI===dHfov) // Has LookAt finished
{
return true;
}
else
{
setTimeout(function(){wait_for_view (dPitch, dYaw, dHfov);},10);
}
}
viewer.on('load', sceneLoadListener)
;// this function is called after an image is loaded, aka if someone click on a hot spot:
function sceneLoadListener()
{
console.log("sceneLoadListener() load " + viewer.getScene() +
" done - looking at LP: " + viewer.getPitch() + " LY: " + viewer.getYaw() + " HF: " +
" setting view to LP: " + dLastPitch + "LY:" + dLastYaw);
//--- zoom a little bit into current viewing direction
LookAndWait(110, dTimeZoomInAfterLoad);
};
var dLastPitch;
var dLastYaw;
var dLastHfov;
and add a onmousedown handler in the displaying div: <div id = "panorama" onmousedown="inMouseDown(event)">
with panorama is the div you gave the pannellum.viewer
//--- stores viewing coordinates of last mouse click (calculates real coordinates to viewer coordinates)
//--- this funcion must be set in the html div
function inMouseDown(e)
{
var coords = viewer.mouseEventToCoords(e);
dLastPitch = coords[0];
dLastYaw = coords[1];
dLastHfov = viewer.getHfov();
console.log(logPOVstr("inMouseDown: "));
};
this worked for me. Here are my timing values used:
var dTimeLookAtHotSpot = 400; // [ms] , after clicking a hotspot, time to focus on hotspot
var dTimeZoomInHotSpot = 1000; // [ms] , after clicking a hotspot, time to zoom into the hotspot
var dTimeZoomInAfterLoad = 500; // [ms] , after clicking a hotspot and its loaded, time to zoom in a little bit
var dTimeToLoad = 1000; // [ms] , setTimeout time to wait for finisheing loading new a scene
Hi HubertK42
An interesting idea. I had tried something similar (in loading the next scene at 120 degrees and zooming to 100 hfov) but took it out of my js due to problems with older partial panoramas not being able to zoom out that far. I’ll have to look at reinstating it.
Best wishes
Derek
Sent from my phone.
On 13 Jan 2020, at 19:30, HubertK42 notifications@github.com wrote:
mhh, zoom in for transitions in walkthroughs would be nice. I've implemented some kind of workaround, to get a feeling of moving in....
The main idea is after clicking a hotspot:
Focus on the Hotspot Zoom in the Hotspt Load new scene (with zoom out parameters, Hfov set to 120) Zoom back (this means zoom a little bit in) to normal view (Hfov set to 110) But there is some work to be done in advance.
here a brief sketch of my way (for details, just ask):
set all scenes initally to Hfov: 110, we zoom in with sceneLoadListener () later
all HotSpots must not contain "sceneId," instead add "clickHandlerFunc": onHotSpotClicked, "clickHandlerArgs" : {target:sSceneID} to the hotspot --- to prevent autoload, sSceneID is the id where the hotspot leads to
add hotspot listener function:
var onHotSpotClicked = function(e, clickHandlerArgs) { setTimeout(function(){LookAndWait(viewer.getHfov(), dTimeLookAtHotSpot);},10); //--- first look directly at the hotspot LookAndWait(50, dTimeZoomInHotSpot); //--- then zoom in setTimeout(function(){viewer.loadScene(clickHandlerArgs.target, dLastPitch, dLastYaw, 120);}, dTimeToLoad); // then load the new scene };
you need a need some function to wait for finished animations: function LookAndWait(dHfov, dTime) // Initiate LookAt / Zoom { var pZ = dLastPitch; // Or other pan angle to Zoom in on. var yZ = dLastYaw ; // Or other yaw angle to Zoom in on. var vZ = dHfov ; // Or other Hfov angle to Zoom in on. var pS = dTime ; // Or other zoom speed viewer.lookAt(pZ, yZ, vZ, pS); setTimeout(function(){wait_for_view(dLastPitch, dLastYaw, vZ);},1000); console.log("LookAndWait(): pZ: "+pZ +" yZ: " +yZ + " vZ:" +vZ + " pS: " + pS); } and
function wait_for_view(dPitch, dYaw, dHfov) { var iCnt = 0; pI=Math.round(viewer.getPitch()); // get actual pitch and round yI=Math.round(viewer.getYaw()); // get actual yaw and round vI=Math.round(viewer.getHfov()); // get actual Hfov and round
if(yI>180){yI=yI-360;viewer.setYaw(yI,0);}
if(yI<-180){yI=yI+360;viewer.setYaw(yI,0);}if (pI===dPitch && yI===dYaw && vI===dHfov) // Has LookAt finished
{
return true; } else {
setTimeout(function(){wait_for_view (dPitch, dYaw, dHfov);},10);
} }add the sceneLoadListener : viewer.on('load', sceneLoadListener); // this function is called after an image is loaded, aka if someone clickt on a hot spot:
function sceneLoadListener() { console.log("sceneLoadListener() load " + viewer.getScene() + " done - looking at LP: " + viewer.getPitch() + " LY: " + viewer.getYaw() + " HF: " + " setting view to LP: " + dLastPitch + "LY:" + dLastYaw);
//--- zoom a little bit into current viewing direction LookAndWait(110, dTimeZoomInAfterLoad); };
further more remeber last clicked mousecoordinates var dLastPitch; var dLastYaw; var dLastHfov; and add a onmousedown handler in the displaying div:
with panorama is the div you gave the pannellum.viewer //--- stores viewing coordinates of last mouse click (calculates real coordinates to viewer coordinates) //--- this funcion must be set in the html div function inMouseDown(e) { var coords = viewer.mouseEventToCoords(e);
dLastPitch = coords[0]; dLastYaw = coords[1]; dLastHfov = viewer.getHfov();
console.log(logPOVstr("inMouseDown: ")); };
this worked for me. Here are my timing values used: var dTimeLookAtHotSpot = 400; // [ms] , after clicking a hotspot, time to focus on hotspot var dTimeZoomInHotSpot = 1000; // [ms] , after clicking a hotspot, time to zoom into the hotspot var dTimeZoomInAfterLoad = 500; // [ms] , after clicking a hotspot and its loaded, time to zoom in a little bit var dTimeToLoad = 1000; // [ms] , setTimeout time to wait for finisheing loading new a scene
— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or unsubscribe.
Hello my experts programmers. I'm testing my limits here, but after a few days of work, I could not get this "zoom" effect to work. It seems that the onHotSpotClicked is never activated. Here is my full code, for a simple example, to switch between two panoramas, while zooming the transition. The first panorama loads just fine, but not the second. Your help is much appreciated!
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tour</title>
<link rel="stylesheet" href="src/css/pannellum.css"/>
<link rel="stylesheet" href="src/standalone/standalone.css"/>
<script type="text/javascript" src="src/js/libpannellum.js"></script>
<script type="text/javascript" src="src/js/pannellum.js"></script>
<script type="text/javascript" src="src/standalone/standalone.js"></script>
<style>
#panorama {
width: 1200px;
height: 600px;
}
</style>
<script>
var dLastPitch;
var dLastYaw;
var dLastHfov;
var dTimeLookAtHotSpot = 400; // [ms] , after clicking a hotspot, time to focus on hotspot
var dTimeZoomInHotSpot = 1000; // [ms] , after clicking a hotspot, time to zoom into the hotspot
var dTimeZoomInAfterLoad = 500; // [ms] , after clicking a hotspot and its loaded, time to zoom in a little bit
var dTimeToLoad = 1000; // [ms] , setTimeout time to wait for finisheing loading new a sce
</script>
</head>
<body>
<!-- <div id="panorama"></div> -->
<div id = "panorama" onmousedown="inMouseDown(event)">
<script>
//--- stores viewing coordinates of last mouse click (calculates real coordinates to viewer coordinates)
//--- this funcion must be set in the html div
function inMouseDown(e)
{
var coords = viewer.mouseEventToCoords(e);
dLastPitch = coords[0];
dLastYaw = coords[1];
dLastHfov = viewer.getHfov();
console.log(logPOVstr("inMouseDown: "));
};
</script>
</div>
<script>
pannellum.viewer('panorama', {
"default": {
"firstScene": "scene_one",
"sceneFadeDuration": 1000
},
"scenes": {
"scene_one": {
"title": "FIRST",
"hfov": 120,
"pitch": 0,
"yaw": 120,
"type": "equirectangular",
"panorama": "./1.jpg",
"hotSpots": [
{
"pitch": 0,
"yaw": 130,
"type": "scene",
"text": "Toward 2",
"clickHandlerFunc": onHotSpotClicked,
"clickHandlerArgs": {target:"scene_two"}
}
]
},
"scene_two": {
"title": "SECOND",
"hfov": 120,
"yaw": 0,
"type": "equirectangular",
"panorama": "./2.jpg",
"hotSpots": [
{
"pitch": 0,
"yaw": 00,
"type": "scene",
"text": "Toward 1",
"clickHandlerFunc": onHotSpotClicked,
"clickHandlerArgs": {target:"scene_one"},
"targetYaw": 120,
"targetPitch": 0
}
]
}
}
});
var onHotSpotClicked = function(e, clickHandlerArgs)
{
console.log("Hotspot clicked!");
setTimeout(function(){LookAndWait(viewer.getHfov(), dTimeLookAtHotSpot);},10); //--- first look directly at the hotspot
LookAndWait(50, dTimeZoomInHotSpot); //--- then zoom in
setTimeout(function(){viewer.loadScene(clickHandlerArgs.target, dLastPitch, dLastYaw, 120);}, dTimeToLoad); // then load the new scene
};
function LookAndWait(dHfov, dTime) // Initiate LookAt / Zoom
{
var pZ = dLastPitch; // Or other pan angle to Zoom in on.
var yZ = dLastYaw ; // Or other yaw angle to Zoom in on.
var vZ = dHfov ; // Or other Hfov angle to Zoom in on.
var pS = dTime ; // Or other zoom speed
viewer.lookAt(pZ, yZ, vZ, pS);
setTimeout(function(){wait_for_view(dLastPitch, dLastYaw, vZ);},1000);
console.log("LookAndWait(): pZ: "+pZ +" yZ: " +yZ + " vZ:" +vZ + " pS: " + pS);
};
function wait_for_view(dPitch, dYaw, dHfov)
{
var iCnt = 0;
pI=Math.round(viewer.getPitch()); // get actual pitch and round
yI=Math.round(viewer.getYaw()); // get actual yaw and round
vI=Math.round(viewer.getHfov()); // get actual Hfov and round
if(yI>180){yI=yI-360;viewer.setYaw(yI,0);}
if(yI<-180){yI=yI+360;viewer.setYaw(yI,0);}
if (pI===dPitch && yI===dYaw && vI===dHfov) // Has LookAt finished
{
return true;
}
else
{
setTimeout(function(){wait_for_view (dPitch, dYaw, dHfov);},10);
}
};
// this function is called after an image is loaded, aka if someone click on a hot spot:
function sceneLoadListener()
{
console.log("sceneLoadListener() load " + viewer.getScene() +
" done - looking at LP: " + viewer.getPitch() + " LY: " + viewer.getYaw() + " HF: " +
" setting view to LP: " + dLastPitch + "LY:" + dLastYaw);
//--- zoom a little bit into current viewing direction
LookAndWait(110, dTimeZoomInAfterLoad);
};
</script>
</body>
</html>
@RoEVDiesel There are a couple changes you need to make:
<script type="text/javascript" src="src/standalone/standalone.js"></script>
line, since you're not using it (and it causes errors to be printed to the developer console)viewer
variable, i.e., replace pannellum.viewer('panorama', {
with var viewer = pannellum.viewer('panorama', {
var viewer = pannellum.viewer('panorama', {...};
block of code to the end of your script, so the onHotSpotClicked
function is defined when you create the viewerThank you. It is working fine now. I was wondering if the already present function: onDocumentDoubleClick(event) can be used as it performs some kind of zoom-ing ...
* Event handler for double clicks. Zooms in at clicked location
* @private
* @param {MouseEvent} event - Document mouse down event.
function onDocumentDoubleClick(event) {
if (config.minHfov === config.hfov) {
_this.setHfov(origHfov, 1000);
} else {
var coords = mouseEventToCoords(event);
_this.lookAt(coords[0], coords[1], config.minHfov, 1000);
}
}
Just my 2cents. By the way, thank you for your work Matthew! Really appreciate it!
I was wondering if the already present function: onDocumentDoubleClick(event) can be used as it performs some kind of zoom-ing
It wouldn't make much sense to use that function directly, since it's only a mouse event wrapper around the lookAt
function. With an appropriate callback to finish with the scene change, lookAt
could be used, though.
A possible enhancement to the current tour functionality would be an option for a zoom animation towards a hot spot before changing to the next scene.