在图扑 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 可视化项目中的重要实践。
您可以至图扑软件官网查看更多案例及效果: