Animating Multipolygons without flicker?

Hello,
We've been trying to animate opacity changes on a few multipolygons from a GeoJSON data source.

Currently, we're iterating through the datasource's entities every second or so using `setInterval()`

    for (var entity_idx = 0; entity_idx < region.entities.values.length; entity_idx++) {
        var entity = region.entities.getById(region.entities.values[entity_idx].id);
        entity.polygon.material.color = REGION_COLOR[name].withAlpha(state[name]);
    }

This functions reasonably well and has been the only way we could determine to animate polygones in this way in cesium. The entire code is below:

    // State for the intervals.
    var state = {
        foo: 0,
        //...
    };
    var intervalId = window.setInterval(_ => {
        // Check done at the bottom!
        let done = 0;
        for (var region_idx = 0; region_idx < viewer.dataSources.length; region_idx++) {
            var region = viewer.dataSources.get(region_idx);
    
            // ...
    
            if (state[name] >= target+0.1) {
                done++;
                continue;
            } else {
                // Set each polygon's new color.
                state[name] += 0.05;
                for (var entity_idx = 0; entity_idx < region.entities.values.length; entity_idx++) {
                    var entity = region.entities.getById(region.entities.values[entity_idx].id);
                    entity.polygon.material.color = REGION_COLOR[name].withAlpha(state[name]);
                }
            }
        }
        if (done >= 5) { window.clearInterval(intervalId); return; }
    }, 1000);

We noticed with this method there is flickering every interval, it seems to be when cesium redraws. The polgons will go opage for just a frame or two and then turn the desired opacity.

Is there a preferred way of animating opacity or is there a tactic to counteract this flickering?

Thanks,
Andrew

When you assign a material using a constant the entity assumes the value is not going to change. To have dynamic values you need to use the property see the example I made below

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var greenCylinder = viewer.entities.add({
name : ‘Green cylinder with black outline’,
position: Cesium.Cartesian3.fromDegrees(-100.0, 40.0, 200000.0),
cylinder : {
length : 400000.0,
topRadius : 200000.0,
bottomRadius : 200000.0,
material : Cesium.Color.GREEN.withAlpha(0.5),
outline : true,
outlineColor : Cesium.Color.DARK_GREEN
}
});

var redCone = viewer.entities.add({
name : ‘Red cone’,
position: Cesium.Cartesian3.fromDegrees(-105.0, 40.0, 200000.0),
cylinder : {
length : 400000.0,
topRadius : 0.0,
bottomRadius : 200000.0,
material : new Cesium.ColorMaterialProperty(
new Cesium.CallbackProperty(
function (time, result){
return Cesium.Color.fromAlpha(
Cesium.Color.RED,
(new Date(time).getTime() % 1000) / 1000,
result);
}, false))
}
});

viewer.zoomTo(viewer.entities);

``

You can any sort of conditional logic to that Callback method to vary your color and/or alpha.

Thank you, that seems to help very much!

I've successfully used with with polygon fill color, but can't get it to work with a polyline color... Any ideas? Code inside the callback isn't even called...

Is this only supported for simple color properties??

new Cesium.PolylineOutlineMaterialProperty(new Cesium.CallbackProperty(function(time, result) {
      ...
    }, false));

Hello,

Here’s an example that changes the polyline color:

var viewer = new Cesium.Viewer(‘cesiumContainer’);

viewer.entities.add({
polyline : {
positions : Cesium.Cartesian3.fromDegreesArrayHeights([-75, 39, 250000,
-125, 39, 250000]),
width : 5,
material : new Cesium.PolylineOutlineMaterialProperty({
color : new Cesium.CallbackProperty(
function (time, result){
return Cesium.Color.fromAlpha(
Cesium.Color.RED,
(new Date(time).getTime() % 1000) / 1000,
result);
}, false),
outlineWidth : 2,
outlineColor : Cesium.Color.BLACK
})
}
});

viewer.zoomTo(viewer.entities);

``

Best,

Hannah