[SOLVED] Did my camera position change in the last second?

camera-controls

#1

I have a PerspectiveCamera and control it with OrbitControls. After my init() function is called (this is just a cube, at world center), I call my animate() function:

function animate() {
  requestAnimationFrame(animate);
  controls.update();
  console.log('animation',controls.getAzimuthalAngle(), controls.getPolarAngle(),camera.position.x);
};

This nicely logs the values that I need, see screenshot below.

Question: Is there an elegant way to trigger/call a function if the user has not moved the camera position in the last second? I would prefer to wait x number of frames or seconds before that function is called.

In my actual application, that function will use the FileLoader to load a new JSON file, and I do not want to retrieve that file while the user is still moving around and has not waited for about 1 second.


#2

Just a quick idea, there might be way better solutions.

class CustomDelay{
    constructor(){
        this.timer = null;
    }
    Timeout(fun= ()=>{},ms){
        clearTimeout(this.timer);
        this.timer = setTimeout(()=>{
            fun()
        },ms)
    }
}
const myDelay = new CustomDelay();
window.addEventListener('click', function () {
    console.log('Clicked');
    myDelay.Timeout(() => {
        console.log('DELAY');
    },1000);
});

You would have to call Timeout method every time you move your camera


#3

Thanks for your reply!

I have tried to plug your code into my project and it works for the click event as you can see in my jsfiddle. I also tried to trigger the cameraOrbitChange() function on the scroll, wheel, or mousewheel events, but failed. As I am working on an Earth visualization, users will zoom in and out with the mousewheel, which should trigger a change in the camera position and update the map.

I apologize if my jsfiddle is not super cleaned up. Truly appreciate your help!

Edit: I just noticed that my three.js application starts as a small black box in the upper right corner, you just have to click-and-drag it and the cube will show up - not sure why that is…


#4

I was thinking about this kind of check:
https://jsfiddle.net/szyt9nka/1/

const myDelay = new CustomDelay();
var camX = camera.position.x;
var camY = camera.position.y;
var camZ = camera.position.z;

function render() {
  if (camX !== camera.position.x && camY !== camera.position.y && camZ !== camera.position.z) {
    myDelay.Timeout(() => {
      cameraOrbitChange();
    }, 1000);
  }

  camX = camera.position.x;
  camY = camera.position.y;
  camZ = camera.position.z;
  renderer.render(scene, camera);
}

but in your fiddle you’re rendering scene after camera update, so you could also use this code:

const myDelay = new CustomDelay();
function render() {
  myDelay.Timeout(() => {
    cameraOrbitChange();
  }, 1000);

  renderer.render(scene, camera);
}

Edit: black box shows up because you forgot to call render function


#5

Thanks, @MateuszWis! This works beautifully. I updated my code with the render() function you provided, and it works exactly as expected. Good stuff!