前言
之前做了个项目需要快速搭建展示threejs模型简单展示多种格式的模型,时间紧任务重,所以上github找了这个蛮优秀的库解决我目前的问题,喜欢的可以去看看。
- 优点:可以快速展示自己的模型,api用起来方便清楚,适合vue2/vue3,适合多格式模型
- 缺点:限制比较多,比如动画自动播放没办法获取组对象进行播放,有的api按照文档添加后没有效果
github地址:github.com/king2088/vu...
vue-3d-loader
vueJS + threeJS整合的一个3d展示组件。
支持.dae/.fbx/.gltf/.glb/.obj/.ply/.stl/.json,并支持同一个场景导入多个不同3D模型,支持mtl材质以及jpg/png等图片纹理
文档:king2088.github.io/vue-3d-load...
vue3请安装2.0.0 及以上版本,vue2请安装1.x.x版本
功能支持列表
- 加载单个3D模型
- 同时加载多个3D模型
- 同时加载多个不同类型3D模型
- 加载Draco压缩gltf模型(使用方法请查看API)
- 支持自定义文件类型(用于无文件后缀名url)
- 设置场景宽高
- 设置材质及纹理
- 交互控制
- 鼠标事件
- 灯光
- 相机位置及旋转
- 添加标注点
安装
css
npm i vue-3d-loader -S
或
csharp
yarn add vue-3d-loader
使用
全局使用,在入口文件中全局安装,代码如下:
javascript
/* vue2 */
import vue3dLoader from "vue-3d-loader";
Vue.use(vue3dLoader)
/* vue3 */
import vue3dLoader from "vue-3d-loader";
createApp(App).use(vue3dLoader).mount('#app')
非全局使用,在Vue文件中使用如下代码:
javascript
import { vue3dLoader } from "vue-3d-loader"; // 注意 vue3dLoader 写在 {...} 内
在组件中使用标签<vue3dLoader></vue3dLoader>
ini
<vue3dLoader
:height="200"
:showFps="true"
:filePath="['/fbx/1.fbx', '/obj/2.obj', '/gltf/3.gltf']"
:mtlPath="[null, '/obj/2.mtl', null]"
:backgroundColor="0xff00ff"
></vue3dLoader>
API属性文档
事件
event | description |
---|---|
mousedown(event, intersects) | 鼠标按下, intersect:当前相交最近的物体 |
mousemove(event, intersects) | 鼠标移动, intersect:当前相交最近的物体 |
mouseup(event, intersects) | 鼠标放开, intersect:当前相交最近的物体 |
click(event, intersects) | 点击, intersect:当前相交最近的物体 |
load | 加载模型事件 |
process(event, fileIndex) | 加载进度, fileIndex:当前加载模型的索引 |
error(event) | 错误事件 |
使用样例
1. 加载一个3D模型
目前支持dae/fbx/gltf(glb)/obj/ply/stl中任意一种
xml
<!-- 加载fbx模型 -->
<vue3dLoader filePath="models/collada/stormtrooper/stormtrooper.dae"></vue3dLoader>
<!-- 加载obj模型 -->
<vue3dLoader filePath="/obj/1.obj"></vue3dLoader>
2. 同一个场景中加载多个模型
ini
<!--
可同时加载多个不同种类的模型,
支持单独设置每一个模型的位置/缩放/旋转
-->
<template>
<div class="check-box">
<input type="checkbox" @change="change($event, 'position')" checked /> Set
position
<input type="checkbox" @change="change($event, 'rotation')" checked /> Set
rotation
<input type="checkbox" @change="change($event, 'scale')" checked /> Set
scale
</div>
<vue3dLoader
:filePath="filePath"
:position="position"
:rotation="rotation"
:scale="scale"
:cameraPosition="{ x: -0, y: 0, z: -500 }"
/>
</template>
<script setup lang="ts">
import { ref } from "vue";
const filePath = ref();
filePath.value = [
"/models/fbx/Samba Dancing.fbx",
"/models/collada/pump/pump.dae",
];
const position = ref();
position.value = [
{ x: 0, y: 0, z: 0 },
{ x: 100, y: 100, z: 100 },
];
const rotation = ref();
rotation.value = [
{ x: 0, y: 0, z: 0 },
{ x: 10, y: 1, z: 1 },
];
const scale = ref();
scale.value = [
{ x: 0.4, y: 0.4, z: 0.4 },
{ x: 0.8, y: 0.8, z: 0.8 },
];
function change(event: any, type: string) {
const value = event.target.checked;
switch (type) {
case "position":
value
? (position.value = [
{ x: 0, y: 0, z: 0 },
{ x: 100, y: 100, z: 100 },
])
: (position.value = []);
break;
case "rotation":
value
? (rotation.value = [
{ x: 0, y: 0, z: 0 },
{ x: 10, y: 1, z: 1 },
])
: (rotation.value = []);
break;
case "scale":
value
? (scale.value = [
{ x: 0.4, y: 0.4, z: 0.4 },
{ x: 0.8, y: 0.8, z: 0.8 },
])
: (scale.value = []);
break;
}
}
</script>
3. 材质及纹理加载
xml
<!-- obj加载mtl材质 -->
<vue3dLoader filePath="/obj/1.obj" mtlPath="/obj/1.mtl" ></vue3dLoader>
<!-- fbx图片纹理加载 -->
<vue3dLoader filePath="/fbx/1.fbx" textureImage="/fbx/1.png" ></vue3dLoader>
4. 背景颜色及透明度
ini
<vue3dLoader filePath="/fbx/1.fbx" :backgroundAlpha="0.5" backgroundColor="red"></vue3dLoader>
5. 交互控制controls
xml
<template>
<div class="controls">
<div class="buttons">
<!-- 禁止右键拖动 -->
<button @click="enablePan = !enablePan">
{{ enablePan ? "disable" : "enable" }} translation
</button>
<!-- 禁止缩放 -->
<button @click="enableZoom = !enableZoom">
{{ enableZoom ? "disable" : "enable" }} zoom
</button>
<!-- 禁止旋转 -->
<button @click="enableRotate = !enableRotate">
{{ enableRotate ? "disable" : "enable" }} rotation
</button>
</div>
<vue3dLoader
:filePath="'/models/collada/elf/elf.dae'"
:controlsOptions="{
enablePan,
enableZoom,
enableRotate,
}"
:cameraPosition="{ x: 0, y: -10, z: 13 }"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from "vue";
const enablePan = ref(true);
const enableZoom = ref(true);
const enableRotate = ref(true);
</script>
6. 旋转模型
ini
<template>
<vue3dLoader
:rotation="rotation"
@load="onLoad()"
filePath="/models/collada/elf/elf.dae"
/>
</template>
<script setup lang="ts">
import { ref } from "vue";
const rotation = ref();
rotation.value = {
x: -Math.PI / 2,
y: 0,
z: 0,
};
function onLoad() {
rotate();
}
function rotate() {
requestAnimationFrame(rotate);
rotation.value.z -= 0.01;
}
</script>
7. 事件
csharp
<template>
<vue3dLoader filePath="/models/ply/Lucy100k.ply" @mousemove="onMouseMove" />
</template>
<script setup lang="ts">
import { ref } from "vue";
const object = ref(null);
function onMouseMove(event: MouseEvent, intersected: any) {
if (object.value) {
(object.value as any).material.color.setStyle("#fff");
}
if (intersected) {
object.value = intersected.object;
(object.value as any).material.color.setStyle("#13ce66");
}
}
</script>
8. 加载draco模型
此功能需要先下载draco库存储与本地项目的静态文件夹内,才可以正常加载,下载地址:github.com/king2088/vu...
ini
<template>
<vue3dLoader
filePath="/models/gltf/LittlestTokyo.glb"
:cameraPosition="{ x: 10, y: 700, z: 1000 }"
:enableDraco="true"
dracoDir="/draco/"
outputEncoding="sRGB"
/>
</template>
9. 更多演示
Docker部署examples
bash
docker build -t vue/vue-3d-loader .
# 运行docker
docker run -p 8010:80 vue/vue-3d-loader