You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Autodesk Viewer中添加随场景缩放移动的HTML元素?

在Autodesk Viewer中添加与场景联动的文本元素

我完全懂你的困扰——直接往Viewer的DOM容器里塞元素,肯定只会钉在屏幕上,没法跟着3D场景一起漫游。要实现文本和场景同步缩放、随相机移动的效果,得用Viewer专门为3D场景设计的API,而不是普通的DOM元素。下面给你两种靠谱的解决方案:

方法一:使用官方Markup API(推荐)

Viewer自带的Markup扩展是最省心的选择,它专门用来创建和3D场景绑定的标注(文本、箭头、高亮框都支持),自动适配相机视角和缩放,不用自己处理复杂的坐标转换。

示例代码:

this.viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, async (event) => {
  // 等待模型加载完成后,加载Markup扩展
  const markupExt = await this.viewer.loadExtension('Autodesk.Viewing.MarkupsCore');
  
  // 进入编辑模式(也可以保持编辑模式手动调整文本位置)
  markupExt.enterEditMode();
  
  // 创建文本标记:传入3D场景坐标、文本内容、字体大小和颜色
  const textMarkup = new Autodesk.Viewing.Extensions.Markups.Core.Markups.Text(
    markupExt,
    new THREE.Vector3(10, 20, 30), // 文本在3D空间中的位置
    "Water",
    16,
    new THREE.Color(0xff0000)
  );
  
  // 将文本添加到Markup场景中
  markupExt.addMarkup(textMarkup);
  
  // 退出编辑模式(可选,如果你不需要手动编辑的话)
  markupExt.leaveEditMode();
});

这种方式的好处是:官方维护兼容性强,文本会自动跟随场景缩放、旋转,完全贴合你的需求。

方法二:自定义WebGL Overlay(适合复杂定制需求)

如果你需要更个性化的文本效果(比如特殊字体、动画、自定义样式),可以用Viewer的impl.createOverlayScene创建自定义WebGL层,结合Three.js的文本渲染能力实现。

示例代码:

this.viewer.addEventListener(Autodesk.Viewing.GEOMETRY_LOADED_EVENT, (event) => {
  const viewer = event.target;
  // 创建自定义Overlay场景
  const overlayScene = viewer.impl.createOverlayScene('custom-text-overlay');
  
  // 加载Three.js字体文件(需要提前准备字体的JSON文件,比如从typeface.js生成)
  const fontLoader = new THREE.FontLoader();
  fontLoader.load('your-font-file.json', (font) => {
    // 创建文本几何体
    const textGeometry = new THREE.TextGeometry('Water', {
      font: font,
      size: 5,
      height: 0.5,
      curveSegments: 12,
    });
    
    // 设置文本材质
    const textMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
    const textMesh = new THREE.Mesh(textGeometry, textMaterial);
    
    // 定位文本到3D场景中的目标位置
    textMesh.position.set(10, 20, 30);
    // 让文本始终面向相机
    textMesh.lookAt(viewer.impl.camera.position);
    
    // 将文本添加到Overlay场景
    overlayScene.add(textMesh);
    
    // 监听相机变化,实时更新文本朝向
    viewer.addEventListener(Autodesk.Viewing.CAMERA_CHANGE_EVENT, () => {
      textMesh.lookAt(viewer.impl.camera.position);
      viewer.impl.invalidate(true); // 强制刷新Viewer
    });
  });
});

这种方式需要你自己处理文本的朝向、缩放逻辑,还要准备Three.js兼容的字体文件,但灵活性极高,能实现各种定制化效果。

为什么你之前的方法不行?

你之前把DOM元素添加到clientContainer里,这个容器是Viewer的外层DOM节点,里面的元素都是屏幕空间定位的,和3D场景的相机、坐标系完全无关,自然没法跟着场景移动。而上面两种方法都是在WebGL的3D场景空间里渲染文本,所以能和场景联动。

内容的提问来源于stack exchange,提问作者Sam Curry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:16:04