diff --git a/parade.js b/parade.js index 32340e4..fb12795 100644 --- a/parade.js +++ b/parade.js @@ -10,6 +10,7 @@ var config = { playDuration: 16, // seconds. how long should audio play after dragging/pressing next. Something like audio duration / nr of images. Note that if everything is sorted interview will just continue; textColor: "orange", font: "bold 70px Arial", + returnToSpectatorCamTimeout: 3000, // ms, when dragging weight slider, after release, how long should it take before reversing to spectator camera position } // polyfill @@ -164,7 +165,7 @@ class Parade { // }); this.audioEl.addEventListener('seeking',(e)=>{ this.t = parseInt(e.target.currentTime * 1000); - console.log('restore timer',this.t,e); + // console.log('restore timer',this.t,e); }); if(!time) return; @@ -200,6 +201,13 @@ class Parade { // set maximum to last image index this.sorterTemplate.content.querySelector('.weight').max = this.images.length - 1; + this.followCameraTimeout = null; + document.body.addEventListener('mouseup', () => { + // because the movement of the image can be a bit slower, we set a timeout instead + // of going straight back into spectator position + this.followCameraTimeout = setTimeout(this.stopFollowSortingImage.bind(this), this.config['returnToSpectatorCamTimeout']); + }); + this.changeSorterImage(); } @@ -242,11 +250,23 @@ class Parade { // weightEl.value = parseInt(image.info['weight']); weightEl.value = parseInt(this.imageToSort.position); // don't use weight, but the image's actual position weightEl.addEventListener('input', this.changeSorterWeight.bind(this)); + weightEl.addEventListener('mousedown', this.followSortingImage.bind(this)); sorterContent.innerHTML = ""; sorterContent.appendChild(clone); } + followSortingImage() { + clearTimeout(this.followCameraTimeout); // cancel any pending return to spectator cam + // this.imgCamera.lockedTarget = this.imageToSort.mesh; + this.imgCamera.parent = this.imageToSort.mesh; + this.scene.activeCamera = this.imgCamera; + } + + stopFollowSortingImage() { + this.scene.activeCamera = this.spectatorCamera; + } + changeSorterWeight(ev) { this.play(); @@ -366,15 +386,41 @@ class Parade { // 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( -11.79906036421707, -0.7028999316894499, 32.43524104627659 ), this.scene); - camera.rotation = new BABYLON.Vector3(-0.16070762395712468, 2.4005702973639886, 0); - camera.fov = 1.5; - // camera.rotation = new BABYLON.Vector3(0.1, 0,0); - // camera.lowerRadiusLimit = 6; - // camera.upperRadiusLimit = 20; + + // CAM 1: the specatator position. + this.spectatorCamera = new BABYLON.UniversalCamera("SpectatorCam", new BABYLON.Vector3( -11.79906036421707, -0.7028999316894499, 32.43524104627659 ), this.scene); + this.spectatorCamera.rotation = new BABYLON.Vector3(-0.16070762395712468, 2.4005702973639886, 0); + this.spectatorCamera.fov = 1.5; + // this.spectatorCamera.rotation = new BABYLON.Vector3(0.1, 0,0); + // this.spectatorCamera.lowerRadiusLimit = 6; + // this.spectatorCamera.upperRadiusLimit = 20; // This attaches the camera to the canvas - camera.attachControl(this.canvasEl, true); + 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); + this.imgCamera.position = new BABYLON.Vector3(20,10,-20); + + // // this.imgCamera = new BABYLON.FollowCamera("FollowCam", new BABYLON.Vector3(0, 10, -10), this.scene); + // // The goal distance of camera from target + // this.imgCamera.radius = 50; + // // The goal height of camera above local origin (centre) of target + // this.imgCamera.heightOffset = 20; + // // The goal rotation of camera around local origin (centre) of target in x y plane + // this.imgCamera.rotationOffset = 120; //degree + // // Acceleration of camera in moving from current to goal position + // this.imgCamera.cameraAcceleration = 0.1; + // // The speed at which acceleration is halted + // this.imgCamera.maxCameraSpeed = 100 + // This attaches the camera to the canvas (disabled for now) + // this.imgCamera.attachControl(this.canvasEl, true); + // this.imgCamera.lockedTarget = null; // So far there's nothing to track yet + + + this.scene.activeCamera = this.spectatorCamera; + for(let i in this.images) { // create the Meshes with the images in the scene this.images[i].makeMesh(this.scene, this.config); @@ -382,6 +428,9 @@ class Parade { this.lastRenderTime = window.performance.now(); + + // this.scene.registerBeforeRender(this.animate.bind(this)); // we now do this in renderLoop().. for some reason works better/different? + return this.scene; } }