First WIP of parade
This commit is contained in:
commit
62b6717d1b
2 changed files with 294 additions and 0 deletions
74
index.html
Normal file
74
index.html
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Parade</title>
|
||||||
|
<style media="screen">
|
||||||
|
html,body{
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
canvas{
|
||||||
|
margin:0;
|
||||||
|
width:100vw;
|
||||||
|
height:100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* audio{
|
||||||
|
position: absolute;
|
||||||
|
top:0;
|
||||||
|
} */
|
||||||
|
|
||||||
|
#subtitles{
|
||||||
|
position:fixed;
|
||||||
|
bottom:0;
|
||||||
|
width:100%;
|
||||||
|
color:white;
|
||||||
|
text-shadow: black 0 0 10px;;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Will automatically be injected if needed: <script src=https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js></script> -->
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<canvas id="renderCanvas" touch-action="none"></canvas> <!--touch-action="none" for best results from PEP-->
|
||||||
|
|
||||||
|
<div id='annotation'>
|
||||||
|
<template id="annotationContent">
|
||||||
|
<img id='img'>
|
||||||
|
<input type='number' id='weight'>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<audio id='interview'
|
||||||
|
src="/interview/interview-with-ellen.mp3">
|
||||||
|
|
||||||
|
<track default kind="captions"
|
||||||
|
srclang="en"
|
||||||
|
src="/interview/interview-with-ellen_v3.mp3.vtt"/>
|
||||||
|
|
||||||
|
</audio>
|
||||||
|
|
||||||
|
<div id='subtitles'>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="https://cdn.babylonjs.com/babylon.js"></script>
|
||||||
|
<script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
|
||||||
|
<script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
|
||||||
|
<script src="parade.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
220
parade.js
Normal file
220
parade.js
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
var parade;
|
||||||
|
var interview_sorter;
|
||||||
|
|
||||||
|
// polyfill
|
||||||
|
window.performance = window.performance || {};
|
||||||
|
performance.now = (function() {
|
||||||
|
return performance.now ||
|
||||||
|
performance.mozNow ||
|
||||||
|
performance.msNow ||
|
||||||
|
performance.oNow ||
|
||||||
|
performance.webkitNow ||
|
||||||
|
Date.now /*none found - fallback to browser default */
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
const request = new Request('dataset/images_prop.json');
|
||||||
|
fetch(request)
|
||||||
|
.then(response => {
|
||||||
|
if (response.status === 200) {
|
||||||
|
return response.json();
|
||||||
|
} else {
|
||||||
|
throw new Error('Something went wrong on api server!');
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.debug(data);
|
||||||
|
// loaded data from json, initialise interface
|
||||||
|
const canvas = document.getElementById("renderCanvas");
|
||||||
|
parade = new Parade(canvas, data['image']);
|
||||||
|
parade.createScene();
|
||||||
|
// parade.scene.debugLayer.show();
|
||||||
|
}).catch(error => {
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
class Parade {
|
||||||
|
constructor(canvasEl, images) {
|
||||||
|
this.speedFactor = -.05;
|
||||||
|
this.distanceFactor = 20;
|
||||||
|
this.startOffset = 800;
|
||||||
|
this.maxStepSize = 1;
|
||||||
|
|
||||||
|
this.prevRenderTime = null;
|
||||||
|
this.canvasEl = canvasEl;
|
||||||
|
this.engine = new BABYLON.Engine(canvasEl, true);
|
||||||
|
|
||||||
|
this.audioEl = document.getElementById('interview'); // audio player
|
||||||
|
this.subtitleEl = document.getElementById('subtitles'); // the subtitle div
|
||||||
|
this.trackEl = this.audioEl.querySelector('track'); // the subtitle track
|
||||||
|
|
||||||
|
|
||||||
|
// set up subtitles:
|
||||||
|
this.trackEl.addEventListener("cuechange", (event) => {
|
||||||
|
console.log(event);
|
||||||
|
let cues = event.target.track.activeCues;
|
||||||
|
let content = "";
|
||||||
|
for(let cue of cues) {
|
||||||
|
content += "<p>"+cue.text+"</p>";
|
||||||
|
}
|
||||||
|
this.subtitleEl.innerHTML = content;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// initialise image objects:
|
||||||
|
this.images = [];
|
||||||
|
for(let i in images) {
|
||||||
|
this.images.push(new ParadeImage(images[i], i));
|
||||||
|
// for testing:
|
||||||
|
// if(this.images.length > 5)
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Watch for browser/canvas resize events
|
||||||
|
window.addEventListener("resize", function () {
|
||||||
|
this.engine.resize();
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
|
//Register a render loop to repeatedly render the scene
|
||||||
|
this.engine.runRenderLoop(this.renderLoop.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLoop() {
|
||||||
|
// limit camera movement:
|
||||||
|
// let camera = this.scene.cameras[0];
|
||||||
|
// if(camera.rotation['x'] < 0.1) {
|
||||||
|
// camera.rotation['x'] = 0.1
|
||||||
|
// }
|
||||||
|
// if(camera.rotation['x'] > .3) {
|
||||||
|
// camera.rotation['x'] = .3
|
||||||
|
// }
|
||||||
|
this.animate();
|
||||||
|
this.scene.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
animate() {
|
||||||
|
let t = window.performance.now() - this.startTime;
|
||||||
|
// let maxStepSize = Math.inf;
|
||||||
|
|
||||||
|
// if (this.prevRenderTime === null) {
|
||||||
|
|
||||||
|
// } else {
|
||||||
|
// let tdiff = t - this.prevRenderTime;
|
||||||
|
// if(tdiff < 1) {
|
||||||
|
// // sometimes multiple render calls within very short moment??
|
||||||
|
// // skip some work.
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// maxStepSize = Math.abs(this.maxStepSize * tdiff * this.speedFactor);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// this.prevRenderTime = t;
|
||||||
|
// console.log(tdiff);
|
||||||
|
t -= 800/this.speedFactor; // start offset ( milliseconds)
|
||||||
|
// console.log(maxStepSize);
|
||||||
|
for(let i of this.images){
|
||||||
|
i.updateMeshPosition(t*this.speedFactor/1000);
|
||||||
|
t-= this.distanceFactor/this.speedFactor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createScene() {
|
||||||
|
// This creates a basic Babylon Scene object (non-mesh)
|
||||||
|
this.scene = new BABYLON.Scene(this.engine);
|
||||||
|
// return this.scene;
|
||||||
|
// this.scene.clearColor = new BABYLON.Color3(0.6, 0.6, 0.); // color RGB
|
||||||
|
// this.scene.clearColor = new BABYLON.Color4(0.6, 0.6, 0.,0); // transparent - RGBA
|
||||||
|
this.scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
|
||||||
|
this.scene.fogColor = this.scene.clearColor;
|
||||||
|
this.scene.fogDensity = 0.002;
|
||||||
|
|
||||||
|
// let camera = new BABYLON.UniversalCamera("camera1", new BABYLON.Vector3( 0.0, 0.0, 120.86337575312979), this.scene);
|
||||||
|
// camera.rotation = new BABYLON.Vector3(0, Math.PI, 0);
|
||||||
|
// camera.fov = 1.1; // default: 0.8
|
||||||
|
let camera = new BABYLON.UniversalCamera("camera2", new BABYLON.Vector3( -14.40894348196419, 0.9954991699417852, 17.582966906902247), this.scene);
|
||||||
|
camera.rotation = new BABYLON.Vector3(0.023121520223909536, 2.5494248799675163, 0);
|
||||||
|
camera.fov = 1.5;
|
||||||
|
// camera.rotation = new BABYLON.Vector3(0.1, 0,0);
|
||||||
|
// camera.lowerRadiusLimit = 6;
|
||||||
|
// camera.upperRadiusLimit = 20;
|
||||||
|
// This attaches the camera to the canvas
|
||||||
|
camera.attachControl(this.canvasEl, true);
|
||||||
|
|
||||||
|
let radius = 60;
|
||||||
|
for(let i in this.images) {
|
||||||
|
// console.log(i, this.images, this);
|
||||||
|
this.images[i].makeMesh(this.scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.startTime = window.performance.now();
|
||||||
|
// this.scene.registerBeforeRender(this.animate.bind(this));
|
||||||
|
return this.scene;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ParadeImage {
|
||||||
|
constructor(info, position) {
|
||||||
|
this.info = info;
|
||||||
|
this.weight = info['weight'];
|
||||||
|
this.position = position; // index in list
|
||||||
|
}
|
||||||
|
|
||||||
|
makeMesh(scene) {
|
||||||
|
// let videoSrc = this.images[i]['image'];
|
||||||
|
// random fluctuation in radius
|
||||||
|
let i = 1;
|
||||||
|
let radius = 60
|
||||||
|
let localRadius = (Math.random() * .2 + 1) * radius;
|
||||||
|
let x = Math.sin(2*Math.PI * i / 1) * localRadius;
|
||||||
|
let y = Math.cos(2*Math.PI * i / 1) * localRadius;
|
||||||
|
var planeOpts = {
|
||||||
|
height: 5.4762,
|
||||||
|
width: 7.3967,
|
||||||
|
sideOrientation: BABYLON.Mesh.DOUBLESIDE
|
||||||
|
};
|
||||||
|
this.mesh = BABYLON.MeshBuilder.CreatePlane("plane", planeOpts, scene);
|
||||||
|
|
||||||
|
var ANote0VideoMat = new BABYLON.StandardMaterial("m", scene);
|
||||||
|
|
||||||
|
let imgUrl = 'dataset/small/'+ this.info['image'];
|
||||||
|
// console.log(imgUrl);
|
||||||
|
ANote0VideoMat.diffuseTexture = new BABYLON.Texture(imgUrl, scene);
|
||||||
|
ANote0VideoMat.roughness = 1;
|
||||||
|
ANote0VideoMat.emissiveColor = new BABYLON.Color3.White();
|
||||||
|
this.mesh.material = ANote0VideoMat;
|
||||||
|
|
||||||
|
// this.updateMeshPosition(1, Math.inf); //TODO: remove when animating
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMeshPosition(t){
|
||||||
|
// factors determine scale of animation
|
||||||
|
let target_x = Math.sin(2*t)*100;
|
||||||
|
let target_z = Math.sin(t)*1300;
|
||||||
|
|
||||||
|
// let diff_x = target_x - this.mesh.position.x;
|
||||||
|
// let diff_z = target_z - this.mesh.position.z;
|
||||||
|
|
||||||
|
// let stepSize = Math.sqrt( Math.pow(diff_x, 2) + Math.pow(diff_z, 2) );
|
||||||
|
|
||||||
|
// if(stepSize > maxStepSize) {
|
||||||
|
// // console.log('throttle', maxStepSize, stepSize);
|
||||||
|
// // throttle the step, so switching items looks like movement
|
||||||
|
// diff_x *= maxStepSize/stepSize;
|
||||||
|
// diff_z *= maxStepSize/stepSize;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // console.log(diff_x, diff_z, stepSize);
|
||||||
|
// this.mesh.position.x += diff_x;
|
||||||
|
// this.mesh.position.z += diff_z;
|
||||||
|
this.mesh.position.x = target_x;
|
||||||
|
this.mesh.position.z = target_z;
|
||||||
|
|
||||||
|
// this.mesh.position = new BABYLON.Vector3(x,0,y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue