Changing the color of a polygon overtime.

Hi all,

first of all, i want to thank you for the great job you guys did with Cesium.js, the API is awesome.

That being said, i did not find related topic to the one i am posting right now. So here it goes, what i am trying to do is to dynamically change the color of a polygon overtime. In order to do so, I developed some code that changes the value of rgb with an interval of time. Well the function is working, but it is not perfect. The code is also not perfect, i wrote it quickly as an example. As you can see if you paste the code below in Sandcastle, each time the color changes, there is a flashy spark over the polygons. My hypothesis is I think the flashy thing occurs because the entity is reloading the entire material. When you set the polygon material to plain (alpha channel to 255), you do not see the flashy spark when the color changes.

I am wondering, is there a better way to change the color of a polygon without having that flashy spark or reloading the entire material ?

Here is the code I used in Sandcastle,

/**************************************************************************/

var viewer = new Cesium.Viewer('cesiumContainer');

var state= {};

function loadData(jsonFile, entitiesName) {
    var statesDataSource = new Cesium.GeoJsonDataSource();
    statesDataSource.load(jsonFile).then(function () {
        viewer.dataSources.add(statesDataSource);
        // Get entities from dataSources.
        state.test = statesDataSource.entities;
    });
    //Set the camera to a US centered tilted view and switch back to moving in world coordinates.
    viewer.camera.lookAt(Cesium.Cartesian3.fromDegrees(-98.0, 40.0), new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));
    viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
}

function fadeColor(entity) {
    console.log("FADING COLOR....");
    var r=255,g=0,b=0;
    setInterval(function(){
        if (r > 0 && b === 0) {
            r--;
            g++;
        }
        if (g > 0 && r === 0) {
            g--;
            b++;
        }
        if (b > 0 && g === 0) {
            r++;
            b--;
        }
        console.log("RGB: " + r + "," + g + "," + b);
        entity.polygon.material.color.setValue(new Cesium.Color.fromBytes(r, g, b, 160));
    },120);
}

function main() {
    console.log("n_of_states: " + state.test.length);
    
    // launch fading color on one entity.
    fadeColor(state.test.values[0]);
}

loadData('../../SampleData/ne_10m_us_states.topojson', "test");
setTimeout(main, 5000);

Thanks in advance for your answer!

Best regards,

Fred

1 Like

Hi Fred,

I’m glad you like the API! We’re incredibly happy with the community of users that has built around it. :slight_smile:

As for your color animation, the flicker is caused because your geometry is being drawn asynchronously. To remove the flicker, you want to update the color per frame as opposed to at some interval. I think using a CallbackProperty would work well in your case. You define a function that is called every frame to get the new update value. Passing in false for isConstant will tell Cesium to draw the polyline synchronously, and that will get rid of the flickering.

Here’s a short example of color animation with a CallbackProperty: http://cesiumjs.org/Cesium/Apps/Sandcastle/?src=Hello%20World.html&label=Showcases&gist=635b076158394095e4a4cfa7b0cb78a6

By the way, did you know that you can paste code into Sandcastle and save a link to your example by hitting the Share button at the top? This will save your code as a gist – it’s how I’m sharing the above link. Hopefully that will make it easier for you to share code in the future.

Hope that helps!

  • Rachel

Hey Rachel,

thank you for taking the time to answer me !

You are absolutely right about making a callback function, it works perfectly! This is exactly what i wanted to do.

I didn't know about the sharing link in Cesium Sandcastle, will definitely use it next time! Thank you for letting me know.

Wish you a nice day,

Cheers!