快速搭建vue3 threejs模型展示

前言

之前做了个项目需要快速搭建展示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等图片纹理

English

文档: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
相关推荐
Martin -Tang28 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发29 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂2 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
秦jh_6 小时前
【Linux】多线程(概念,控制)
linux·运维·前端