|
|
|
@ -20,7 +20,7 @@ performance.now = (function() {
@@ -20,7 +20,7 @@ performance.now = (function() {
|
|
|
|
|
performance.mozNow || |
|
|
|
|
performance.msNow || |
|
|
|
|
performance.oNow || |
|
|
|
|
performance.webkitNow || |
|
|
|
|
performance.webkitNow || |
|
|
|
|
Date.now /*none found - fallback to browser default */ |
|
|
|
|
})(); |
|
|
|
|
|
|
|
|
@ -76,7 +76,7 @@ class Parade {
@@ -76,7 +76,7 @@ class Parade {
|
|
|
|
|
// console.log('pos', , pos);
|
|
|
|
|
let img = new ParadeImage(images[i], pos); |
|
|
|
|
this.images.push(img); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// for testing:
|
|
|
|
|
// if(this.images.length > 5)
|
|
|
|
|
// break;
|
|
|
|
@ -85,7 +85,7 @@ class Parade {
@@ -85,7 +85,7 @@ class Parade {
|
|
|
|
|
this.setupSubtitles(); |
|
|
|
|
this.setupSorter(); |
|
|
|
|
this.restoreTime(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Watch for browser/canvas resize events
|
|
|
|
|
window.addEventListener("resize", function () { |
|
|
|
|
this.engine.resize(); |
|
|
|
@ -124,7 +124,7 @@ class Parade {
@@ -124,7 +124,7 @@ class Parade {
|
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
for(let track of this.audioEl.textTracks){ |
|
|
|
|
// by default only one (or none) is set to showing.
|
|
|
|
|
// by default only one (or none) is set to showing.
|
|
|
|
|
// for some reason setting it on trackEl doesn't work, while this does the trick.
|
|
|
|
|
track.mode = 'showing'; |
|
|
|
|
} |
|
|
|
@ -140,7 +140,7 @@ class Parade {
@@ -140,7 +140,7 @@ class Parade {
|
|
|
|
|
updateTimestring() { |
|
|
|
|
let now = this.audioEl.currentTime; |
|
|
|
|
let duration = this.audioEl.duration; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let timestring = String(Math.floor(now/60)).padStart(2, '0') + ":" |
|
|
|
|
+ String(Math.floor(now)%60).padStart(2, '0') |
|
|
|
|
+ " / " + String(Math.floor(duration/60)).padStart(2, '0') + ":" |
|
|
|
@ -188,8 +188,8 @@ class Parade {
@@ -188,8 +188,8 @@ class Parade {
|
|
|
|
|
for (let index = 0; index < this.images.length; index++) { |
|
|
|
|
this.imagesToSort[index] = index; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
let nextButton = document.getElementById('nextButton'); |
|
|
|
|
nextButton.addEventListener('click', this.nextSorterImage.bind(this)); |
|
|
|
|
|
|
|
|
@ -233,10 +233,10 @@ class Parade {
@@ -233,10 +233,10 @@ class Parade {
|
|
|
|
|
document.body.classList.remove('finished'); |
|
|
|
|
this.audioEl.controls = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// pick random image
|
|
|
|
|
this.imageIdToSort = this.imagesToSort[Math.floor(Math.random()*this.imagesToSort.length)]; |
|
|
|
|
this.imageToSort = this.images[this.imageIdToSort]; |
|
|
|
|
this.imageToSort = this.images[this.imageIdToSort]; |
|
|
|
|
|
|
|
|
|
let clone = this.sorterTemplate.content.cloneNode(true); |
|
|
|
|
let imgEl = clone.querySelector(".img"); |
|
|
|
@ -283,7 +283,7 @@ class Parade {
@@ -283,7 +283,7 @@ class Parade {
|
|
|
|
|
new_position, 0, |
|
|
|
|
this.imagePositions.splice(old_position, 1)[0] |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// update positions of image objects
|
|
|
|
|
for(let i in this.images) { |
|
|
|
|
i = parseInt(i); |
|
|
|
@ -365,23 +365,23 @@ class Parade {
@@ -365,23 +365,23 @@ class Parade {
|
|
|
|
|
this.t += dt; |
|
|
|
|
} |
|
|
|
|
this.lastRenderTime = n; // also increment when paused;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// console.log(maxStepSize);
|
|
|
|
|
for(let i of this.images){ |
|
|
|
|
i.updateMeshPosition(this.t, dt, this.config); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
createScene() { |
|
|
|
|
// This creates a basic Babylon Scene object
|
|
|
|
|
this.scene = new BABYLON.Scene(this.engine); |
|
|
|
|
|
|
|
|
|
this.scene.clearColor = new BABYLON.Color3(.22,0.27,0.38); // color RGB
|
|
|
|
|
|
|
|
|
|
this.scene.clearColor = new BABYLON.Color3(98,44,246); // 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; |
|
|
|
|
this.scene.fogDensity = 0.000; |
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
@ -396,8 +396,8 @@ class Parade {
@@ -396,8 +396,8 @@ class Parade {
|
|
|
|
|
// this.spectatorCamera.upperRadiusLimit = 20;
|
|
|
|
|
// This attaches the camera to the canvas
|
|
|
|
|
this.spectatorCamera.attachControl(this.canvasEl, true); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// CAM 2: follow/track the image when we're editing its weight.
|
|
|
|
|
// Parameters: name, position, scene
|
|
|
|
|
this.imgCamera = new BABYLON.ArcRotateCamera("FollowCam", 20, 20, 10, new BABYLON.Vector3(0, 0, 0), this.scene); |
|
|
|
@ -449,7 +449,7 @@ class ParadeImage {
@@ -449,7 +449,7 @@ class ParadeImage {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
* |
|
|
|
|
* @param {int} new_position new position in parade |
|
|
|
|
* @param {float} time_complete time at which it should have transitioned to this position |
|
|
|
|
*/ |
|
|
|
@ -476,11 +476,11 @@ class ParadeImage {
@@ -476,11 +476,11 @@ class ParadeImage {
|
|
|
|
|
width: this.width/100, |
|
|
|
|
sideOrientation: BABYLON.Mesh.DOUBLESIDE // texture should be visible from front and back
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let imagePlane = BABYLON.MeshBuilder.CreatePlane("image", planeOptions, scene); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var imageMat = new BABYLON.StandardMaterial("m", scene); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
imageMat.diffuseTexture = new BABYLON.Texture(self.getImageUrl(), scene); |
|
|
|
|
imageMat.roughness = 1; |
|
|
|
|
imageMat.emissiveColor = new BABYLON.Color3.White(); |
|
|
|
@ -488,7 +488,7 @@ class ParadeImage {
@@ -488,7 +488,7 @@ class ParadeImage {
|
|
|
|
|
imagePlane.parent = self.mesh; |
|
|
|
|
} |
|
|
|
|
img.src = this.getImageUrl(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// text https://www.babylonjs-playground.com/#TMHF80
|
|
|
|
|
// TODO: cleanup this mess of the dynamic texture:
|
|
|
|
@ -510,19 +510,19 @@ class ParadeImage {
@@ -510,19 +510,19 @@ class ParadeImage {
|
|
|
|
|
ctx.fillStyle = config['textColor']; |
|
|
|
|
ctx.fillText(text, 0, 50, maxWidth); |
|
|
|
|
dynamicTexture.update(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var mat = new BABYLON.StandardMaterial("mat", scene); |
|
|
|
|
mat.diffuseTexture = dynamicTexture; |
|
|
|
|
mat.opacityTexture = dynamicTexture; // smoother transparency: https://www.html5gamedevs.com/topic/19647-quality-of-dynamictexture-text-with-transparent-background/?do=findComment&comment=111383
|
|
|
|
|
mat.roughness = 1; |
|
|
|
|
mat.emissiveColor = new BABYLON.Color3.White(); |
|
|
|
|
|
|
|
|
|
var textPlane = BABYLON.MeshBuilder.CreatePlane("text", {width:planeWidth, height:planeHeight, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene); |
|
|
|
|
textPlane.material = mat; |
|
|
|
|
textPlane.parent = this.mesh; |
|
|
|
|
textPlane.position.y = -4.3; // text sits below image
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// var textPlane = BABYLON.MeshBuilder.CreatePlane("text", {width:planeWidth, height:planeHeight, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
|
|
|
|
|
// textPlane.material = mat;
|
|
|
|
|
// textPlane.parent = this.mesh;
|
|
|
|
|
// textPlane.position.y = -4.3;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.mesh.rotation.y = Math.PI; // rotate 180 deg. to avoid looking at backside from the start.
|
|
|
|
|
|
|
|
|
@ -560,7 +560,7 @@ class ParadeImage {
@@ -560,7 +560,7 @@ class ParadeImage {
|
|
|
|
|
p *= config.speedFactor/1000 |
|
|
|
|
p -= config.startOffset/config.speedFactor; // start offset ( milliseconds)
|
|
|
|
|
p -= config.distanceFactor * this.position / 1000; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// factors determine scale of animation
|
|
|
|
|
let target_x = Math.sin(2*p)*config.shapeWidth; |
|
|
|
|
let target_z = Math.sin(p)*config.shapeHeight; |
|
|
|
|