Reputation: 5639
What I'd like to do is control the clock ticks for a non-realtime Cesium application. Imagine there's expensive code running, plus I want to give the viewer time to load the tiles before continuing. So how do I disable automatic ticking, and then call tick() manually when my code is ready for it?
Docs for Cesium.Clock say "The clock will only tick when both Clock#canAnimate and Clock#shouldAnimate are true." but that's not what I'm getting. What I currently see:
viewer.clock.canAnimate = false;
viewer.clock.shouldAnimate = false;
viewer.clock.onTick.addEventListener(function(clock){
console.log("Tick");
});
The result in the console shows the clock still ticking:
Tick
Tick
Tick
Tick
...
What I'd like to do:
viewer.clock.stopTicking(); // or whatever that command would be...
while (someCondition){
// run expensive code
tick(); // issue manual tick
}
Thanks for your help! Max
Upvotes: 4
Views: 5366
Reputation: 12448
It's a bit of a legacy quirk of the Cesium API that the Clock's onTick
event fires for every animation frame rendered, regardless of whether the clock advances in time or not.
If you want to take control of Cesium's render loop yourself, you can do that like this:
viewer.useDefaultRenderLoop = false;
function myOwnRenderLoop() {
viewer.resize();
viewer.render();
Cesium.requestAnimationFrame(myOwnRenderLoop);
}
Cesium.requestAnimationFrame(myOwnRenderLoop);
Above, I'm using requestAnimationFrame
, so the loop runs as fast as possible. But I could replace that with setTimeout
to get a slower loop, emulating poor render performance. Note that interactivity and screen updates would slow down with such a method when longer time intervals are used.
viewer.useDefaultRenderLoop = false;
function myOwnRenderLoop() {
viewer.resize();
viewer.render();
window.setTimeout(myOwnRenderLoop, 500);
}
window.setTimeout(myOwnRenderLoop, 500);
Upvotes: 3
Reputation: 1899
So, your console.log
is still printing 'Tick' because the onTick
continues to fire, regardless of whether the clock is advancing. All you need to do is toggle both the canAnimate
and shouldAnimate
, as you suspected. So, your example code would basically be:
viewer.clock.canAnimate = false;
viewer.clock.shouldAnimate = false;
while (someCondition){
// run expensive code
// toggle someCondition so we can exit this
}
// set the animate bools back to true so the clock can advance
viewer.clock.canAnimate = true;
viewer.clock.shouldAnimate = true;
To better see this in action, try this (and maybe set the if conditional to 1000 instead of 100):
viewer.clock.canAnimate = false;
viewer.clock.shouldAnimate = false;
var s = 0;
viewer.clock.onTick.addEventListener(function(clock){
if (s < 100) {
console.log(viewer.clock.currentTime);
} else {
viewer.clock.canAnimate = true;
viewer.clock.shouldAnimate = true;
}
s++;
});
You'll see that the console.log
is printing the same value for 100 (or 1000) times...this is because the currentTime
isn't advancing because of the canAnimate
and shouldAnimate
. Once those are both toggled back to true
, the currentTime
will advance.
Upvotes: 2