This commit is contained in:
2018-07-23 20:25:36 +02:00
commit 09c3507d66
8 changed files with 613 additions and 0 deletions

11
client-side-preview.html Normal file
View File

@@ -0,0 +1,11 @@
<html>
<head>
<script src="https://aframe.io/aframe/dist/aframe-master.min.js"></script>
<script src="gallery-via-json-noprocess.js"></script>
</head>
<body>
<a-scene>
<a-sky gallery-via-json></a-sky>
</a-scene>
</body>
</html>

View File

@@ -0,0 +1,267 @@
AFRAME.registerComponent('gallery-via-json', {
init: function () {
// Create our stylesheet
// Create our stylesheet
var style = document.createElement('style');
style.innerHTML =
'.gallery {' +
'background: transparent;' +
'margin: auto;' +
'text-align: center;' +
'position: absolute;' +
'bottom: 0px;' +
'width: 100%;' +
'padding: 5px 0;' +
'}' +
'.scrolling { ' +
'overflow-x: scroll;' +
'overflow-y: hidden;' +
'height: 112px;' +
'white-space:nowrap' +
'} ' +
'.scrolling .thumb img { ' +
'height: 100%; ' +
'min-width: 100%; ' +
'top: 50%; ' +
'left: 50%; ' +
'position: absolute; ' +
'transform: translate(-50%,-50%); ' +
'} ' +
'.scrolling .thumb { ' +
'width: 100px; ' +
'height: 80px; ' +
'overflow: hidden; ' +
'position: relative; ' +
'margin: 5px; ' +
'width: 100px; ' +
'border: 1px solid #fff;' +
'box-shadow: 1px 1px 5px rgba(0,0,0,0.5); ' +
'opacity: 0.7;' +
'max-height: 80px;' +
'cursor: pointer;' +
'display:inline-block;' +
'*display:inline;' +
'*zoom:1;' +
'vertical-align:top;' +
'}' +
'.scrolling .thumb:hover, .scrolling .thumb.active {' +
'box-shadow: 1px 1px 10px rgba(0,0,0,0.25);' +
'opacity: 1;' +
'transform: scale(1.1);' +
'}';
// Get the first script tag
var ref = document.querySelector('script');
// Insert our new styles before the first script tag
ref.parentNode.insertBefore(style, ref);
var i = 0;
if(window.location.hash) {
i = Number( window.location.hash.replace("#image","") );
}
var el = this.el;
var files;
var timer;
var thumb = "";
var enablePreview = AFRAME.utils.getUrlParameter('enable-preview');
var preventTimer = AFRAME.utils.getUrlParameter('disable-timer');
var url = AFRAME.utils.getUrlParameter('json-file');
if (!url){
var msg = "Error: Specify json-file parameter in URL!";
var errorMsg = document.createElement("a-entity");
errorMsg.setAttribute("text", "value", msg);
errorMsg.setAttribute("position", "0.2 0 -0.5");
errorMsg.setAttribute("text", "color", "red");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(errorMsg); }, 1000)
console.error(msg);
return;
}
function setupPreviews(){
var gallery = document.createElement("div")
gallery.classList.add("gallery");
document.body.appendChild(gallery)
var previews = document.createElement("div")
previews.classList.add("scrolling");
gallery.appendChild(previews)
/* for now delegated to css stylesheet
previews.style.position = "absolute";
previews.style.bottom = "0px";
previews.style.left = "0px";
previews.style.height = "100px";
//previews.style.width = files.length * 110 + "px";
previews.style.overflowX = "auto";
previews.style.whiteSpace = "nowrap";
//previews.style.width = "100%";
//previews.style.overflowX = "scroll";
//previews.style.overflowY = "hidden";
*/
for (var imageIdx in files){
var file = files[imageIdx];
var imageEl = document.createElement("img");
imageEl.src = path+thumb+file;
imageEl.setAttribute("fullpath", path+file);
imageEl.setAttribute("index", imageIdx);
imageEl.classList.add("thumb");
imageEl.onclick = function(){
i = this.getAttribute("index");
updateSky();
}
previews.appendChild(imageEl);
/* for now delegated to css stylesheet
imageEl.style.margin = "5px";
imageEl.style.width = "100px";
imageEl.onmouseover = function(){
this.style.boxShadow = "5px 5px";
}
imageEl.onmouseleave = function(){
this.style.boxShadow = "";
}
*/
}
}
function setupPreview(){
var preview = document.createElement("a-image");
preview.setAttribute("position", "1 0 -2");
preview.setAttribute("rotation", "0 -30 0");
preview.setAttribute("id", "preview");
preview.setAttribute("visible", false);
preview.setAttribute("src", path+thumb+files[(i+1)]);
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(preview); }, 1000)
}
function updateSky(){
document.querySelectorAll(".scrolling img").forEach( (e) => e.classList.remove("active") )
window.location = "#image" + i;
el.setAttribute("src", path+files[i]);
var previewEl = document.querySelector('.scrolling img[index="'+i+'"]')
if (previewEl) previewEl.style.opacity = 0.7;
el.classList.add("active");
}
var instructions = document.createElement("a-entity");
instructions.setAttribute("text", "value", "<- previous, next ->, ^ first, v last\nSPACE pause/start\n? help");
instructions.setAttribute("position", "0.2 0 -0.3");
if (AFRAME.utils.device.isMobile ()) {
instructions.setAttribute("text", "value", "Diaporama starting...");
instructions.setAttribute("position", "0.2 0 -1");
}
instructions.setAttribute("id", "instructions");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(instructions); }, 1000)
var message = document.createElement("a-entity");
message.setAttribute("text", "value", "");
message.setAttribute("position", "0.2 0 -0.5");
message.setAttribute("id", "message");
message.setAttribute("visible", "false");
message.setAttribute("text", "opacity", "0.6");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(message); }, 1000)
var path = url.replace(/[a-zA-Z]*.json/,'');
var interval = Number( AFRAME.utils.getUrlParameter('interval') );
if (interval < 1) interval = 5;
myFetch(url).then( (r)=>{ displayGallery(r) } )
function displayGallery(json){
files = json;
updateSky();
if (!preventTimer)
timer = startTimer();
if (enablePreview)
setupPreview();
setupPreviews();
}
function startTimer(){
return setInterval( () => {
document.querySelector("#instructions").setAttribute("visible", false);
i++;
if (i > files.length-1) i = 0;
updateSky();
if (enablePreview) setTimeout( () => {
document.querySelector("#preview").setAttribute("visible", true);
document.querySelector("#preview").setAttribute("src", path+thumb+files[(i+1)]);
setTimeout( () => {
document.querySelector("#preview").setAttribute("visible", false);
}, 2000);
}, interval * 1000 - (interval * 1000 / 5) )
}, interval * 1000)
}
function showTemporaryMessage(text){
document.querySelector("#message").setAttribute("visible", true);
document.querySelector("#message").setAttribute("text", "value", text);
setTimeout( () => {
document.querySelector("#message").setAttribute("visible", false);
// could also do an animation
}, 1000)
}
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
//console.log('key:' + e.key + '.')
document.querySelector("#instructions").setAttribute("visible", false);
switch (e.key){
case ' ':
if (!timer){
timer = startTimer();
showTemporaryMessage("Restarting diaoporama\n(" + interval + "s interval)" );
} else {
showTemporaryMessage("Paused diaoporama");
clearInterval(timer);
timer = 0;
}
break;
case '?':
document.querySelector("#instructions").setAttribute("visible", "true");
break;
case 'ArrowUp':
showTemporaryMessage("Going to the beginning");
i = 0;
updateSky();
break;
case 'ArrowDown':
showTemporaryMessage("Going to the end");
i = files.length-1;
updateSky();
break;
case 'ArrowLeft':
showTemporaryMessage("Previous image");
i--;
if (i<0) i=files.length-1;
updateSky();
break;
case 'ArrowRight':
showTemporaryMessage("Next image");
i++;
if (i > files.length-1) i =0;
updateSky();
break;
}
}
function myFetch(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = 'json';
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
}
});

252
gallery-via-json.js Normal file
View File

@@ -0,0 +1,252 @@
AFRAME.registerComponent('gallery-via-json', {
init: function () {
// Create our stylesheet
var style = document.createElement('style');
style.innerHTML =
'.gallery {' +
'background: transparent;' +
'margin: auto;' +
'text-align: center;' +
'position: absolute;' +
'bottom: 0px;' +
'width: 100%;' +
'padding: 5px 0;' +
'}' +
'.scrolling { ' +
'overflow-x: scroll;' +
'overflow-y: hidden;' +
'height: 112px;' +
'white-space:nowrap' +
'} ' +
'.scrolling img { ' +
'margin: 5px; ' +
'width: 100px; ' +
'border: 1px solid #fff;' +
'box-shadow: 1px 1px 5px rgba(0,0,0,0.5); ' +
'opacity: 0.7;' +
'max-height: 80px;' +
'cursor: pointer;' +
'display:inline-block;' +
'*display:inline;' +
'*zoom:1;' +
'vertical-align:top;' +
'}' +
'.scrolling img:hover, .scrolling img.active {' +
'box-shadow: 1px 1px 10px rgba(0,0,0,0.25);' +
'opacity: 1;' +
'transform: scale(1.1);' +
'}';
// Get the first script tag
var ref = document.querySelector('script');
// Insert our new styles before the first script tag
ref.parentNode.insertBefore(style, ref);
var i = 0;
if(window.location.hash) {
i = Number( window.location.hash.replace("#image","") );
}
var el = this.el;
var files;
var timer;
var thumb = "thumb/";
var enablePreview = AFRAME.utils.getUrlParameter('enable-preview');
var preventTimer = AFRAME.utils.getUrlParameter('disable-timer');
var url = AFRAME.utils.getUrlParameter('json-file');
if (!url){
var msg = "Error: Specify json-file parameter in URL!";
var errorMsg = document.createElement("a-entity");
errorMsg.setAttribute("text", "value", msg);
errorMsg.setAttribute("position", "0.2 0 -0.5");
errorMsg.setAttribute("text", "color", "red");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(errorMsg); }, 1000)
console.error(msg);
return;
}
function setupPreviews(){
var gallery = document.createElement("div")
gallery.classList.add("gallery");
document.body.appendChild(gallery)
var previews = document.createElement("div")
previews.classList.add("scrolling");
gallery.appendChild(previews)
/* for now delegated to css stylesheet
previews.style.position = "absolute";
previews.style.bottom = "0px";
previews.style.left = "0px";
previews.style.height = "100px";
//previews.style.width = files.length * 110 + "px";
previews.style.overflowX = "auto";
previews.style.whiteSpace = "nowrap";
//previews.style.width = "100%";
//previews.style.overflowX = "scroll";
//previews.style.overflowY = "hidden";
*/
for (var imageIdx in files){
var file = files[imageIdx];
var imageEl = document.createElement("img");
imageEl.src = path+thumb+file;
imageEl.setAttribute("fullpath", path+file);
imageEl.setAttribute("index", imageIdx);
imageEl.onclick = function(){
i = this.getAttribute("index");
updateSky();
}
previews.appendChild(imageEl);
/* for now delegated to css stylesheet
imageEl.style.margin = "5px";
imageEl.style.width = "100px";
imageEl.onmouseover = function(){
this.style.boxShadow = "5px 5px";
}
imageEl.onmouseleave = function(){
this.style.boxShadow = "";
}
*/
}
}
function setupPreview(){
var preview = document.createElement("a-image");
preview.setAttribute("position", "1 0 -2");
preview.setAttribute("rotation", "0 -30 0");
preview.setAttribute("id", "preview");
preview.setAttribute("visible", false);
preview.setAttribute("src", path+thumb+files[(i+1)]);
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(preview); }, 1000)
}
function updateSky(){
document.querySelectorAll(".scrolling img").forEach( (e) => e.classList.remove("active") )
window.location = "#image" + i;
el.setAttribute("src", path+files[i]);
var previewEl = document.querySelector('.scrolling img[index="'+i+'"]')
if (previewEl) previewEl.style.opacity = 0.7;
el.classList.add("active");
}
var instructions = document.createElement("a-entity");
instructions.setAttribute("text", "value", "<- previous, next ->, ^ first, v last\nSPACE pause/start\n? help");
instructions.setAttribute("position", "0.2 0 -0.3");
if (AFRAME.utils.device.isMobile ()) {
instructions.setAttribute("text", "value", "Diaporama starting...");
instructions.setAttribute("position", "0.2 0 -1");
}
instructions.setAttribute("id", "instructions");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(instructions); }, 1000)
var message = document.createElement("a-entity");
message.setAttribute("text", "value", "");
message.setAttribute("position", "0.2 0 -0.5");
message.setAttribute("id", "message");
message.setAttribute("visible", "false");
message.setAttribute("text", "opacity", "0.6");
setTimeout( () => { AFRAME.scenes[0].camera.el.appendChild(message); }, 1000)
var path = url.replace(/[a-zA-Z]*.json/,'');
var interval = Number( AFRAME.utils.getUrlParameter('interval') );
if (interval < 1) interval = 5;
myFetch(url).then( (r)=>{ displayGallery(r) } )
function displayGallery(json){
files = json;
updateSky();
if (!preventTimer)
timer = startTimer();
if (enablePreview)
setupPreview();
setupPreviews();
}
function startTimer(){
return setInterval( () => {
document.querySelector("#instructions").setAttribute("visible", false);
i++;
if (i > files.length-1) i = 0;
updateSky();
if (enablePreview) setTimeout( () => {
document.querySelector("#preview").setAttribute("visible", true);
document.querySelector("#preview").setAttribute("src", path+thumb+files[(i+1)]);
setTimeout( () => {
document.querySelector("#preview").setAttribute("visible", false);
}, 2000);
}, interval * 1000 - (interval * 1000 / 5) )
}, interval * 1000)
}
function showTemporaryMessage(text){
document.querySelector("#message").setAttribute("visible", true);
document.querySelector("#message").setAttribute("text", "value", text);
setTimeout( () => {
document.querySelector("#message").setAttribute("visible", false);
// could also do an animation
}, 1000)
}
document.onkeydown = checkKey;
function checkKey(e) {
e = e || window.event;
//console.log('key:' + e.key + '.')
document.querySelector("#instructions").setAttribute("visible", false);
switch (e.key){
case ' ':
if (!timer){
timer = startTimer();
showTemporaryMessage("Restarting diaoporama\n(" + interval + "s interval)" );
} else {
showTemporaryMessage("Paused diaoporama");
clearInterval(timer);
timer = 0;
}
break;
case '?':
document.querySelector("#instructions").setAttribute("visible", "true");
break;
case 'ArrowUp':
showTemporaryMessage("Going to the beginning");
i = 0;
updateSky();
break;
case 'ArrowDown':
showTemporaryMessage("Going to the end");
i = files.length-1;
updateSky();
break;
case 'ArrowLeft':
showTemporaryMessage("Previous image");
i--;
if (i<0) i=files.length-1;
updateSky();
break;
case 'ArrowRight':
showTemporaryMessage("Next image");
i++;
if (i > files.length-1) i =0;
updateSky();
break;
}
}
function myFetch(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = 'json';
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
}
});

11
gallery.html Normal file
View File

@@ -0,0 +1,11 @@
<html>
<head>
<script src="https://aframe.io/aframe/dist/aframe-master.min.js"></script>
<script src="gallery-via-json.js"></script>
</head>
<body>
<a-scene>
<a-sky gallery-via-json></a-sky>
</a-scene>
</body>
</html>

22
image.html Normal file
View File

@@ -0,0 +1,22 @@
<html>
<head>
<!-- <script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script> -->
<script src="https://aframe.io/aframe/dist/aframe-master.min.js"></script>
<script src="http://fabien.benetou.fr:1337/vorlon.js"></script>
<!-- doesn't support https, see http://vorlonjs.com/documentation/#vorlonjs-server-advanced-topics -->
</head>
<body>
<script>
AFRAME.registerComponent('photosphere-via-url', {
init: function () {
this.el.setAttribute("src", AFRAME.utils.getUrlParameter('photosphere') );
}
});
</script>
<a-scene>
<a-sky photosphere-via-url></a-sky>
</a-scene>
</body>
</html>

5
make_thumbs.sh Executable file
View File

@@ -0,0 +1,5 @@
mkdir thumb
cp *JPG thumb/
cd thumb/
mogrify -resize 30% *.JPG
mogrify -crop 560x450+1000+200 *.JPG

3
todo Normal file
View File

@@ -0,0 +1,3 @@
- merge single image, gallery and video
- add the tagging system cf https://vatelier.net/MyDemo/360sorter/
- clarify parameters e.g. &interval=15 disable-timer=true

42
video.html Normal file
View File

@@ -0,0 +1,42 @@
<html>
<head>
<script src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script src="https://aframe-360-video-example.glitch.me/play-on-window-click.js"></script>
<script src="https://aframe-360-video-example.glitch.me/play-on-vrdisplayactivate-or-enter-vr.js"><script>
<script src="https://aframe-360-video-example.glitch.me/hide-once-playing.js"></script>
</head>
<body>
<script>
AFRAME.registerComponent('videosphere-via-url', {
init: function () {
this.el.setAttribute("src", AFRAME.utils.getUrlParameter('videosphere') );
}
});
</script>
<a-scene>
<a-assets>
<video id="video" style="display:none"
autoplay loop crossorigin="anonymous" playsinline webkit-playsinline
videosphere-via-url
>
</video>
</a-assets>
<a-camera user-height="0">
<!-- Text element for display messaging. Hide once video is playing. -->
<a-entity id="msg" position="0 -0.3 -1.5" text="align:center;
width:3;
wrapCount:100;
color:red;
value:Click window to make the video play, if needed."
hide-once-playing="#video">
</a-entity>
</a-camera>
<a-videosphere play-on-window-click play-on-vrdisplayactivate-or-enter-vr></a-videosphere>
</a-scene>
</body>
</html>