绘制动态立体墙

关键引入文件:

  • 第一步:引入框架地图关键文件
    • https://mhc.ixiera.com/mhc/main_min.js
    • https://mhc.ixiera.com/mhc/Cesium-1.120/Build/Cesium/Cesium.js
    • https://mhc.ixiera.com/mhc/Cesium3DTile.js
  • 第二步:引入动态立体墙绘制文件
    • https://mhc.ixiera.com/mhc/mchmap/DynamicWall/js/DynamicWall.min.js

1. 初始化

wall = new DynamicWall(viewer, options);

2. 参数说明

一、构造函数参数。

参数数据类型是否必填说明
viewerObject必填Cesium Viewer 实例
optionsObject选填全局配置参数(详见下方表格)

二、draw 方法配置参数(也可在构造函数中传入)。

参数数据类型是否必填默认值说明
positionsArray必填-墙体底面坐标,格式 [[lon, lat], ...](经纬度数组)
heightnumber选填100墙体高度(米)
arrowTypestring选填undefined箭头类型:'arrow'、'chevron'、'triangle'、'line'、'dot'、'custom',不设置则不显示
arrowDirectionstring选填'left'箭头指向:'left'、'right'、'up'、'down'、'both'
arrowSizenumber选填28箭头尺寸(像素)
arrowThicknessnumber选填0.5箭头粗细系数(0~1)
arrowGapnumber选填18箭头间距(像素)
flowAxisstring选填'horizontal'流动方向:'horizontal'(水平)或 'vertical'(垂直)
flowSpeednumber选填2.0流动速度
flowDirectionstring选填'forward'流动方向:'forward'(正向)或 'backward'(反向)。
水平:正向=向右,反向=向左;垂直:正向=向上,反向=向下
colorstring选填'#ffff00'箭头颜色(CSS 颜色字符串)
opacitynumber选填0.9箭头整体透明度(0~1)
scanModestring选填'none'扫描模式:'none'、'vertical'(垂直线)或 'horizontal'(水平线)
scanColorstring选填'#ff0000'扫描线颜色
scanSpeednumber选填1.0扫描速度
scanDirectionstring选填'up'扫描方向:垂直时为 'up'/'down',水平时为 'right'/'left'
scanWidthnumber选填0.3扫描线宽度(占画布高度的比例)
scanOpacitynumber选填0.8扫描线透明度
scanGradientboolean选填true是否启用渐变边缘
borderColorstring选填'#ffaa00'边框颜色
borderWidthnumber选填2.0边框线宽(像素)
borderGlownumber选填0.3边框发光强度
showBorderboolean选填true是否显示边框
textureTypestring选填'canvas'纹理类型:'canvas'(内置箭头)或 'image'(外部图片)
imageUrlstring选填null图片地址(DataURL 或 URL)
imageRepeatObject选填{x:10, y:1}水平/垂直重复次数({x: number, y: number})
imageColorstring选填'#ffffff'图片叠加颜色(白色为原色)
animationTypestring选填'flow'动画类型:'flow'(流动)或 'pulse'(脉冲闪烁)
pulseSpeednumber选填1.0脉冲速度
repeatVerticalboolean选填false图片纹理/箭头垂直方向是否多行
verticalCountnumber选填1垂直行数(仅 repeatVertical: true 时生效)
canvasWidthnumber选填1024内部画布宽度(像素),影响纹理分辨率
canvasHeightnumber选填128内部画布高度(像素),影响纹理分辨率
backgroundColorstring选填null墙体背景色(CSS 颜色字符串),默认透明
backgroundOpacitynumber选填0背景透明度(0~1),仅在 backgroundColor 不为空时生效
customDrawfunction选填null自定义绘制函数 (ctx, x, y, size, config) => {...}
cameraOffsetnumber选填600飞向墙体时的附加距离(米)
cameraPitchnumber选填-35相机俯仰角(度)

三、API 方法

方法名参数返回值说明
draw(params)ObjectDynamicWall绘制墙体,params 可覆盖任何配置项
update(options)ObjectDynamicWall更新墙体配置并重新绘制(保留原 positions)
clear()DynamicWall清除所有墙体实体及边框
toggle(visible)boolean(可选)boolean切换显示/隐藏,返回当前可见状态
flyTo(options)ObjectDynamicWall相机飞向墙体中心,options:{ cameraOffset, cameraPitch, heading, duration }
getCenter()Cartesian3获取墙体中心点坐标
getBoundingBox()BoundingSphere获取墙体外接球体
destroy()void销毁实例,释放资源

4. 使用示例

4.1 基础绘制(水平流动箭头)

// 定义墙体底面坐标

const positions = [

    [116.3860, 39.9060],

    [116.3940, 39.9060],

    [116.3940, 39.9140],

    [116.3860, 39.9140]

];

 

// 绘制带箭头的墙体

const wall = new DynamicWall(viewer, {

    positions: positions,

    height: 120,

    arrowType: 'arrow',

    arrowDirection: 'left',

    color: '#ffff00',

    flowSpeed: 2.0,

    borderColor: '#ffaa00',

    showBorder: true

});

wall.draw();

wall.flyTo();

4.2 垂直流动(向上/向下)

// 向上流动(forward)

wall.draw({

    flowAxis: 'vertical',

    flowDirection: 'forward',

    arrowDirection: 'up',

    color: '#00ff88'

});

 

// 向下流动(backward)

wall.draw({

    flowAxis: 'vertical',

    flowDirection: 'backward',

    arrowDirection: 'down',

    color: '#00aaff'

});

4.3 扫描效果(无箭头)

// 只显示扫描线,不显示箭头

wall.draw({

    arrowType: undefined, // 不显示箭头

    scanMode: 'vertical',

    scanColor: '#ff0000',

    scanDirection: 'up',

    scanSpeed: 0.8,

    scanWidth: 0.5,

    scanOpacity: 0.9,

    borderColor: '#ff0000'

});

4.4 图片纹理无缝流动

// 生成箭头图片 DataURL

const canvas = document.createElement('canvas');

canvas.width = 64; canvas.height = 64;

const ctx = canvas.getContext('2d');

ctx.strokeStyle = '#ffff00';

ctx.lineWidth = 8;

ctx.beginPath();

ctx.moveTo(10, 15);

ctx.lineTo(45, 32);

ctx.lineTo(10, 49);

ctx.stroke();

const imageUrl = canvas.toDataURL();

 

// 应用图片纹理

wall.draw({

    textureType: 'image',

    imageUrl: imageUrl,

    imageRepeat: { x: 20, y: 1 },

    flowSpeed: 4.0,

    repeatVertical: false, // 仅单行

    height: 290

});

4.5 脉冲动画

wall.draw({

    arrowType: 'arrow',

    arrowDirection: 'both',

    animationType: 'pulse',

    pulseSpeed: 1.5,

    color: '#00ffff'

});

4.6 自定义图案(闪电)

wall.draw({

    arrowType: 'custom',

    customDraw: function(ctx, x, y, size, config) {

        const half = size / 2;

        ctx.lineWidth = size * 0.5;

        ctx.strokeStyle = ctx.fillStyle;

        ctx.beginPath();

        ctx.moveTo(x - half*0.3, y - half*0.8);

        ctx.lineTo(x + half*0.2, y - half*0.1);

        ctx.lineTo(x - half*0.1, y - half*0.1);

        ctx.lineTo(x + half*0.3, y + half*0.8);

        ctx.stroke();

    },

    color: '#ffff00'

});

4.7 显示控制

// 显示并飞向墙体

wall.flyTo();

 

// 隐藏

wall.toggle(false);

 

// 切换

wall.toggle();

 

// 获取可见状态

const visible = wall.toggle(); // 返回当前状态

4.8 更新与清除

// 更新配置(保持位置不变)

wall.update({ color: '#ff6600', flowSpeed: 3.0 });

 

// 完全清除

wall.clear();

 

// 销毁实例

wall.destroy();

5. 完整代码实例

<!DOCTYPE html>

<html lang="zh-CN">

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>动态立体墙演示</title>

    <script src="https://mhc.ixiera.com/mhc/main.js"></script>

    <script src="https://mhc.ixiera.com/mhc/Cesium-1.120/Build/Cesium/Cesium.js"></script>

    <script src="https://mhc.ixiera.com/mhc/Cesium3DTile.js"></script>

    <script src="https://mhc.ixiera.com/mhc/mchmap/DynamicWall/js/DynamicWall.min.js"></script>

    <style>

        html,body,#cesiumContainer { width:100%; height:100%; margin:0; padding:0; overflow:hidden; }

        .btns { position:fixed; top:10px; left:10px; z-index:1000; display:flex; gap:8px; flex-wrap:wrap; }

        .btns button { background:#fff; border:1px solid #ccc; border-radius:4px; padding:5px 12px; cursor:pointer; font-size:12px; }

        .btns button.active { background:#ffaa00; color:#fff; border-color:#ffaa00; }

        .info { position:fixed; bottom:10px; left:10px; z-index:1000; background:rgba(0,0,0,0.8); color:#fff; padding:10px 15px; border-radius:6px; font-size:12px; max-width:400px; }

    </style>

</head>

<body>

    <div id="cesiumContainer"></div>

    <div class="btns">

        <button onclick="demoArrow()" class="active">箭头</button>

        <button onclick="demoScan()">扫描</button>

        <button onclick="demoImage()">图片纹理</button>

        <button onclick="demoPulse()">脉冲</button>

        <button onclick="toggleShow()">切换显示</button>

        <button onclick="clearWall()">清除</button>

    </div>

    <div class="info" id="info">点击按钮切换效果</div>

 

    <script>

        const view3D = MchCesium.init('cesiumContainer', true);

        const viewer = MchCesium.viewer;

        viewer.scene.globe.depthTestAgainstTerrain = true;

 

        let wall = null;

        const positions = [

            [116.3860, 39.9060],

            [116.3940, 39.9060],

            [116.3940, 39.9140],

            [116.3860, 39.9140]

        ];

 

        function demoArrow() {

            clearWall();

            wall = new DynamicWall(viewer, {

                positions: positions,

                height: 120,

                arrowType: 'arrow',

                arrowDirection: 'left',

                color: '#ffff00',

                flowSpeed: 2.0,

                borderColor: '#ffaa00',

                showBorder: true

            });

            wall.draw();

            wall.flyTo();

            setActive(0);

            document.getElementById('info').innerText = '水平流动箭头(←)';

        }

 

        function demoScan() {

            clearWall();

            wall = new DynamicWall(viewer, {

                positions: positions,

                height: 150,

                scanMode: 'vertical',

                scanColor: '#ff0000',

                scanDirection: 'up',

                scanSpeed: 0.8,

                scanWidth: 0.5,

                scanOpacity: 0.9,

                borderColor: '#ff0000',

                showBorder: true

            });

            wall.draw();

            wall.flyTo();

            setActive(1);

            document.getElementById('info').innerText = '红色扫描线(无箭头)';

        }

 

        function demoImage() {

            clearWall();

            const canvas = document.createElement('canvas');

            canvas.width = 64; canvas.height = 64;

            const ctx = canvas.getContext('2d');

            ctx.strokeStyle = '#ffff00';

            ctx.lineWidth = 8;

            ctx.beginPath();

            ctx.moveTo(10, 15);

            ctx.lineTo(45, 32);

            ctx.lineTo(10, 49);

            ctx.stroke();

            const imageUrl = canvas.toDataURL();

 

            wall = new DynamicWall(viewer, {

                positions: positions,

                height: 290,

                textureType: 'image',

                imageUrl: imageUrl,

                imageRepeat: { x: 20, y: 1 },

                flowSpeed: 4.0,

                borderColor: '#ffaa00',

                showBorder: false

            });

            wall.draw();

            wall.flyTo();

            setActive(2);

            document.getElementById('info').innerText = '图片纹理无缝流动';

        }

 

        function demoPulse() {

            clearWall();

            wall = new DynamicWall(viewer, {

                positions: positions,

                height: 120,

                arrowType: 'arrow',

                arrowDirection: 'both',

                animationType: 'pulse',

                pulseSpeed: 1.5,

                color: '#00ffff',

                borderColor: '#00cccc',

                showBorder: true

            });

            wall.draw();

            wall.flyTo();

            setActive(3);

            document.getElementById('info').innerText = '脉冲闪烁箭头(双向)';

        }

 

        function toggleShow() {

            if (wall) {

                const visible = wall.toggle();

                document.getElementById('info').innerText = visible ? '墙体已显示' : '墙体已隐藏';

            }

        }

 

        function clearWall() {

            if (wall) {

                wall.clear();

                wall = null;

            }

        }

 

        function setActive(index) {

            document.querySelectorAll('.btns button').forEach((btn, i) => {

                btn.classList.toggle('active', i === index);

            });

        }

 

        // 默认加载箭头演示

        setTimeout(demoArrow, 500);

    </script>

</body>

</html>

6. 效果展示

Demo地址:https://mhc.ixiera.com/mhc/mchmap/DynamicWall/index.html

 

本文档来自—MCHMAP 丨 地图引擎平台