html5自动切换城市功能,基于 HTML5 WebGL 构建智能城市 3D 场景

本文介绍了如何利用HT for Web产品轻量化HTML5/WebGL技术创建3D城市模型,实现动态交互的可视化效果。通过加载场景、设置动画,展示了波纹、旋转、流动和浮动等特效的实现方法,强调了这种技术在城市管理和监控中的应用,以及在移动端的良好体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

随着城市规模的扩大,传统的方式很难彻底地展示城市的全貌,但随着 3D 技术的应用,出现了 3D 城市群的方式以动态,交互式地把城市全貌呈现出来。配合智能城市系统,通过 Web 可视化的方式,使得城市管理者可以更及时地了解交通情况,城市消防,电力管理等方面的运行情况,做出处理。

本 demo 使用 产品轻量化 HTML5/WebGL 建模的方案,传统的 智慧楼宇/楼宇自动化/楼宇安防/智慧园区 常会采用 BIM(建筑信息模型 Building information modeling)软件,如 Autodesk 的 Revit 或 Bentley 这类建筑和工程软件,但这些 BIM 建模模型的数据往往过于庞大臃肿,绝大部分细节信息对楼宇自控意义不大,反而影响拖累了行业 Web SCADA 或 Web 组态监控的趋势,所以我们采用以 Hightopo 的 HT for Web 产品轻量化 HTML5/WebGL 建模的方案,实现快速建模、运行时轻量化到甚至手机终端浏览器即可 3D 可视化运维的良好效果。

demo 地址:

预览图:

07e5b42b6162f3f0d396465c8078d78e.gif

代码实现

加载 3d 场景

新建一个 3d 场景,并加入到页面中。

const g3d = new ht.graph3d.Graph3dView();

const dm3d = g3d.dm();

g3d.addToDOM();

addToDOM 函数默认将场景加载到 body 中并填充窗口。

接下来反序列化城市场景 json,并在反序列化函数的回调中设置了场景的视角,中心位置,天空盒,并获得各图元信息,调用 startAnim 函数:

g3d.deserialize('scenes/ny.json', () => {

g3d.setEye([1132.8386351821287, 1916.836416970022, 1479.5345608290288]);

g3d.setCenter([519.9741236104874, 273.4741921410557, -319.58669041297884]);

g3d.setSkyBox(dm3d.getDataByTag('skyBox'));

// 获取扩散效果的图元

scaleList.push(

dm3d.getDataByTag('scaleBlue'),

dm3d.getDataByTag('scaleRed')

);

···

// 开始动画

startAnim();

});

动画实现

加载后的城市场景如下图所示:

format,png

我们可以看到场景中有蓝黄水波纹效果,道路,消防通道的流动效果,上下浮动的效果和旋转的 logo 和卫星。

动画的实现均通过 ht.Default.startAnim 实现的,先来了解一下:

ht.Default.startAnim({

// 动画帧数

frames: 12,

// 动画帧间隔毫秒数

interval: 10,

// 动画缓动函数,默认采用 ht.Default.animEasing

easing: function(t){ return t * t; },

// 动画结束后调用的函数

finishFunc: function(){ console.log('Done!') },

// action 函数必须提供,实现动画过程中的属性变化

action: function(v, t){

// 此例子展示将节点 node 从位置 p1 动画到位置 p2

node.setPosition(

p1.x + (p2.x - p1.x) * v,

p1.y + (p2.y - p1.y) * v

);

}

});

以上为 Frame-Based 方式动画, 这种方式用户通过指定 frames 动画帧数,以及 interval 动画帧间隔参数控制动画效果。

ht的动画手册可以参照:

下面依次介绍各个效果的实现。

1. 波纹效果

预览图:

e6dea17147f3ea629abd5d5efb3b4ccc.gif

代码:

function waveScale(obj, dlt, max, min) {

obj.forEach(node => {

// 扩散半径增加 let s = node.getScaleX() + dlt;

// 扩散半径大于最大值的时候, 重置为最小值 if (s >= max) s = min;

// 设置 x,y,z 方向的缩放值

node.setScale3d(s, s, s);

});

} function startAnim() {

ht.Default.startAnim({

frames: Infinity,

interval: 20,

action: () => {

// 扩散蓝和扩散红

waveScale(scaleList, dltScale, maxScale, minScale);

}

});

}

2. 旋转效果

预览图:

656fb08b920e9c46f221b0d74006bbe9.gif

代码:

function rotateAction(obj, dlt) {

// 获取图元旋转弧度值,没有就置零 let rotation = obj.getRotation() || 0;

// 每帧弧度增加

obj.setRotation(rotation + dlt);

} function startAnim() {

ht.Default.startAnim({

frames: Infinity,

interval: 20,

action: () => {

// 卫星转动

rotateAction(star, dltRoattion);

}

});

}

3. 流动效果

预览图:

afc056db9842519e55047a615db6b616.gif

流动效果是非常常见的效果,实现的过程也较为简单,只需要动态地去改变 uv 贴图的偏移值即可。在本例中,通过对模型六面的贴图的 U 方向实施动态增减实现了多个流动效果:

function uvFlow(obj, dlt) {

// 改变贴图 uv 坐标实现流动效果 let offset = obj.s('all.uv.offset') || [0, 0];

obj.s('all.uv.offset', [offset[0] + dlt, offset[1]]);

} function startAnim() {

ht.Default.startAnim({

frames: Infinity,

interval: 20,

action: () => {

// 小路流动效果

uvFlow(roadSmall, dltRoadSmall);

}

});

}

4. 浮动效果

预览图:

d26a699a2d40653969e05063d3918ed4.gif

代码:

function blockFloat(obj, dis, dlt) {

obj.forEach(node => { let startE = node.a('startE'); if (startE == null)

// 获得图元在 y(高度)方向上的值

node.a('startE', startE = node.getElevation()); let float = node.a('float') || 0;

// 设置 status 为方向 let status = node.a('status') || 1;

node.setElevation(startE + dis * float); if (float > 1 || float < 0)

// 超出阀值则改变方向

node.a('status', status = -status); float += dlt * status;

// 重新设置图元高度

node.a('float', float);

});

} function startAnim() {

ht.Default.startAnim({

frames: Infinity,

interval: 20,

action: () => {

// 消防标志浮动效果

blockFloat(fireFloatList, fireFloadDis, fireFloatDlt)

}

});

}复制代码

这样,一个基本的效果就实现了。

HT 的 3D 城市群方案不仅可以在大屏上有良好的效果,在移动端也有着不错的体验,这使得城市管理者不管何时何地都能获取到实时的监控信息,这里放两张在移动端浏览器上的预览图给大家体验一下:

format,png

format,png

HT包含了数百个工业互联网 2D 3D 可视化应用案例,点击这里体验把玩:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值