在图扑 HT 项目中,尤其是复杂应用里,单一场景或图纸通常难以承载所有需求,因此在多个图纸或场景之间进行切换是一种常见的实现方式。本文将深入解析图扑 HT 项目中场景/图纸切换的核心实现方法,并详细介绍如何为切换过程添加流畅自然的过渡效果,以提升用户体验。

场景 / 图纸核心切换步骤
图扑 HT 项目中,实现图纸或场景的无缝切换需严格遵循以下关键步骤,以避免潜在问题并确保切换过程稳定可靠:
清除当前的数据模型
使用 dataModel.clear() 清除当前场景关联的所有数据模型。反序列化新场景/图纸
通过 view.deserialize(url) 方法加载并反序列化新的场景或图纸资源文件,完成新场景的载入。
注意
:不建议通过创建多个 ht.graph3d.GraphView 进行切换。
原因在于 ht.graph3d.GraphView 是基于 WebGL 的 3D 渲染组件。而多数浏览器对单个页面可运行的 WebGL 上下文数量有严格限制。频繁创建新实例会导致内存泄漏或资源耗尽,引发场景显示异常甚至浏览器崩溃。
场景切换过渡效果
为了在场景切换时获得更流畅、更具视觉吸引力的体验,可以添加过渡动画。常见的实现思路有两种:
利用场景属性实现过渡
通过控制场景的特定属性,在切换过程中产生动态过渡效果,常见的有
景深动画和亮度调节
等。景深动画过渡
景深效果主要通过以下两个属性控制:
- image 属性:模拟景深的贴图(通常为四周黑色、中间透明的 PNG 图片,黑色区域应用景深模糊,透明区域保持清晰)。
- aperture(孔径)属性:代表中间空白区域的大小,取值范围 0~1,0 表示无景深效果,1 表示景深效果最明显。

实现步骤
使用一张全黑景深贴图(确保整个场景受景深影响),在旧场景切换前开启景深并执行递增孔径值的动画,新场景加载后执行递减孔径值的动画,形成“渐隐渐显”的过渡效果。
let dof = g3d.getPostProcessingModule('Dof'); dof.image = 'assets/景深.png' dof.aperture = 0 // 景深开启 g3d.enablePostProcessing('Dof', true); let anim = { duration: 800, easing: (t: number) => { return t * t; }, action: (v: number, t: number) => { // 动态设置景深阈值 dof.aperture = v * 0.2 } } ht.Default.startAnim(anim);
新场景反序列化后,新场景也需要执行景深动画。
这时执行的景深动画跟旧场景的景深动画区别在于 action 中的逻辑是递减的过程:dof.aperture =0.2-v*0.2。

其他属性过渡效果
除景深外,还可通过调节亮度等场景属性实现过渡,原理与景深动画一致:
- 旧场景切换前,执行属性动画(如亮度逐渐降低至 0,场景变暗);
- 新场景加载后,执行反向动画(如亮度从 0 逐渐恢复至正常值,场景变亮)。
利用 2D 图纸动画实现过渡
通过在 3D 场景上层叠加 2D 图纸,利用 2D 元素的动画效果遮蔽切换过程,创意自由度更高,为整体呈现带来了更多的艺术动感和技术深度。
帧动画过渡(云朵过渡)
旧场景被“云朵”图片序列逐渐覆盖(遮蔽),切换新场景后,“云朵”再逐渐消散以展现新场景。

实现步骤
- 准备一组连续的过渡图片(如从透明到完全遮蔽再到透明的云朵图片序列);
- 旧场景切换前,执行动画使图片从初始状态过渡到完全遮蔽场景;
- 新场景加载后,执行反向动画使图片从完全遮蔽过渡到消失。
代码示例
const cloudList = [ "assets/cloud1.png", "assets/cloud2.png", ... "assets/cloud20.png", ]; const image = this.getDataByTag('cloud'); let i = 0; ht.Default.startAnim({ frames: 20, interval:50, action: (t) => { cloudList[i] && image.setImage(cloudList[i]); } })
在新旧场景内执行的动画代码基本一样,区别在于切换前 action 中是从第一张图片切换到最后一张,在新场景反序列化后是从最后一张切换回第一张。
其他创意效果
利用 2D 覆盖层进行过渡的核心优势在于创意自由度极高。开发者可以结合 HT 强大的 2D 动画能力,对覆盖元素应用多种属性动画组合:
- 渐入渐出的遮罩层动画;
- 模拟镜头推拉的缩放动画;
- 基于路径的元素移动动画;
- ……

2D 图纸间切换过渡
前文主要探讨了 3D 场景的切换过渡。同样地,在纯 2D 图纸 (ht.graph.GraphView) 之间进行切换时,也可以利用 HT 的 2D 特性实现平滑的过渡效果。一种实用的方法是
动态生成并动画化当前视图的缩略图。
利用缩略图过渡
在图纸切换前动态生成缩略图并施加动画,实现平滑过渡的效果,具体的实现步骤:
生成当前视图缩略图:
在触发图纸切换前,使用 gv.toDataURL() 生成当前视图的缩略图。
创建过渡节点:
生成与图纸视图窗口尺寸相同的节点。
将缩略图设置为该节点的内容。
应用动画效果:
在动画中调整缩略图节点的裁切、透明等属性,以达到过渡效果。

代码示例
functiongenerateThumbnail() { var jsonSerializer = new ht.JSONSerializer(dm); // 创建序列化器,并传入旧图纸的 dm jsonSerializer.isSerializable = function (data) { // 过滤节点 return data.getTag() != 'mask'; } var json = ht.Default.parse(jsonSerializer.serialize()); json.a = {}; const gv = new ht.graph.GraphView(); // 创建一个新的2D 视图 gv.dm().deserialize(json); // 反序列化 const thumbnail = gv.toDataURL(null, null, 1, 0); // 生成缩略图 } functioncreateThumbnailData(thumbnail){ const thumbnail_data = new ht.Node(); // 生成缩略图节点 thumbnail_data.setImage(thumbnail); const contentRect = gv.getContentRect(); // 获取所有图元占用的矩形区域 const rect = div.getBoundingClientRect();// 获取2D视图尺寸 const width = rect.width; const height = rect.height; thumbnail_data.p({ x: contentRect.x + contentRect.width / 2, y: contentRect.y + contentRect.height / 2 }) // 为缩略图节点设置位置 thumbnail_data.setSize({ width, height });// 为缩略图节点设置尺寸 thumbnail_data.setScale(contentRect.width / width, contentRect.height / height);// 为缩略图节点设置缩放 thumbnail_data.setAnchor({ x: 0.5, y: 0.5 }); dm.add(thumbnail_data); const mask = dm.getDataByTag('mask'); thumbnail_data.setHost(mask); thumbnail_data.s('clip.host', true); // 开启吸附裁切后,缩略图节点会根据吸附的节点进行裁切 ht.Default.startAnim({ duration: 2000, easing: function (t) { return t; }, finishFunc: function () { dm.remove(thumbnail_data); // 动画结束后移除缩略图节点 }, action: function (v, t) { thumbnail_data.s('opacity', 1 - v + 0.1); mask.setScaleX(1 - v); thumbnail_data.iv(); } }); } view.mi((e) =>{ if(e.kind === 'onClick' && e.type === 'data'){ if(e.data.getTag() === 'switchBtn'){ // 点击按钮切换图纸 const thumbnail = generateThumbnail(); // 生成缩略图 .... createThumbnailData(thumbnail); // 生成缩略图节点 ... } } })
总结
在图扑软件 HT 项目中实现场景/图纸切换,关键在于遵循 dataModel.clear() + view.deserialize() 的核心步骤,并避免重复创建 ht.graph3d.GraphView 实例。
为了提升用户体验,添加过渡效果是重要环节。无论是通过动态调整场景后处理属性(如景深、亮度)还是利用精心设计的 2D 图纸动画(如帧序列),本质上都是对 HT 引擎灵活性和设计者创意的结合应用。不仅优化了技术流程,更能创造出引人入胜的视觉表现,是当前 Web 可视化项目中的重要实践。
您可以至图扑软件官网查看更多案例及效果:
https://www.hightopo.com/demos/index.html
这一切,似未曾拥有