cesium flashing point entity flashing

Posted by juneym on Sun, 19 Dec 2021 19:42:03 +0100

#Effect

See the encapsulation column below for the final complete code

#Basic ideas

You can dynamically divide the current effect into two parts, add a point and add a circle. When you click, you can dynamically change the color of the point and the size of the circle

#Implementation method

1. First, we need to generate a sphere to mark the container.

viewer = new Cesium.Viewer('cesiumContainer',{
            // terrainProvider: Cesium.createWorldTerrain(),
            // animation: false, / / controls the playback speed of scene animation
            // baseLayerPicker: true, / / basemap switching control
            // Baselayerpicker: false, / / turn off the layer selection control to add other image data
            // //fullscreenButton: false, / / full screen control
            // geocoder: false, / / location query and location control
            // homeButton: true, / / default camera position control
            // timeline: false, / / time scroll bar control
            // infoBox: false, / / whether to display the Infobox
            // sceneModePicker: false, / / show 3D/2D selector
            // selectionIndicator: false, / / click green to display the selection indicator component
            // sceneMode: Cesium.SceneMode.SCENE3D, / / set the default scene mode of 3D map: cesium SceneMode. SCENE2D,Cesium.SceneMode.SCENE3D,Cesium.SceneMode.MORPHING
            // navigationHelpButton: false, / / default camera control prompt control
            // scene3DOnly: true, / / each geometry instance is rendered only in 3D to save GPU memory
            // navigationInstructionsInitiallyVisible: false,
            // Showrenderloop errors: false, / / show rendering errors
            // Orderindependenttranslucence: false, / / set background transparency
            
        });

2. Then use the billboard in cesium to add the target point
Add data format of point

poin :  [{id:'12321321' , name: "Beijing west road test point", type: "Fixed gun", state: "on-line", position: { x: 116.4568, y: 39.8926} ,text:'X'},
         {id:'43244324' , name: "The gate of a Le repair shop", type: "Fixed gun", state: "on-line", position: {  x: 116.4568, y: 39.8944 } ,text:'+'},
         {id:'43764324', name: "Yuhua Road gas station", type: "Fixed gun", state: "on-line", position: { x: 116.4566, y: 39.8923 } ,text:'?'},
         {id:'437543345', name: "Konka pharmacy", type: "Fixed gun", state: "on-line", position: { x: 116.4513, y: 39.8923 }  ,text:'!'},],

Add point first code (class encapsulation)

//Loading point
 dragEntity(){
   let drag = new DragEntity({
     viewer:this.$store.state.viewer, 
   })
   let _this = this
   // this.poin = [{id:234,position:[122.8,39.9],text:"L"},{id:432,position:[122,39],text:"C"}]
   this.poin.forEach(item => {
     let entity = drag.addEntity(item);
     _this.poinEntity[item.id] = entity;
   })
 },
 

Create dragentity JS file

/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        //Data format {id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            monitoItems:{
                    data:value
                },
        });
        return poin
    }
    
}

To explain, we encapsulate a class class and encapsulate the method of adding points into the class for easy calling. We use the "billboard" method and PinBuilder in cesium to add target points. PinBuilder won't. You can see the official website https://sandcastle.cesium.com/?src=Map%20Pins.html&label=All Then, we will create a good entity, return it, and use an object to receive it. The purpose of using the object is to facilitate future search. Take a look at the effect

3. Step 3: let's dynamically diffuse the circle, just modify the dragentity above JS file, use the ellipse method to load the circle, and see the specific explanation of dynamic diffusion element https://blog.csdn.net/weixin_46730573/article/details/119505757?spm=1001.2014.3001.5502

/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        let minR=value.minR;//Minimum radius
        let maxR = value.maxR;// Maximum radius
        let deviationR = value.deviationR; // Size of each increase
        var r1 = minR
        function changeR1() {  
            r1=r1+deviationR;//deviationR is the size of each circle increase
            if(r1>=maxR){
                r1=minR;
            }
            return r1;
        }
        function color() {
            let x=1-r1/maxR;
            return Cesium.Color.RED.withAlpha(x);
        }
        //Data format {id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(changeR1,false),
                semiMajorAxis: new Cesium.CallbackProperty(changeR1,false),
                material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(color,false)),
                outlineColor: Cesium.Color.RED,
                show: false
            },
            monitoItems:{
                data:value
            },
        });
        return poin
    }
}

Modify the dragEntity function and add the radius size {minR:0, maxR:40, deviationR:1,} to the dynamic circle

//Loading point
    dragEntity(){
      let drag = new DragEntity({
        viewer:this.$store.state.viewer, 
      })
      let _this = this
      this.poin.forEach(item => {
        let entity = drag.addEntity(Object.assign(item,{minR:0, maxR:40, deviationR:1,}));
        _this.poinEntity[item.id] = entity;
      })
    },

Now we load the dynamic diffusion circle;

4. Let's load the click event and get the click entity

leftDownAction(){
      let viewer = this.$store.state.viewer
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        let _this = this
        let id
        _this.handler.setInputAction(function (movement) {
            let pick = viewer.scene.pick(movement.position); 
            if (Cesium.defined(pick) && (pick.id.id) ) {
                // _this.leftDownFlag = true;
                id= pick.id.id;
                 console.log(id)
            }
            
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        
    },

5. When clicking on an entity, click blink. When clicking on a blank space, clear the blink and use cesium Callbackproperty() to control the flashing of the point

	clearClick(){
      let _this = this;
      if(_this.oldId){
        _this.poinEntity[_this.oldId].billboard.color = Cesium.Color.WHITE.withAlpha(1);
        _this.poinEntity[_this.oldId].ellipse.show = false;
      }
    },
    callbackProperty(id){
      this.clearClick()
      let flog = true;
      let x = 1;
      let callbackProperty = new Cesium.CallbackProperty(function () {
        if(flog){
            x=x-0.05;
            if(x<=0){
                flog=false;
            }
        }else{
            x=x+0.05;
            if(x>=1){
                flog=true;
            }
        }
        return Cesium.Color.RED.withAlpha(x);
      },false);
      setTimeout(()=>{
        this.poinEntity[id].billboard.color = callbackProperty;
        this.poinEntity[id].ellipse.show = true;
        this.oldId = id;
      },1000)
    },

When the click event gets the id, we can call callbackProperty (id). In this function, we create a callbackProperty method to modify the property color

#Encapsulation (complete code)

Create dragentity JS file

/**
 * @param {Viewer} viewer
 * 
*/
export default class DragEntity{
    constructor(val){
        this.viewer = val.viewer,
    }
    addEntity(value){
        let minR=value.minR;//Minimum radius
        let maxR = value.maxR;// Maximum radius
        let deviationR = value.deviationR; // Size of each increase
        var r1 = minR
        function changeR1() {  
            r1=r1+deviationR;//deviationR is the size of each circle increase
            if(r1>=maxR){
                r1=minR;
            }
            return r1;
        }
        function color() {
            let x=1-r1/maxR;
            return Cesium.Color.RED.withAlpha(x);
        }
        //Data format {id:543595234324_432423,position:[122.8,39.9],text:"L"}
        let pinBuilder = new Cesium.PinBuilder();
        let poin = this.viewer.entities.add({
            id:value.id,
            name: value.name,
            position: Cesium.Cartesian3.fromDegrees(value.position.x, value.position.y),
            billboard: {
              image: pinBuilder.fromText(value.text,Cesium.Color.ROYALBLUE, 48).toDataURL(),
              verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            },
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(changeR1,false),
                semiMajorAxis: new Cesium.CallbackProperty(changeR1,false),
                material: new Cesium.ColorMaterialProperty(new Cesium.CallbackProperty(color,false)),
                outlineColor: Cesium.Color.RED,
                show: false
            },
            monitoItems:{
                data:value
            },
        });
        return poin
    }
    
}

Call in instances

import DragEntity from './dragentity.js'
data(){
    return{
      poinEntity:{},
      oldId:null,//Save last point ID
      poin :  [{id:'12321321' , name: "Beijing west road test point", type: "Fixed gun", state: "on-line", position: { x: 116.4568, y: 39.8926} ,text:'X'},
            {id:'43244324' , name: "The gate of a Le repair shop", type: "Fixed gun", state: "on-line", position: {  x: 116.4568, y: 39.8944 } ,text:'+'},
            {id:'43764324', name: "Yuhua Road gas station", type: "Fixed gun", state: "on-line", position: { x: 116.4566, y: 39.8923 } ,text:'?'},
            {id:'437543345', name: "Konka pharmacy", type: "Fixed gun", state: "on-line", position: { x: 116.4513, y: 39.8923 }  ,text:'!'},],
    }
  },
mounted(){
    this.dragEntity()
    this.leftDownAction()
},
methods:{
	// Left click event
    leftDownAction(){
      	let viewer = this.$store.state.viewer
        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        let _this = this
        let id
        _this.handler.setInputAction(function (movement) {
            let pick = viewer.scene.pick(movement.position); 
            if (Cesium.defined(pick) && (pick.id.id) ) {
                id= pick.id.id;
                 _this.callbackProperty(id)
            }else{
              _this.clearClick();
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
        
    },
    // Clearing effect
    clearClick(){
      let _this = this;
      if(_this.oldId){
        _this.poinEntity[_this.oldId].billboard.color = Cesium.Color.WHITE.withAlpha(1);
        _this.poinEntity[_this.oldId].ellipse.show = false;
      }
    },
    //Add effect display
    callbackProperty(id){
      this.clearClick()
      let flog = true;
      let x = 1;
      let callbackProperty = new Cesium.CallbackProperty(function () {
        if(flog){
            x=x-0.05;
            if(x<=0){
                flog=false;
            }
        }else{
            x=x+0.05;
            if(x>=1){
                flog=true;
            }
        }
        return Cesium.Color.RED.withAlpha(x);
      },false);
      setTimeout(()=>{
        this.poinEntity[id].billboard.color = callbackProperty;
        this.poinEntity[id].ellipse.show = true;
        this.oldId = id;
      },1000)
    },
    //Loading points and circles
    dragEntity(){
      let drag = new DragEntity({
        viewer:this.$store.state.viewer, 
      })
      let _this = this
      // this.poin = [{id:234,position:[122.8,39.9],text:"L"},{id:432,position:[122,39],text:"C"}]
      this.poin.forEach(item => {
        let entity = drag.addEntity(Object.assign(item,{minR:0, maxR:40, deviationR:1,}));
        _this.poinEntity[item.id] = entity;
      })
    },
}

If you want a complete demo, you can write a private note

Topics: Vue.js cesium