easy-threesdk
v1.0.6
Published
����Threejs��װ�ij��ù��ܵ�sdk
Readme
ThreeSDK 使用文档
1. 简介
ThreeSDK 是一个基于 Three.js 的封装库,旨在简化 3D 场景的搭建、模型加载、交互控制以及标签系统的开发。通过封装常用的 Three.js 功能,开发者可以更快速地构建具有漫游、交互和标注功能的 3D 应用。
当前版本: 1.0.3
2. 安装
npm install easy-threesdk或直接通过 Gitee 仓库使用:
git clone https://gitee.com/xieqianstudent/visual-learning.git3. 核心功能
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 的 3D HTML 标签系统,支持多种标签样式
- ModelControl:GLTF 模型加载、模型点击/悬停交互管理、网格变换控制器
3.4 其他工具
- 全景球体 (Panorama Sphere):快速创建全景背景
- 立方体贴图背景:支持六面体背景纹理
- 场景组管理 (ThreeGroup):方便管理场景中的对象分组
- 地面平面管理:支持设置地面平面用于漫游模式检测
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 插件支持三种标签类型:
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 }
);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);属性
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 格式的建筑物模型。
参数:
options(Object):ModelID(string): 模型唯一标识符modelPath(string): GLTF 模型文件路径position(Array, 默认:[0, 0]): 模型位置[x, z]坐标scale(number, 默认:30): 模型缩放比例clickable(boolean, 默认:true): 模型是否可点击
onLoadProcess(Function, 可选): 加载进度回调函数(percent) => {}
返回: Promise<THREE.Object3D>
示例:
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);5.3 Plugin: LabelControl
主要方法
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
createExpand3DLabel(LabelID, contentOptions, position, options, Events)
创建可展开的 3D 标签,点击标签可展开显示更多内容。
参数:
contentOptions(Object):template(string): 标签显示的 HTML 模板expandContentHtml(string): 展开时显示的 HTML 内容data(Object): Vue 数据对象
- 其他参数同
createArrow3DLabel,但className默认为"label-3d-Expand"
返回: CSS3DObject
示例:
labelControl.createExpand3DLabel(
"ExpandLabel",
{
template: "<div>点击展开</div>",
expandContentHtml: "<div>这是展开的内容</div>",
data: {},
},
new THREE.Vector3(0, 10, 0),
{ size: 0.02 }
);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");
// 加载模型
await modelControl.loadGLTFBuilding({
ModelID: "house",
modelPath: "./models/house.gltf",
position: [0, 0],
scale: 1,
clickable: true,
});
// 模型交互
modelControl.onModelClickListener((object) => {
if (object) {
console.log("模型被点击");
}
});
// 创建标签
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),
});
},
}
);7. 注意事项
- 依赖要求:需要安装 Three.js 和相关依赖
- Vue 支持:标签系统使用 Vue 2.x 进行渲染,需要确保项目中已引入 Vue
- 地面检测:漫游模式需要设置
_GroundPlane属性才能正常使用地面点击跳转功能 - 性能优化:大量模型和标签时建议使用场景组管理,合理控制渲染对象数量
- 浏览器兼容性:建议使用现代浏览器(Chrome、Firefox、Edge 等)
8. 许可证
ISC
9. 作者
coderxq
10. 仓库地址
- Gitee: https://gitee.com/xieqianstudent/visual-learning.git
