three.js 库二次功能封装 + 配置化的 three.js 开发。
npm i vis-three
// 整体导入
import * as Vis from "vis-three";
// 按需导入
import {
ModelingEngineSupport,
SupportDataGenerator,
generateConfig,
} from "vis-three";
-
下载或者克隆 main 分支代码
-
执行
npm i
安装依赖 -
执行
npm run examples
-
demo 源码位于:
examples
文件夹下
gitee 仓库为 github 的同步备份仓库 github 地址:https://github.com/Shiotsukikaedesari/vis-three
// 基础配置单
const pointLight = Vis.generateConfig("PointLight", {
position: {
x: 10,
y: 20,
z: 20,
},
});
// vis响应式
const engine = new Vis.ModelingEngineSupport();
const pointLight = engine.reactiveConfig(
Vis.generateConfig("PointLight", {
position: {
x: 10,
y: 20,
z: 20,
},
})
);
// vue2 + vis响应式
const engine = new Vis.ModelingEngineSupport();
const pointLight = engine.reactiveConfig(
Vue.observable(
Vis.generateConfig("PointLight", {
position: {
x: 10,
y: 20,
z: 20,
},
})
)
);
// vue3 + vis响应式
const engine = new Vis.ModelingEngineSupport();
const pointLight = reactive(
engine.reactiveConfig(
Vis.generateConfig("PointLight", {
position: {
x: 10,
y: 20,
z: 20,
},
})
)
);
engine.applyConfig(pointLight);
// 动态载入
const engine = new Vis.ModelingEngineSupport();
engine.applyConfig(pointLight);
// 预设加入
const lightDataSupport = new Vis.LightDataSupport({
[pointLight.vid]: pointLight,
});
const engine = new Vis.ModelingEngineSupport({
lightDataSupport: lightDataSupport,
});
const lightDataSupport = new Vis.LightDataSupport({
[pointLight.vid]: pointLight,
});
const cameraDataSupport = new Vis.CameraDataSupport({
// ...
});
const engine = new Vis.ModelingEngineSupport({
lightDataSupport,
cameraDataSupport,
});
const engine = new Vis.ModelingEngineSupport({
lightDataSupport: lightDataSupport,
}).setDom(document.getElementById("app"));
const scene = Vis.generateConfig("Scene", {
children: [pointLight.vid],
});
engine.applyConfig(scene).setScene(scene.vid);
const camera = Vis.generateConfig("PerspectiveCamera", {
position: {
x: 50,
y: 50,
z: 50,
},
far: 5000,
});
engine.applyConfig(camera).setCamera(camera.vid);
<input type="number" v-model="pointLight.position.x" />
data() {
return {
pointLight
}
},
method: {
movePointLight () {
this.pointLight.position.x = 10;
this.pointLight.position.y = 20;
}
}
console.log(engineSupport.toJSON());
import config from "/examples/config.json";
const handlerConfig = JSON.parse(JSON.stringify(config), Vis.JSONHandler.parse);
const engine = new Vis.ModelingEngineSupport()
.setDom(document.getElementById("app"))
.setSize()
.play()
.loadConfigAsync(handlerConfig)
.then((event) => {
// loaded do something...
});
const ENGINEPLUGIN = Vis.ENGINEPLUGIN;
// ModelingEngine
const engine = new Vis.Engine()
.install(ENGINEPLUGIN.WEBGLRENDERER, {
antialias: true,
alpha: true,
})
.install(ENGINEPLUGIN.SCENE)
.install(ENGINEPLUGIN.POINTERMANAGER)
.install(ENGINEPLUGIN.EVENTMANAGER)
.install(ENGINEPLUGIN.EFFECTCOMPOSER, {
WebGLMultisampleRenderTarget: true,
})
.install(ENGINEPLUGIN.SELECTION)
.install(ENGINEPLUGIN.AXESHELPER)
.install(ENGINEPLUGIN.GRIDHELPER)
.install(ENGINEPLUGIN.OBJECTHELPER)
.install(ENGINEPLUGIN.VIEWPOINT)
.install(ENGINEPLUGIN.DISPLAYMODE)
.install(ENGINEPLUGIN.RENDERMANAGER)
.install(ENGINEPLUGIN.STATS)
.install(ENGINEPLUGIN.ORBITCONTROLS)
.install(ENGINEPLUGIN.KEYBOARDMANAGER)
.install(ENGINEPLUGIN.TRANSFORMCONTROLS)
.complete() // 安装插件完成后调用
.setDom(document.getElementById("app"))
.setSize()
.setStats(true)
.play();
GL 渲染器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.WEBGLRENDERER, {
// WebGLRendererParameters
antialias: true, // 抗锯齿
alpha: true, // 允许透明度
//...
});
// event
engine.addEventListener("setSize", (event) => {
// event.width
// event.height
});
engine.addEventListener("setCamera", (event) => {
// event.camera
});
CSS3D 渲染器插件
场景插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.SCENE);
// event
engine.addEventListener("afterAdd", (event) => {
// event.objects
});
engine.addEventListener("afterRemove", (event) => {
// event.objects
});
后期处理器插件
const engine = new Vis.Engine()
.install(Vis.ENGINEPLUGIN.EFFECTCOMPOSER ,{
samples: 4 // 采样程度
format: THREE.RGBAFormat // 后期编码
MSAA: true
})
// event
指针,鼠标管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.POINTERMANAGER, {
throttleTime: number, // 节流时间
});
// event
engine.dom.addEventListener("pointerdown", (event) => {
// mouseevent
});
engine.dom.addEventListener("pointermove", (event) => {
// mouseevent
});
engine.dom.addEventListener("pointerup", (event) => {
// mouseevent
});
场景与物体的事件管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.EVENTMANAGER, {
recursive: false, // 是否可递归计算物体包括children
penetrate: false, // 是否可以穿透触发事件委托
});
// event
// global
engine.eventManager.addEventListener("pointerdown", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("pointermove", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("pointerup", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("pointerenter", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("pointerleave", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("click", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("dblclick", (event) => {
// mouseevent
// event.intersections
});
engine.eventManager.addEventListener("contextmenu", (event) => {
// mouseevent
// event.intersections
});
// object
threeObject.addEventListener("pointerdown", (event) => {
// event.intersections
});
threeObject.addEventListener("pointermove", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("pointerup", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("pointerenter", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("pointerleave", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("click", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("dblclick", (event) => {
// mouseevent
// event.intersection
});
threeObject.addEventListener("contextmenu", (event) => {
// mouseevent
// event.intersection
});
渲染管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.RENDERMANAGER, {
fps: 0, //(预设) 帧率
});
// event
engine.renderManager.addEventListener("render", (event) => {
// event.delta
// event.total
});
engine.renderManager.addEventListener("play", () => {});
engine.renderManager.addEventListener("stop", () => {});
加载器管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.LOADERMANAGER, {
loaderExtends: { diy: DIYLoader }, // 扩展的加载器 extends THREE.Loader
});
// event
engine.loaderManager.addEventListener("beforeLoad", (event) => {
// event.urlList
});
engine.loaderManager.addEventListener("loading", (event) => {
// event.loadTotal
// event.loadSuccess,
// event.loadError
});
engine.loaderManager.addEventListener("loaded", (event) => {
// event.loadTotal,
// event.loadSuccess
// event.loadError
// event.resourceMap
});
engine.loaderManager.addEventListener("detailLoading", (event) => {
// event.detail
// detail = {
// url,
// progress: 0,
// error: false,
// message: url
// }
});
engine.loaderManager.addEventListener("detailLoaded", (event) => {
// event.detail
// detail = {
// url,
// progress: 0,
// error: false,
// message: url
// }
});
资源管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.RESOURCEMANAGER);
// event
engine.resourceManager.addEventListener("mapped", (event) => {
// event.structureMap: Map<string, unknown>
// event.configMap: Map<string, unknown>
// event.resourceMap: Map<string, unknown>
});
快捷键管理插件
数据支持管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.DATASUPPORTMANAGER, {
//module DataSupport
lightDataSupport: new Vis.LightDataSupport(),
// ...
});
// event
编译管理器插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.COMPILERMANAGER);
// event
轨道控制器插件
变换控制器插件
资源监视器插件
坐标轴辅助插件
网格辅助插件
物体辅助插件
视角切换插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.VIEWPOINT, {
viewpoint: Vis.VIEWPOINT.DEFAULT, // default top bottom left right front back
perspective: { // 初始的透视相机设置
position: Vector3Config,
lookAt: Vector3Config,
up: Vector3Config,
};
orthograpbic: { // 初始的正交相机设置
distance: number,
up: Vector3Config,
allowRotate: boolean,
};
});
// event
渲染模式插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.DISPLAYMODE, {
mode: Vis.DISPLAYMODE.ENV, // 'geometry', 'material', 'light', 'env'
overrideColor: "rgb(250, 250, 250)", // geometry模式下被替换的颜色
defaultAmbientLightSetting: { // 默认环境光设置
color: "rgb(255, 255, 255)",
intensity: 0.5
};
defaultDirectionalLightSetting: { // 默认平行光设置
color: "rgb(255, 255, 255)",
intensity: 0.5,
position: {
x: -100,
y: 100,
z: 100,
};
};
});
// event
物体选择插件
const engine = new Vis.Engine().install(Vis.ENGINEPLUGIN.SELECTION);
// event
engine.addEventListener("selected", (event) => {
// event.objects
// event.objectSymbols
});
const customPlugin = function (params) {
// this is engine
this.scene.add(new THREE.Mesh());
this.completeSet.add(() => {
// 稍微允许无须安装插件,所以部分逻辑放在completeSet中最后complete()调用完成
});
};
Vis.Engine.register("customPlugin", customPlugin);
new Vis.Engine().install("customPlugin", params);
const engine = new Vis.ModelingEngine();
// .install(ENGINEPLUGIN.WEBGLRENDERER, {
// antialias: true,
// alpha: true
// })
// .install(ENGINEPLUGIN.SCENE)
// .install(ENGINEPLUGIN.POINTERMANAGER)
// .install(ENGINEPLUGIN.EVENTMANAGER)
// .install(ENGINEPLUGIN.EFFECTCOMPOSER, {
// WebGLMultisampleRenderTarget: true
// })
// .install(ENGINEPLUGIN.SELECTION)
// .install(ENGINEPLUGIN.AXESHELPER)
// .install(ENGINEPLUGIN.GRIDHELPER)
// .install(ENGINEPLUGIN.OBJECTHELPER)
// .install(ENGINEPLUGIN.VIEWPOINT)
// .install(ENGINEPLUGIN.DISPLAYMODE)
// .install(ENGINEPLUGIN.RENDERMANAGER)
// .install(ENGINEPLUGIN.STATS)
// .install(ENGINEPLUGIN.ORBITCONTROLS)
// .install(ENGINEPLUGIN.KEYBOARDMANAGER)
// .install(ENGINEPLUGIN.TRANSFORMCONTROLS)
// .complete()
const engine = Vis.DisplayEngine();
// .install(ENGINEPLUGIN.WEBGLRENDERER, {
// antialias: true,
// alpha: true
// })
// .install(ENGINEPLUGIN.SCENE)
// .install(ENGINEPLUGIN.RENDERMANAGER)
// .install(ENGINEPLUGIN.EFFECTCOMPOSER, {
// WebGLMultisampleRenderTarget: true
// })
// .install(ENGINEPLUGIN.ORBITCONTROLS)
// .install(ENGINEPLUGIN.POINTERMANAGER)
// .install(ENGINEPLUGIN.EVENTMANAGER)
// .complete()
// .install(ENGINEPLUGIN.LOADERMANAGER)
// .install(ENGINEPLUGIN.RESOURCEMANAGER)
// .install(ENGINEPLUGIN.DATASUPPORTMANAGER, parameters)
// .install(ENGINEPLUGIN.COMPILERMANAGER)
EngineSupport + ModelingEngine
const engine = Vis.ModelingEngineSupport();
EngineSupport + DisplayEngine
const engine = Vis.DisplayEngineSupport();
const assets = [
"/examples/public/model/katana/katana.obj",
"/examples/public/texture/katana/katana_BaseColor.png",
"/examples/public/texture/katana/katana_Normal.png",
"/examples/public/texture/katana/katana_Roughness.png",
"/examples/public/texture/katana/katanal_Metallic.png",
];
const loaderManager = engineSupport.loaderManager;
loaderManager.addEventListener("loaded", (e) => {
// do something...
});
engineSupport.loadResources(assets);
engineSupport.registerResources({
"examples.canvas": new document.createElement("canvas"),
});
const resourceManager = engineSupport.resourceManager;
// 额外资源映射
resourceManager.addEventListener("mapped", (e) => {
// do something...
});
const engine = new Vis.ModelingEngine()
.setDom(document.getElementById("app"))
.setSize()
.play();
engine.scene.add(
new THREE.Mesh(
new THREE.BoxGeometry(5, 5, 5),
new THREE.MeshStandardMaterial({ color: "red" })
)
);
engine.scene.add(new THREE.PointLight("white", 1));
- 开发:
npm run dev
- 构建:
npm run build
- 代码格式化:
npm run lint
- e2e 测试:
npm run e2e:open
- 查看例子:
npm run examples
- 内置了 ID 检查,生成 id 请使用
npm i uuid
,import {v4 as getUuid} from 'uuid'
/doc/**/*
- 物体约束器
- 几何修改器
github:
- https://github.com/Shiotsukikaedesari/three-vis-display-editor
- https://github.com/Shiotsukikaedesari/vis-model-generator
gitee: