Cesium splitscreen

Good afternoon,

I am trying to build a split screen tool on a project using cesium split direction methods and constants
I used this sandcastle example https://sandcastle.cesium.com/?src=Imagery%20Layers%20Split.html and adapted it to my code.

It works just fine when I add a layer one by one, each to its respective side.
A feature I would like to add to the project is to push to a layer (already added to the map) to the left side of the slide bar when activating the split screen tool.
The problem is that when doing so, the layer is added (already checked with the debugger and saw its properties - show property is also set to true) but its not rendered on the screen at all. Even when I manually remove the layer and add it again to the map, splitting it to the left side it does not appear.

It becomes visible only when I move the split screen slide bar.

An example of what I am trying to do is here:

private enableSplitScreen(layer: Layer) {

    this.splitScreenMode.enabled = true;

    let handler = new Cesium.ScreenSpaceEventHandler(this.slider);

    let moveActive: boolean = false;

    let move = ( movement => {

        if (!moveActive)
        return;

        const relativeOffset = movement.endPosition.x;
        const splitPosition = (this.slider.offsetLeft + relativeOffset) / this.slider.parentElement.offsetWidth;

        this.slider.style.left = 100.0 * splitPosition + "%";
        this.viewer.scene.imagerySplitPosition = splitPosition;

        this.viewer.scene.requestRender();
    });

    handler.setInputAction(() => { moveActive = true }, Cesium.ScreenSpaceEventType.LEFT_DOWN);

    handler.setInputAction(() => { moveActive = true }, Cesium.ScreenSpaceEventType.PINCH_START);

    handler.setInputAction(move, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    handler.setInputAction(move, Cesium.ScreenSpaceEventType.PINCH_MOVE);

    handler.setInputAction(() => { moveActive = false }, Cesium.ScreenSpaceEventType.LEFT_UP);

    handler.setInputAction(() => { moveActive = false }, Cesium.ScreenSpaceEventType.PINCH_END);

    //If there is a layer on map already, push it to the left side
    if (layer !== undefined) {
        let layerToPushLeft = this.getLayerFromMap(layer);
        layerToPushLeft.splitDirection = Cesium.ImagerySplitDirection.LEFT;
        this.splitScreenMode.leftLayerAdded = true;
        this.viewer.scene.imagerySplitPosition = this.slider.offsetLeft / this.slider.parentElement.offsetWidth;
    }

I am using 1.64 cesium version

Thanks for the help

1 Like

Welcome to the Cesium community!

Are you able to reproduce this issue in Sandcastle? I’ve modified the example you link to, and I am able to add a layer dynamically to the left side of the view.

See my modified Sandcastle here.

Thank you!

No, I can’t reproduce what I am doing to sandcastle at 100% because I am using angular and typescript
Yeah, I see your example and it did work for me as well
In my code I can also add and remove a layer dynamically. The problem stands for when I activate the “split screen mode” with an already added layer and simply change its split direction to left. The layer is on the map, it just doesn’t render, only when I move the slider or add a right side layer

It doesn’t need to be 100%, if you can just create a simple Sandcastle reproducing the issue that’d help narrow down whether it’s a bug or something else.

I can’t reproduce it because I am not using the sandcastle environment.
I feel that the issue I am having is related with the different functions scopes, since I am using Cesium in a typescript code. Beyond that, in the sandcastle environment the problem I’m facing doesn’t happen, I can access the imagery layer collection and change the split direction normally. Doing so, renders immediately the layer on the map

I’m also using Cesium from Angular (TS). There are some gotchas going in and out of Angular space. In some places, I have to inject NgZone in my components, so that I can interact with Cesium using this.zone.runOutsideAngular, or from a Cesium-triggered callback (like various ScreenSpaceEventHandler actions), using this.zone.run. Here’s a simple test: if you wrap your callbacks in setTimeout(myCallback, 1) and it starts working, you probably need better Zone management and/or change detection. (That’s outside the scope of this site, but hopefully it could get you moving in the right direction.)

1 Like

Thank you James, I will search on NgZone and try to solve the issue!

I tried to use the setTimeout function wrapping my callbacks but it didn’t work
Using ngZone to handle cesium did not work as well
Its a very strange issue due to the fact that it seems that the cesium is waiting for some kind of action or movement from the slider or another layers to move on…

I think reproducing a minimal test case with the same symptoms would be very helpful. Could you use the default Angular template on StackBlitz as a starting point, then load Cesium from a CDN and try to make a test case for the feature you’re using there?

Hey MisterHappy,

If you move the slider programmatically, does it work correctly? If not, then it is definitely a problem with the change detection mechanism of the Angular framework. Otherwise, it should be something related with your Cesium code.