Keeping Cesium pointing North: camera.constrainedAxis being ignored?

Could you help me figure out how to force the Cesium viewer to keep north pointing toward the top of the screen with the camera looking directly toward the center of the Earth?

With javascript alert( ), I've checked that equals Cesium.Cartesian3.UNIT_Z, which I thought would force north to remain pointing toward the top of the screen while I pan around by dragging with the mouse. However, it appears that my Cesium viewer is acting as if constrained axis were undefined, because as I pan around, north slowly rotates until it's off at some odd angle other than straight toward the top of the screen.

A google search doesn't seem to come up with any useful hints, so any help you can provide would be appreciated.

I am a Google Earth user trying to switch to Cesium. It used to annoy me that Google Earth would always have north slowly rotating as I panned, so I would consider it a major step forward if there were a setting in the Cesium javascript interface that would allow me to keep north pointing toward the top of the screen.


Hello Owen,

The constrainedAxis parameter is set to UNIT_Z by default. This keeps you from panning over the poles.

I don’t think we have anything built in to always keep the axis always pointing up, but you can add a pre-render event to force the camera heading to always be zero. This makes the tilt behavior a little weird, but it works pretty well. Here is an example:

var viewer = new Cesium.Viewer(‘cesiumContainer’);
var camera =;
viewer.scene.preRender.addEventListener(function() {
orientation: {
heading: 0,
pitch: camera.pitch,
roll: camera.roll





Thank you. I put the viewer.scene.preRender.addEventListener( ) call that you suggested in my page and now, no matter where I navigate, north is always pointing toward the top of the screen, just like I want!

Is there some place where I can learn about how the main "event loop" works in Cesium? Somewhere in the Cesium javascript library, there must be an event loop that fires off any accumulated navigation events from the mouse or from camera.setView( ) or from any add/remove object events from javascript calls on the HTML page. Also, something in the main event loop must be deciding when the screen should be updated (rerendered).

Here is how this question comes up: Until now, I had thought that when I called camera.setView( ), then camera.setView( ) updated the camera position and triggered a render event. However, now I realize that this can't be true. It can't be that camera.setView( ) is triggering a render event. Instead, it must be that the render event is triggered by something in the main event loop and outside of any specific function like camera.setView( ). Otherwise, if camera.setView( ) did actually trigger a render event, then you would get an infinite loop if you called camera.setView( ) from within the prerender listener (a render event would call prerender which would trigger another render event, etc).


Hi Owen,

The main render loop is activated by the CesiumWidget. Here is the code:

In the loop, it calls Scene.render. Then in Scene, it fires off the preRender event before render and the postRender event after rendering that frame has finished. Here is the code for scene.render if you’re curious:

Does that answer your question?




Thank you for your help. My Cesium application is working now for viewing NASA global precipitation estimates in near-realtime. Here is the link if you want to take a look:


Nice app Owen!

Hi all,

Issue #4639 was just fixed by #5603. It will be in Cesium 1.38 on October 2.