cesium实现六边形扩散效果


Cesium实战系列文章总目录传送门

1.实现效果

在这里插入图片描述

2.实现方法

2.1调用方法

引入该类的js文件后直接调用即可,需要设置该六边形的名称及其参数。

// 六边形扩散
const hexagonSpread1 = new HexagonSpread(this.viewer, "hexagonSpred1");
hexagonSpread1.add([113.934, 22.552, 0], '#0099BF', 1000, 7500)

2.2材质设置

/***
 * 六边形扩散效果
 * 参考gitee开源ts代码
 * 取消import和export,整合两个类
 */

// 点效果集合 父类
class Effect {
    viewer;
    id;
    duration;
    maxRadius;
    pointDraged;
    leftDownFlag;
    update_position;
    constructor(viewer, id) {
        this.viewer = viewer
        this.id = id
        this.duration = 1000
        this.maxRadius = 1000
        this.pointDraged = null
        this.leftDownFlag = false
    }
    change_duration(d) {
        this.duration = d
    }
    change_color(val) {
        const curEntity = this.viewer.entities.getById(this.id)
        curEntity._ellipse._material.color = new Cesium.Color.fromCssColorString(
            val
        )
    }
    change_position(p) {
        const cartesian3 = Cesium.Cartesian3.fromDegrees(
            parseFloat(p[0]),
            parseFloat(p[1]),
            parseFloat(p[2])
        )
        const curEntity = this.viewer.entities.getById(this.id)
        curEntity.position = cartesian3
    }
    del() {
        this.viewer.entities.removeById(this.id)
    }
    add(
        position,
        color,
        maxRadius,
        duration,
        isEdit = false
    ) {
        const _this = this
        this.duration = duration
        this.maxRadius = maxRadius
        if (!isEdit) {
            return
        }

        function leftDownAction(e) {
            _this.pointDraged = _this.viewer.scene.pick(e.position) // 选取当前的entity
            if (
                _this.pointDraged &&
                _this.pointDraged.id &&
                _this.pointDraged.id.id === _this.id
            ) {
                _this.leftDownFlag = true
                _this.viewer.scene.screenSpaceCameraController.enableRotate = false // 锁定相机
            }
        }

        function leftUpAction(e) {
            _this.leftDownFlag = false
            _this.pointDraged = null
            _this.viewer.scene.screenSpaceCameraController.enableRotate = true // 解锁相机
        }

        function mouseMoveAction(e) {
            if (
                _this.leftDownFlag === true &&
                _this.pointDraged !== null &&
                _this.pointDraged !== undefined
            ) {
                const ray = _this.viewer.camera.getPickRay(e.endPosition)
                const cartesian = _this.viewer.scene.globe.pick(ray, _this.viewer.scene)
                _this.pointDraged.id.position = cartesian // 此处根据具体entity来处理,也可能是pointDraged.id.position=cartesian;
                    // 这里笛卡尔坐标转 经纬度
                const ellipsoid = _this.viewer.scene.globe.ellipsoid
                const cartographic = ellipsoid.cartesianToCartographic(cartesian)
                const lat = Cesium.Math.toDegrees(cartographic.latitude)
                const lng = Cesium.Math.toDegrees(cartographic.longitude)
                let alt = cartographic.height
                alt = alt < 0 ? 0 : alt
                if (_this.update_position) {
                    _this.update_position([lng.toFixed(8), lat.toFixed(8), alt])
                }
            }
        }
        this.viewer.screenSpaceEventHandler.setInputAction(
            leftDownAction,
            Cesium.ScreenSpaceEventType.LEFT_DOWN
        )
        this.viewer.screenSpaceEventHandler.setInputAction(
            leftUpAction,
            Cesium.ScreenSpaceEventType.LEFT_UP
        )
        this.viewer.screenSpaceEventHandler.setInputAction(
            mouseMoveAction,
            Cesium.ScreenSpaceEventType.MOUSE_MOVE
        )
    }
}

/**
 * 六边形扩散材质
 * @date:2022-01-12
 */
function HexagonSpreadMaterialProperty(color) {
    this._definitionChanged = new Cesium.Event()
    this._color = undefined
    this._colorSubscription = undefined
    this.color = color
    this._time = new Date().getTime()
}
Object.defineProperties(HexagonSpreadMaterialProperty.prototype, {
    isConstant: {
        get: function() {
            return false
        },
    },
    definitionChanged: {
        get: function() {
            return this._definitionChanged
        },
    },
    color: Cesium.createPropertyDescriptor('color'),
})
HexagonSpreadMaterialProperty.prototype.getType = function(_time) {
    return Cesium.Material.HexagonSpreadMaterialType
}
HexagonSpreadMaterialProperty.prototype.getValue = function(
    time,
    result
) {
    if (!Cesium.defined(result)) {
        result = {}
    }
    result.color = Cesium.Property.getValueOrClonedDefault(
        this._color,
        time,
        Cesium.Color.WHITE,
        result.color
    )
    result.image = Cesium.Material.HexagonSpreadMaterialImage
    return result
}
HexagonSpreadMaterialProperty.prototype.equals = function(other) {
    const reData = (
        this === other ||
        (other instanceof HexagonSpreadMaterialProperty &&
            Cesium.Property.equals(this._color, other._color))
    )
    return reData
}
Cesium.HexagonSpreadMaterialProperty = HexagonSpreadMaterialProperty
Cesium.Material.HexagonSpreadMaterialType = 'HexagonSpreadMaterial'
Cesium.Material.HexagonSpreadMaterialImage = './../../data/pictures/hexagon.png'
Cesium.Material.HexagonSpreadSource = `
  czm_material czm_getMaterial(czm_materialInput materialInput)
  {
       czm_material material = czm_getDefaultMaterial(materialInput);
       vec2 st = materialInput.st;
       vec4 colorImage = texture2D(image,  vec2(st));
       material.alpha = colorImage.a * color.a * 0.5;
       material.diffuse =  1.8 * color.rgb  ;
       return material;
   }
   `
Cesium.Material._materialCache.addMaterial(
    Cesium.Material.HexagonSpreadMaterialType, {
        fabric: {
            type: Cesium.Material.HexagonSpreadMaterialType,
            uniforms: {
                color: new Cesium.Color(1, 0, 0, 0.5),
                image: Cesium.Material.HexagonSpreadMaterialImage,
            },
            source: Cesium.Material.HexagonSpreadSource,
        },
        translucent: function(material) {
            return true
        },
    }
)

// 六边形扩散效果
class HexagonSpread extends Effect {
    constructor(viewer, id) {
        super(viewer, id)
    }
    add(position, color, maxRadius, duration, isedit = false) {
        super.add(position, color, maxRadius, duration, isedit)
        const _this = this
        let currentRadius = 1
        this.viewer.entities.add({
            id: _this.id,
            position: Cesium.Cartesian3.fromDegrees(
                position[0],
                position[1],
                position[2]
            ),
            ellipse: {
                semiMajorAxis: new Cesium.CallbackProperty(function(n) {
                    currentRadius += (1000 / _this.duration) * 50
                    if (currentRadius > _this.maxRadius) {
                        currentRadius = 1
                    }
                    return currentRadius
                }, false),
                semiMinorAxis: new Cesium.CallbackProperty(function(n) {
                    return currentRadius
                }, false),
                material: new Cesium.HexagonSpreadMaterialProperty(
                    new Cesium.Color.fromCssColorString(color)
                ),
            },
        })
    }
}
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
要在Cesium实现抛物线效果,可以使用贝塞尔曲线来模拟抛物线的路径。以下是实现抛物线效果的步骤: 1. 使用entity方式创建一个新的实体对象。 2. 设置实体的position为抛物线的起始点。 3. 使用polyline实例化一个新的PolylineGraphics对象。 4. 将PolylineGraphics对象的positions属性设置为一个包含抛物线路径上的点的数组。 5. 设置PolylineGraphics对象的material为所需的抛物线材质。 6. 将PolylineGraphics对象添加到viewer中。 下面是一个示例代码,展示了如何在Cesium实现抛物线效果: ```javascript // 创建起始点和终点 var start = Cesium.Cartesian3.fromDegrees(113.9236839, 22.528061); var end = Cesium.Cartesian3.fromDegrees(113.925, 22.53); // 计算控制点 var controlPoint = new Cesium.Cartesian3( (start.x + end.x) / 2, (start.y + end.y) / 2, (start.z + end.z) / 2 + 1000 ); // 计算抛物线路径上的点 var numberOfPoints = 100; var positions = []; for (var i = 0; i <= numberOfPoints; i++) { var t = i / numberOfPoints; var x = (1 - t) * (1 - t) * start.x + 2 * (1 - t) * t * controlPoint.x + t * t * end.x; var y = (1 - t) * (1 - t) * start.y + 2 * (1 - t) * t * controlPoint.y + t * t * end.y; var z = (1 - t) * (1 - t) * start.z + 2 * (1 - t) * t * controlPoint.z + t * t * end.z; positions.push(new Cesium.Cartesian3(x, y, z)); } // 创建实体对象 viewer.entities.add({ polyline: { positions: positions, width: 10, material: new Cesium.PolylineGlowMaterialProperty({ glowPower: 0.5, color: Cesium.Color.YELLOW }) } }); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值