I like to have background music streaming with my panoramas. I understand I could achieve that in parallel to Pannellum viewer in HTML5 using audio tag. I would like to however offer users music on/off (mute) button. Is it possible to have such button displayed inside Pannellum viewer itself? This would be especially helpful when user switches the panorama to full screen mode. I am familiar with programming principles, but haven't done anything in JavaScript yet.
If you want to see an example of what I mean, please have a look at following link with a Flash enabled browser (if Flash is not available Pannellum is used instead and currently music doesn't play): https://tomassobekphotography.co.nz/pano36.php
I had a look at this myself, after a JavaScript crash course. I am proposing following:
_showMusicCtrl_ (boolean)
If set to true, a new button will be displayed to turn music on/off. Default value is false.
_musicPlayerId_ (string)
ID of an audio tag anywhere on the page, that the above button will control (issue pause/play). Default value is empty string, i.e. not set.
It could be done with changes as per attached diff file. The only issue that is not addressed is to prevent the click on the button being interpreted as user interaction on panorama level. At the moment every click stops auto-rotation. As @mpetroff is fixing auto-rotation right now (see #170), I am not confident how to address that. For now I just left a place-holder comment in function toggleMusic.
Please let me know if I should provide a different format or any other useful feedback. I have never contributed on github before. But I noticed at least one diff file floating somewhere in issue comments previously.
I think this is too specialized to be built in, particularly when it's easy to do with the API. A quick example of adding a new control with the API version is below:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Music Toggle Mockup</title>
<link rel="stylesheet" href="https://cdn.pannellum.org/2.2/pannellum.css"/>
<script type="text/javascript" src="https://cdn.pannellum.org/2.2/pannellum.js"></script>
<style>
#panorama {
width: 600px;
height: 400px;
}
#music-toggle {
position: absolute;
top: 4px;
right: 4px;
width: 26px;
height: 26px;
text-align: center;
}
</style>
</head>
<body>
<div id="panorama"><div id="music-toggle" class="pnlm-controls">♪</div></div>
<script>
viewer = pannellum.viewer('panorama', {
"panorama": "https://i.imgur.com/G7t9QD9.jpg"
});
document.getElementById('music-toggle').addEventListener('click', function(e) {
alert('Music toggle pressed.')
});
</script>
</body>
</html>
Thanks, @mpetroff! I had no idea it could be done in such a simple way ;)
Btw, for the benefit of any readers: If I give music-toggle also class pnlm-control it will gain identical hover behaviour as the other buttons (slight change of background colour).
One question however remains: How to prevent stopping auto-rotation when the button is clicked? It seems like the viewer is processing the click event _before_ my button. I checked available methods of the viewer object. I couldn't find anything telling me that auto-rotation was happening just before the click, nor any method to restart it.
All right, I just learnt that the event model in JavaScript is quite powerful. I can capture events and don't let them be processed further (using the third optional argument of addEventListener set to true in combination with method stopPropagation). But in order to override the panorama viewer default mouse capture I need to respond to event mousedown instead of click. Here is a snippet of my code:
document.getElementById('music-toggle').addEventListener('mousedown', function(e) {
var musicControl = document.getElementById('MusicPlayer');
if(musicControl.paused) {
document.getElementById('music-toggle').classList.remove('music-toggle-inactive');
musicControl.play();
} else {
document.getElementById('music-toggle').classList.add('music-toggle-inactive');
musicControl.pause();
}
e.stopPropagation();
}, true);
Most helpful comment
I think this is too specialized to be built in, particularly when it's easy to do with the API. A quick example of adding a new control with the API version is below: