快速搭建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
相关推荐
辻戋2 小时前
从零实现React Scheduler调度器
前端·react.js·前端框架
徐同保2 小时前
使用yarn@4.6.0装包,项目是react+vite搭建的,项目无法启动,报错:
前端·react.js·前端框架
Qrun3 小时前
Windows11安装nvm管理node多版本
前端·vscode·react.js·ajax·npm·html5
中国lanwp3 小时前
全局 npm config 与多环境配置
前端·npm·node.js
JELEE.4 小时前
Django登录注册完整代码(图片、邮箱验证、加密)
前端·javascript·后端·python·django·bootstrap·jquery
TeleostNaCl6 小时前
解决 Chrome 无法访问网页但无痕模式下可以访问该网页 的问题
前端·网络·chrome·windows·经验分享
前端大卫7 小时前
为什么 React 中的 key 不能用索引?
前端
你的人类朋友7 小时前
【Node】手动归还主线程控制权:解决 Node.js 阻塞的一个思路
前端·后端·node.js
小李小李不讲道理9 小时前
「Ant Design 组件库探索」五:Tabs组件
前端·react.js·ant design
毕设十刻9 小时前
基于Vue的学分预警系统98k51(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js