1. Creating a Pulsing Point Entity
The following example demonstrates how to make a point entity flash by oscillating the alpha channel of its color. We define a state variable to track the current opacity level and a directional flag to switch between fading in and out.
function createPulsingPoint() {
let currentOpacity = 1.0;
let isFadingOut = true;
viewer.entities.add({
name: "Pulsing Point Entity",
position: Cesium.Cartesian3.fromDegrees(116.23, 39.56, 0),
point: {
pixelSize: 15,
color: new Cesium.CallbackProperty(function() {
// Adjust opacity incrementally
if (isFadingOut) {
currentOpacity -= 0.04;
if (currentOpacity <= 0) {
isFadingOut = false;
}
} else {
currentOpacity += 0.04;
if (currentOpacity >= 1) {
isFadingOut = true;
}
}
return Cesium.Color.CYAN.withAlpha(currentOpacity);
}, false),
outlineWidth: 0,
outlineColor: Cesium.Color.TRANSPARENT
}
});
}
2. Flashing Ellipse (Area) Entity
To polygon or area-based entities like ellipses, we apply the same logic to the material property. By wrapping the color callback in a ColorMaterialProperty, we can control the transparency of the surface.
function createFlashingEllipse() {
let alphaLevel = 1.0;
let direction = -1; // -1 for fading, 1 for brightening
viewer.entities.add({
name: "Flashing Circular Zone",
position: Cesium.Cartesian3.fromDegrees(116.20, 39.53, 0),
ellipse: {
semiMinorAxis: 2500.0,
semiMajorAxis: 2500.0,
material: new Cesium.ColorMaterialProperty(
new Cesium.CallbackProperty(function() {
alphaLevel += 0.02 * direction;
// Reverse direction at boundaries
if (alphaLevel <= 0.1) {
direction = 1;
} else if (alphaLevel >= 1.0) {
direction = -1;
}
return Cesium.Color.RED.withAlpha(alphaLevel);
}, false)
)
}
});
}
3. Toggling Billboard Visibility
Bilbloard images can be made to "blink" by toggling their show property. Instead of fading transparency, we use a threshold value to switch the visibility state on and off rapidly.
function createBlinkingBillboard() {
let fadeFactor = 1.0;
let isDecreasing = true;
viewer.entities.add({
name: 'Warning Billboard',
position: Cesium.Cartesian3.fromDegrees(116.20, 39.53),
billboard: {
image: 'warning_icon.png',
width: 64,
height: 64,
// Toggle visibility based on the fade factor
show: new Cesium.CallbackProperty(function() {
if (isDecreasing) {
fadeFactor -= 0.05;
if (fadeFactor <= 0) {
isDecreasing = false;
}
} else {
fadeFactor += 0.05;
if (fadeFactor >= 1) {
isDecreasing = true;
}
}
// Return true if factor is above 0.5, creating a strobe effect
return fadeFactor > 0.5;
}, false)
}
});
}
4. Advanced Breathing Effect (Radius and Color)
To create a "breathing" animation where the circle expands and fades simultaneous, we synchronize the semiMinorAxis, semiMajorAxis, and the material color. The radius increases while the opacity decreases.
const minR = 50;
const maxR = 150;
let currentRadius = minR;
let isExpanding = true;
const position = Cesium.Cartesian3.fromDegrees(120.191, 30.255, 100);
// Callback for dynamic radius
const getDynamicRadius = () => {
return new Cesium.CallbackProperty(() => {
const step = 1.0;
if (isExpanding) {
currentRadius += step;
if (currentRadius >= maxR) isExpanding = false;
} else {
currentRadius -= step;
if (currentRadius <= minR) isExpanding = true;
}
return currentRadius;
}, false);
};
// Callback for dynamic color based on radius
const getDynamicColor = () => {
return new Cesium.CallbackProperty(() => {
// Calculate opacity inversely proportional to radius
const opacity = 1 - (currentRadius - minR) / (maxR - minR);
return new Cesium.Color(1, 0.5, 0, opacity);
}, false);
};
viewer.entities.add({
position: position,
ellipse: {
semiMinorAxis: getDynamicRadius(),
semiMajorAxis: getDynamicRadius(),
material: new Cesium.ColorMaterialProperty(getDynamicColor()),
height: 0,
outline: false
}
});
5. Randomizing Colors for Polyline Volumes
You can also use CallbackProperty to generate random effects, such as changing the color of a geometry continuously on every frame.
function createRandomColorTube() {
const shape = computeCircle(6000.0);
viewer.entities.add({
name: 'Random Color Tube',
polylineVolume: {
positions: Cesium.Cartesian3.fromDegreesArray([
-85.0, 32.0,
-85.0, 36.0,
-89.0, 36.0
]),
shape: shape,
material: new Cesium.ColorMaterialProperty(
new Cesium.CallbackProperty(function() {
return Cesium.Color.fromRandom({
minimumRed: 0.5,
minimumGreen: 0.5,
minimumBlue: 0.5,
alpha: 1.0
});
}, false)
)
}
});
viewer.zoomTo(viewer.entities);
}
// Helper function to generate circle shape
function computeCircle(radius) {
const positions = [];
for (let i = 0; i < 360; i++) {
const rad = Cesium.Math.toRadians(i);
positions.push(new Cesium.Cartesian2(radius * Math.cos(rad), radius * Math.sin(rad)));
}
return positions;
}