npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

easy-threesdk

v1.0.10

Published

����Threejs��װ�ij��ù��ܵ�sdk

Readme

ThreeSDK 使用文档

1. 简介

ThreeSDK 是一个基于 Three.js 的封装库,旨在简化 3D 场景的搭建、模型加载、交互控制以及标签系统的开发。通过封装常用的 Three.js 功能,开发者可以更快速地构建具有漫游、交互和标注功能的 3D 应用。

当前版本: 1.0.9

2. 安装

npm install easy-threesdk

或直接通过 Gitee 仓库使用:

git clone https://gitee.com/xieqianstudent/visual-learning.git

3. 核心功能

ThreeSDK 封装了以下核心能力:

3.1 场景基础建设

  • 自动化初始化:一键初始化 Scene、Camera、Renderer、OrbitControls 和 Lights
  • 响应式适配:自动处理窗口大小调整 (Resize)
  • 光照系统:内置环境光、方向光和边缘光 (Rim Light) 配置
  • 背景系统:支持全景球体背景和立方体贴图背景

3.2 摄像机与视角控制

  • 轨道控制器 (OrbitControls):默认支持旋转、缩放、平移
  • 第一人称模式 (First Person Mode)
    • 固定相机位置,仅允许围绕自身旋转查看
    • 适用于全景查看
  • 漫游模式 (Roam Mode)
    • 类似游戏的操作方式 (WASD / 方向键移动)
    • 鼠标拖拽改变视角朝向
    • 地面点击跳转 (Teleport)
    • 实时显示地面指示圆圈
  • 视角动画 (flyTo):平滑过渡到指定位置和视角的动画功能,支持 Promise

3.3 插件系统

采用插件化架构,通过 plugins() 方法注册功能模块。目前内置插件包括:

  • LabelControl:基于 CSS3DRenderer 和 CSS2DRenderer 的 HTML 标签系统,支持 2D/3D 标签、多种标签样式,支持标签绑定到模型对象
  • ModelControl:GLTF 模型加载(支持 Draco 压缩)、模型点击/悬停交互管理、网格变换控制器、模型轮廓辉光效果

3.4 其他工具

  • 全景球体 (Panorama Sphere):快速创建全景背景
  • 立方体贴图背景:支持六面体背景纹理
  • 场景组管理 (ThreeGroup):方便管理场景中的对象分组
  • 地面平面管理:支持设置地面平面用于漫游模式检测
  • Mesh 信息管理:支持获取和应用 mesh 的位置、旋转、缩放信息

4. 快速上手

4.1 基础示例

以下代码展示了如何使用 ThreeSDK 初始化场景、加载模型、添加标签以及启用交互。

import * as THREE from "three";
import ThreeSdk from "./index.js";
import LabelControl from "./plugins/LabelControl.js";
import ModelControl from "./plugins/ModelControl.js";

// 1. 初始化 SDK
const container = document.getElementById("canvas-container");
const threeSdk = new ThreeSdk(container);

// 2. 配置并启动场景
threeSdk.init(
  {
    // 相机初始位置
    position: new THREE.Vector3(0, 15, 20),
    lookAt: new THREE.Vector3(0, 0, 0),
  },
  {
    // 控制器配置
    enableDamping: true,
    dampingFactor: 0.05,
    minDistance: 10,
    maxDistance: 500,
    maxPolarAngle: Math.PI / 2,
    target: new THREE.Vector3(0, 0, 0),
  },
  {
    // 灯光配置 (可选)
    ambientLight: 0xffffff,
    ambientLightIntensity: 0.8,
    directionalLightColor: 0xa5f3fc,
    directionalLightIntensity: 1.5,
    rimLightColor: 0x0ea5e9,
    rimLightIntensity: 3,
  }
);

// 3. 注册插件
threeSdk.plugins([LabelControl, ModelControl]);

// 4. 创建全景背景 (可选)
threeSdk.createPanoramaSphere("/path/to/panorama.jpg");

// 或创建立方体贴图背景
threeSdk.createBackground([
  "/path/to/xpos.jpg", // 右
  "/path/to/xneg.jpg", // 左
  "/path/to/ypos.jpg", // 上
  "/path/to/yneg.jpg", // 下
  "/path/to/zpos.jpg", // 前
  "/path/to/zneg.jpg", // 后
]);

// 5. 使用 ModelControl 插件加载 GLTF 模型
const modelControl = threeSdk._PluginsManager.get("ModelControl");

modelControl.loadGLTFBuilding(
  {
    ModelID: "MyCar",
    modelPath: "./resource/car/scene.gltf",
    position: [0, 0], // [x, z] 坐标
    scale: 0.1,
    clickable: true,
  },
  (percent) => {
    console.log(`模型加载进度: ${Math.round(percent)}%`);
  }
);

// 监听模型点击事件
modelControl.onModelClickListener((object) => {
  if (object) {
    console.log("点击了模型:", object);
  }
});

// 监听模型悬停事件
modelControl.onModelMouseMoveListener((object) => {
  if (object) {
    console.log("悬停在模型上:", object);
  }
});

// 6. 使用 LabelControl 插件添加 3D 标签
const labelControl = threeSdk._PluginsManager.get("LabelControl");

// 创建箭头标签
labelControl.createArrow3DLabel(
  "CarLabel",
  {
    template: "<div>My Car</div>",
    data: {},
  },
  new THREE.Vector3(0, 10, 0), // 标签位置
  {
    size: 0.02,
    backgroundColor: "rgba(20, 30, 50, 0.9)",
    textColor: "#ffffff",
    borderColor: "#22d3ee",
    fontSize: 16,
    className: "my-label-class",
  },
  {
    click: (e) => {
      console.log("点击了标签", e);
      // 视角飞向标签位置
      threeSdk.flyTo({
        position: new THREE.Vector3(10, 10, 10),
        target: new THREE.Vector3(0, 0, 0),
      });
    },
    mouseenter: (e) => {
      console.log("鼠标进入标签", e);
    },
    mouseleave: (e) => {
      console.log("鼠标离开标签", e);
    },
  }
);

// 7. 切换视角模式示例
// 开启漫游模式
threeSdk.enterRoamMode();

// 开启第一人称模式
threeSdk.enterFirstPersonMode();

// 退出模式
threeSdk.exitRoamMode();
threeSdk.exitFirstPersonMode();

4.2 标签类型示例

LabelControl 插件支持三种标签类型,每种类型都有 2D 和 3D 两种版本:

3D 标签(CSS3DRenderer)

const labelControl = threeSdk._PluginsManager.get("LabelControl");

// 1. 箭头标签 - 带向下箭头指示器
labelControl.createArrow3DLabel(
  "ArrowLabel",
  { template: "<div>箭头标签</div>", data: {} },
  new THREE.Vector3(0, 5, 0),
  { size: 0.02 }
);

// 2. 指示器标签 - 带折线指示器和背景图
labelControl.createIndicator3DLabel(
  "IndicatorLabel",
  { template: "<div>指示器标签</div>", data: {} },
  new THREE.Vector3(5, 5, 0),
  { size: 0.02 }
);

// 3. 可展开标签 - 点击可展开显示更多内容
labelControl.createExpand3DLabel(
  "ExpandLabel",
  {
    template: "<div>点击展开</div>",
    expandContentHtml: "<div>展开的内容</div>",
    data: {},
  },
  new THREE.Vector3(-5, 5, 0),
  { size: 0.02 }
);

2D 标签(CSS2DRenderer,支持绑定到模型)

// 加载模型
const model = await modelControl.loadGLTFBuilding({
  ModelID: "myModel",
  modelPath: "./models/model.gltf",
  position: [0, 0],
  scale: 1,
  clickable: true,
});

// 1. 2D 箭头标签 - 可以绑定到模型,标签会跟随模型移动和旋转
labelControl.createArrow2DLabel(
  "Arrow2DLabel",
  { template: "<div>模型标签</div>", data: {} },
  new THREE.Vector3(0, 5, 0), // 相对于模型中心的偏移
  {
    size: 0.02,
    model: model, // 绑定到模型
  }
);

// 2. 2D 指示器标签
labelControl.createIndicator2DLabel(
  "Indicator2DLabel",
  { template: "<div>指示器</div>", data: {} },
  new THREE.Vector3(0, 3, 0),
  {
    size: 0.02,
    model: model,
  }
);

// 3. 2D 可展开标签
labelControl.createExpand2DLabel(
  "Expand2DLabel",
  {
    template: "<div>点击展开</div>",
    expandContentHtml: "<div>展开内容</div>",
    data: {},
  },
  new THREE.Vector3(0, 7, 0),
  {
    size: 0.02,
    model: model,
  }
);

2D 与 3D 标签的区别:

  • 3D 标签:使用 CSS3DRenderer,标签会随相机视角变化产生 3D 透视效果,适合固定在场景中的标签
  • 2D 标签:使用 CSS2DRenderer,标签始终面向相机,不会产生透视变形,适合绑定到模型上跟随模型移动的标签

5. API 详细文档

5.1 ThreeSdk 类

构造函数

new ThreeSdk(container);
  • container (HTMLElement): 用于渲染 3D 场景的 DOM 容器

主要方法

init(cameraConfig, controlConfig, lightConfig)

初始化场景、相机、灯光和控制器。

参数:

  • cameraConfig (Object, 可选):

    • position (THREE.Vector3, 默认: new THREE.Vector3(0, 280, 320)): 相机初始位置
    • lookAt (THREE.Vector3, 默认: new THREE.Vector3(0, 0, 0)): 相机初始朝向
  • controlConfig (Object, 可选):

    • enableDamping (boolean, 默认: true): 是否启用阻尼
    • dampingFactor (number, 默认: 0.05): 阻尼因子
    • minDistance (number, 默认: 50): 最小缩放距离
    • maxDistance (number, 默认: 800): 最大缩放距离
    • maxPolarAngle (number, 默认: Math.PI / 2): 最大极角
    • target (THREE.Vector3, 默认: new THREE.Vector3(0, 0, 0)): 控制器目标位置
  • lightConfig (Object, 可选):

    • ambientLight (THREE.Color, 默认: 0xffffff): 环境光颜色
    • ambientLightIntensity (number, 默认: 0.5): 环境光强度
    • directionalLightColor (THREE.Color, 默认: 0xa5f3fc): 方向光颜色
    • directionalLightIntensity (number, 默认: 1.5): 方向光强度
    • rimLightColor (THREE.Color, 默认: 0x0ea5e9): 边缘光颜色
    • rimLightIntensity (number, 默认: 3): 边缘光强度
    • rimLightPosition (THREE.Vector3, 默认: new THREE.Vector3(0, 100, -100)): 边缘光位置
    • mainLightPosition (THREE.Vector3, 默认: new THREE.Vector3(50, 100, 50)): 主光位置
plugins(plugins)

注册插件。

参数:

  • plugins (Array | Object): 插件类或插件类数组

示例:

threeSdk.plugins([LabelControl, ModelControl]);
// 或
threeSdk.plugins(LabelControl);
createPanoramaSphere(textureImage)

创建全景球体背景。

参数:

  • textureImage (string): 全景图片路径(单张等距柱状投影图片)

示例:

threeSdk.createPanoramaSphere("/path/to/panorama.jpg");
createBackground(textureImages)

创建立方体贴图背景。

参数:

  • textureImages (string[]): 六面体图片路径数组,顺序为 [右, 左, 上, 下, 前, 后]

示例:

threeSdk.createBackground([
  "/path/to/xpos.jpg",
  "/path/to/xneg.jpg",
  "/path/to/ypos.jpg",
  "/path/to/yneg.jpg",
  "/path/to/zpos.jpg",
  "/path/to/zneg.jpg",
]);
enterRoamMode()

进入漫游模式。支持 WASD/方向键移动,鼠标拖拽旋转视角,双击地面跳转。

操作说明:

  • WASD 或方向键:前后左右移动
  • 鼠标拖拽:旋转视角
  • 双击地面:跳转到点击位置
  • 鼠标悬停地面:显示指示圆圈
exitRoamMode()

退出漫游模式,恢复轨道控制器。

enterFirstPersonMode()

进入第一人称模式。相机位置固定,仅允许围绕自身旋转查看。

使用场景: 全景查看、固定视角观察

exitFirstPersonMode()

退出第一人称模式,恢复原始控制状态。

flyTo(viewInfo, options)

相机平滑飞行到指定视角。返回 Promise。

参数:

  • viewInfo (Object):
    • position (THREE.Vector3): 目标相机位置
    • target (THREE.Vector3): 目标朝向位置
  • options (Object, 可选):
    • duration (number, 默认: 1500): 动画时长(毫秒)

返回: Promise

示例:

threeSdk
  .flyTo(
    {
      position: new THREE.Vector3(10, 20, 30),
      target: new THREE.Vector3(0, 0, 0),
    },
    {
      duration: 2000,
    }
  )
  .then(() => {
    console.log("相机移动完成");
  });
createThreeGroup(name)

创建并获取一个 THREE.Group,用于管理场景中的对象分组。

参数:

  • name (string): 组名称

返回: THREE.Group

示例:

const buildingGroup = threeSdk.createThreeGroup("buildings");
buildingGroup.add(someMesh);
getMeshInfo(mesh)

获取 mesh 的位置、旋转、缩放信息,返回 JSON 对象。

参数:

  • mesh (THREE.Mesh): 要获取信息的 mesh 对象

返回: Object | null

返回对象包含:

  • position: { x, y, z } - 位置信息
  • rotation: { x, y, z } - 旋转信息(弧度制)
  • scale: { x, y, z } - 缩放信息

示例:

const meshInfo = threeSdk.getMeshInfo(someMesh);
console.log(meshInfo);
// {
//   position: { x: 0, y: 10, z: 0 },
//   rotation: { x: 0, y: 0, z: 0 },
//   scale: { x: 1, y: 1, z: 1 }
// }
applyMeshInfo(mesh, infoJson)

将 JSON 信息应用到 mesh,用于恢复或设置 mesh 的位置、旋转、缩放。

参数:

  • mesh (THREE.Mesh): 要应用信息的 mesh 对象
  • infoJson (Object): 包含位置、旋转、缩放信息的 JSON 对象

示例:

// 保存当前状态
const savedInfo = threeSdk.getMeshInfo(someMesh);

// 修改 mesh...

// 恢复之前的状态
threeSdk.applyMeshInfo(someMesh, savedInfo);

属性

  • scene (THREE.Scene): Three.js 场景对象
  • camera (THREE.PerspectiveCamera): 相机对象
  • renderer (THREE.WebGLRenderer): 渲染器对象
  • controls (OrbitControls): 轨道控制器对象
  • raycaster (THREE.Raycaster): 射线检测器
  • _PluginsManager (Map): 插件管理器,可通过此属性获取已注册的插件

5.2 Plugin: ModelControl

主要方法

loadGLTFBuilding(options, onLoadProcess)

加载 GLTF 格式的建筑物模型,支持 Draco 压缩格式。

参数:

  • options (Object):
    • ModelID (string): 模型唯一标识符
    • modelPath (string): GLTF 模型文件路径
    • position (Array, 默认: [0, 0]): 模型位置 [x, z] 坐标
    • scale (number, 默认: 30): 模型缩放比例
    • clickable (boolean, 默认: true): 模型是否可点击
    • openDraco (boolean, 默认: false): 是否启用 Draco 压缩支持(需要配置 Draco 解码器路径)
  • onLoadProcess (Function, 可选): 加载进度回调函数 (percent) => {}

返回: Promise<THREE.Object3D>

注意: 使用 Draco 压缩时,需要确保 Draco 解码器路径正确配置。

示例:

const model = await modelControl.loadGLTFBuilding(
  {
    ModelID: "building1",
    modelPath: "./models/building.gltf",
    position: [10, 20],
    scale: 1.0,
    clickable: true,
  },
  (percent) => {
    console.log(`加载进度: ${percent}%`);
  }
);
onModelClickListener(callback)

监听模型点击事件。

参数:

  • callback (Function): 回调函数 (object) => {},点击模型时触发,object 为被点击的网格对象,未点击模型时为 null

示例:

modelControl.onModelClickListener((object) => {
  if (object) {
    console.log("点击了模型:", object);
    console.log("模型名称:", object.userData.name);
  }
});
onModelMouseMoveListener(callback)

监听模型悬停事件。

参数:

  • callback (Function): 回调函数 (object) => {},悬停在模型上时触发,object 为被悬停的网格对象,未悬停时为 null

注意: 此方法会为可点击的模型添加悬停高亮效果(青色发光)。

示例:

modelControl.onModelMouseMoveListener((object) => {
  if (object) {
    console.log("悬停在模型上:", object);
  }
});
installMeshControls(mesh)

为指定网格安装变换控制器(TransformControls),支持平移、旋转、缩放。

参数:

  • mesh (THREE.Mesh): 需要控制的网格对象

操作说明:

  • G 键:切换到平移模式
  • R 键:切换到旋转模式
  • S 键:切换到缩放模式

示例:

modelControl.installMeshControls(someMesh);
enableModelOutlinePass(color)

启用模型轮廓辉光效果(OutlinePass)。此方法会创建后处理通道,为选中的模型添加轮廓辉光。

参数:

  • color (number, 可选): 辉光颜色,默认 0x00ffff(青色)

注意: 此方法只需要调用一次,后续使用 switchModelOutlinePass 来切换模型的辉光效果。

示例:

// 启用模型辉光效果(默认青色)
modelControl.enableModelOutlinePass();

// 或使用自定义颜色
modelControl.enableModelOutlinePass(0xff0000); // 红色辉光
switchModelOutlinePass(MeshObject)

切换指定模型的轮廓辉光效果。如果模型已有辉光效果则移除,否则添加。

参数:

  • MeshObject (THREE.Mesh): 要切换辉光效果的网格对象

返回: void

示例:

// 加载模型
const model = await modelControl.loadGLTFBuilding({
  ModelID: "building",
  modelPath: "./models/building.gltf",
  position: [0, 0],
  scale: 1,
  clickable: true,
});

// 启用辉光系统(只需调用一次)
modelControl.enableModelOutlinePass();

// 点击模型时切换辉光效果
modelControl.onModelClickListener((object) => {
  if (object) {
    // 切换该模型的辉光效果
    modelControl.switchModelOutlinePass(object);
  }
});

5.3 Plugin: LabelControl

LabelControl 插件支持创建 2D 和 3D 两种类型的标签。2D 标签始终面向相机,适合绑定到模型;3D 标签具有透视效果,适合固定在场景中。

3D 标签方法

createArrow3DLabel(LabelID, contentOptions, position, options, Events)

创建带向下箭头指示器的 3D 标签。

参数:

  • LabelID (string): 标签唯一标识符
  • contentOptions (Object):
    • template (string): HTML 模板字符串(支持 Vue 语法)
    • data (Object): Vue 数据对象
  • position (THREE.Vector3 | Array): 标签 3D 位置,可以是 Vector3 对象或 [x, y, z] 数组
  • options (Object, 可选):
    • size (number, 默认: 0.02): 标签缩放大小
    • backgroundColor (string, 默认: "rgba(20, 30, 50, 0.9)"): 背景颜色
    • textColor (string, 默认: "#ffffff"): 文字颜色
    • borderColor (string, 默认: "#22d3ee"): 边框颜色
    • fontSize (number, 默认: 16): 字体大小(px)
    • width (string, 默认: "auto"): 标签宽度
    • className (string, 默认: "label-3d-arrow"): 自定义 CSS 类名
  • Events (Object, 可选):
    • click (Function): 点击事件回调
    • mouseenter (Function): 鼠标进入事件回调
    • mouseleave (Function): 鼠标离开事件回调

返回: CSS3DObject

createIndicator3DLabel(LabelID, contentOptions, position, options, Events)

创建带折线指示器和背景图的 3D 标签。

参数:createArrow3DLabel,但 className 默认为 "label-3d-Indicator"

注意: 此方法需要背景图片资源 /ponit-ui-item.png

返回: CSS3DObject

createExpand3DLabel(LabelID, contentOptions, position, options, Events)

创建可展开的 3D 标签,点击标签可展开显示更多内容。

参数:

  • LabelID (string): 标签唯一标识符
  • contentOptions (Object):
    • template (string): 标签显示的 HTML 模板
    • expandContentHtml (string): 展开时显示的 HTML 内容
    • data (Object): Vue 数据对象
  • position (THREE.Vector3 | Array): 标签 3D 位置
  • options (Object, 可选): 同 createArrow3DLabel,但 className 默认为 "label-3d-Expand"
  • Events (Object, 可选): 事件回调对象

返回: CSS3DObject

示例:

labelControl.createExpand3DLabel(
  "ExpandLabel",
  {
    template: "<div>点击展开</div>",
    expandContentHtml: "<div>这是展开的内容</div>",
    data: {},
  },
  new THREE.Vector3(0, 10, 0),
  { size: 0.02 }
);

2D 标签方法

2D 标签使用 CSS2DRenderer,始终面向相机,不会产生透视变形。支持通过 options.model 参数绑定到模型对象,标签会跟随模型一起移动和旋转。

createArrow2DLabel(LabelID, contentOptions, position, options, Events)

创建带向下箭头指示器的 2D 标签。

参数:

  • LabelID (string): 标签唯一标识符
  • contentOptions (Object): 同 3D 标签
  • position (THREE.Vector3 | Array): 标签位置(如果绑定了模型,则为相对于模型中心的偏移)
  • options (Object, 可选):
    • 所有 3D 标签的选项都支持
    • model (THREE.Object3D, 可选): 要绑定到的模型对象,如果提供,标签会跟随模型移动和旋转
  • Events (Object, 可选): 事件回调对象

返回: CSS2DObject

示例:

// 创建独立的 2D 标签
labelControl.createArrow2DLabel(
  "Label1",
  { template: "<div>独立标签</div>", data: {} },
  new THREE.Vector3(0, 10, 0),
  { size: 0.02 }
);

// 创建绑定到模型的 2D 标签
const model = await modelControl.loadGLTFBuilding({
  ModelID: "car",
  modelPath: "./models/car.gltf",
  position: [0, 0],
  scale: 1,
});

labelControl.createArrow2DLabel(
  "CarLabel",
  { template: "<div>我的车</div>", data: {} },
  new THREE.Vector3(0, 5, 0), // 相对于模型中心的偏移
  {
    size: 0.02,
    model: model, // 绑定到模型
  }
);
createIndicator2DLabel(LabelID, contentOptions, position, options, Events)

创建带折线指示器和背景图的 2D 标签。

参数:createArrow2DLabel,但 className 默认为 "label-3d-Indicator"

注意: 此方法需要背景图片资源 /ponit-ui-item.png

返回: CSS2DObject

createExpand2DLabel(LabelID, contentOptions, position, options, Events)

创建可展开的 2D 标签,点击标签可展开显示更多内容。

参数:

  • LabelID (string): 标签唯一标识符
  • contentOptions (Object):
    • template (string): 标签显示的 HTML 模板
    • expandContentHtml (string): 展开时显示的 HTML 内容
    • data (Object): Vue 数据对象
  • position (THREE.Vector3 | Array): 标签位置
  • options (Object, 可选): 同 createArrow2DLabel,但 className 默认为 "label-3d-Expand"
  • Events (Object, 可选): 事件回调对象

返回: CSS2DObject


6. 完整示例

import * as THREE from "three";
import ThreeSdk from "./index.js";
import LabelControl from "./plugins/LabelControl.js";
import ModelControl from "./plugins/ModelControl.js";

// 初始化
const container = document.getElementById("app");
const sdk = new ThreeSdk(container);

sdk.init(
  {
    position: new THREE.Vector3(0, 50, 100),
    lookAt: new THREE.Vector3(0, 0, 0),
  },
  {
    minDistance: 10,
    maxDistance: 1000,
  },
  {
    ambientLightIntensity: 0.6,
  }
);

// 注册插件
sdk.plugins([LabelControl, ModelControl]);

const labelControl = sdk._PluginsManager.get("LabelControl");
const modelControl = sdk._PluginsManager.get("ModelControl");

// 加载模型(支持 Draco 压缩)
const model = await modelControl.loadGLTFBuilding(
  {
    ModelID: "house",
    modelPath: "./models/house.gltf",
    position: [0, 0],
    scale: 1,
    clickable: true,
    openDraco: false, // 如果模型使用 Draco 压缩,设置为 true
  },
  (percent) => {
    console.log(`加载进度: ${percent}%`);
  }
);

// 启用模型辉光效果
modelControl.enableModelOutlinePass(0x00ffff); // 青色辉光

// 模型交互
modelControl.onModelClickListener((object) => {
  if (object) {
    console.log("模型被点击");
    // 切换模型的辉光效果
    modelControl.switchModelOutlinePass(object);
  }
});

modelControl.onModelMouseMoveListener((object) => {
  if (object) {
    console.log("悬停在模型上");
  }
});

// 创建 3D 标签
labelControl.createArrow3DLabel(
  "info",
  {
    template: "<div>{{ title }}</div>",
    data: { title: "我的模型" },
  },
  new THREE.Vector3(0, 20, 0),
  { size: 0.02 },
  {
    click: () => {
      sdk.flyTo({
        position: new THREE.Vector3(0, 30, 50),
        target: new THREE.Vector3(0, 0, 0),
      });
    },
  }
);

// 创建绑定到模型的 2D 标签
labelControl.createArrow2DLabel(
  "modelLabel",
  {
    template: "<div>模型标签</div>",
    data: {},
  },
  new THREE.Vector3(0, 5, 0), // 相对于模型中心的偏移
  {
    size: 0.02,
    model: model, // 绑定到模型
  }
);

// Mesh 信息管理示例
const meshInfo = sdk.getMeshInfo(model);
console.log("模型信息:", meshInfo);

// 修改后可以恢复
sdk.applyMeshInfo(model, meshInfo);

7. 注意事项

  1. 依赖要求

    • 需要安装 Three.js 和相关依赖
    • 标签系统使用 Vue 2.x 进行渲染,需要确保项目中已引入 Vue
    • 使用 Draco 压缩模型时,需要配置正确的 Draco 解码器路径
  2. 标签系统

    • 2D 标签使用 CSS2DRenderer,始终面向相机,适合绑定到模型
    • 3D 标签使用 CSS3DRenderer,具有透视效果,适合固定在场景中
    • 指示器标签需要背景图片资源 /ponit-ui-item.png
  3. 模型功能

    • 模型辉光效果(OutlinePass)需要先调用 enableModelOutlinePass() 启用
    • 使用 Draco 压缩模型时,确保 openDraco: true 并配置正确的解码器路径
  4. 地面检测:漫游模式需要设置 _GroundPlane 属性才能正常使用地面点击跳转功能

  5. 性能优化

    • 大量模型和标签时建议使用场景组管理,合理控制渲染对象数量
    • 2D 标签性能通常优于 3D 标签,在不需要透视效果时优先使用 2D 标签
  6. 浏览器兼容性:建议使用现代浏览器(Chrome、Firefox、Edge 等)


8. 许可证

ISC


9. 作者

coderxq


10. 仓库地址

  • Gitee: https://gitee.com/xieqianstudent/visual-learning.git