VueJS + threeJS 3d viewer component

Last update: Aug 11, 2022

vue-3d-loader

vueJS + threeJS 3d viewer component.

support .dae/.fbx/.gltf/.glb/.obj/.ply/.stl/.json models, and support the same scene to import multiple different 3D models, support mtl materials and texture

Version License Downloads

简体中文

Click here view demo page

demo gif

demo gif image

Vue3 please install 2.0.0 or later, vue2 please install 1.x.x version

Feature support list

  • Load a single 3D model
  • Load multiple 3D models simultaneously
  • Load multiple 3D models of different types simultaneously
  • Set scene width and height
  • Set up materials and textures
  • Interactive control
  • Mouse event
  • Light
  • Camera position and rotation
  • Add label points

Install vue-3d-loader

npm i vue-3d-loader -S # npm install vue-3d-loader -save

or

yarn add vue-3d-loader

How to use vue-3d-loader

If use in global, insert code in entry file:

/* vue2 */
import vue3dLoader from "vue-3d-loader";
Vue.use(vue3dLoader);

/* vue3 */
import vue3dLoader from "vue-3d-loader";
createApp(App).use(vue3dLoader).mount("#app");

If non-global use, insert code in your vue files:

import { vue3dLoader } from "vue-3d-loader"; // The vue3dLoader in {...}

Use tags in your components

">
<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

Attributes

Prop Type Default Value Description
filePath string | array -
const filePath = './models/tree.obj'
/* or */
const filePath = [
  './models/tree.obj', 
  './models/building.obj'
]

File path, supports multiple files to be loaded together, note: If each file corresponds to a material, you need to set the material mtlPath as an array. The same is true for image textures, which need to be set to textureImage as an array

mtlPath string | array -
const mltPath = './models/tree.mlt'
/* or */
const mltPath = [
  './models/tree.mlt',
  './models/building.mlt'
]

Material path, supports multiple materials to be loaded together, set this parameter to an array, you must set filePath to an array

textureImage string | array -
const textureImage = './texture/tree.jpg'
/* or */
const textureImage = [
  './texture/tree.jpg',
  null, 
  './building.png'
]

jpg/png texture, if is array, filePath must be set to an array

width number parent element width 100 Scene width
height number parent element height 100 Scene height
position object | array {x:0, y:0, z:0}
const position = {x:0, y:0, z:0}
// or
const position = [
  {x:10, y:10, z:10},
  {x:50, y:50, z:50}
]
Model position coordinates, position use array type when filePath is an array
rotation object | array {x:0, y:0, z:0}
const rotation = {x:0, y:0, z:0}
// or
const rotation = [
  {x: 10, y:20, z:30},
  {x: 0, y: 16, z: 20}
]
Model rotation coordinates, rotation use array type when filePath is an array
cameraPosition object {x:0, y:0, z:0}
const cameraPosition = {x:0, y:0, z:0}
Camera position coordinates
cameraRotation object {x:0, y:0, z:0}
const cameraRotation = {x:0, y:0, z:0}
Camera rotation coordinates
scale object | array {x:1, y:1, z:1}
const scale = {x:1, y:2, z:1}
// or
const scale = [
  {x:1, y:2, z:1},
  {x:0.5, y:0.5, z:0.5}
]
Model scale, scale use array type when filePath is an array
lights array [{ type: "AmbientLight", color: 0xaaaaaa, }, { type: "DirectionalLight", position: { x: 1, y: 1, z: 1 }, color: 0xffffff, intensity: 0.8, }]
const lights = [
  { 
    type: "AmbientLight", 
    color: "red", 
  }, 
  { 
    type: "DirectionalLight", 
    position: { x: 100, y: 10, z: 100 }, 
    color: "green", 
    intensity: 0.8, 
  }, 
  { 
    type: "PointLight", 
    color: "#000000", 
    position: { x: 200, y: -200, z: 100 }, 
    intensity: 1 
  }, 
  { 
    type: "HemisphereLight",
    skyColor: "#00FF00",
    groundColor: "#000000",
    position: { x: 200, y: -200, z: 100 }
  }
]
Lights is array, type AmbientLight | DirectionalLight | PointLight | HemisphereLight
backgroundColor number | string 0xffffff
const bgColor = 0xff00ff
/* or */
const bgColor = 'red'
/* or */
const bgColor = '#000000'
/* or */
const bgColor = 'rgba(0, 0, 0, 0.5)'
Scene background color
backgroundAlpha number 1
const bgAlpha = 0.5
Background transparency. value range 0-1
controlsOptions object - -

Control parameter OrbitControls Properties

crossOrigin string anonymous anonymous | use-credentials Cross-domain configuration.
requestHeader object anonymous
const headers = { 
  'Authorization': 'Bearer token'
}
Set request header.
outputEncoding string linear linear or sRGB

linear is LinearEncoding, sRGB is sRGBEncoding (sRGBEncoding can restore material color better). Renderer's output encoding WebGLRenderer OutputEncoding

webGLRendererOptions object { antialias: true, alpha: true } -

WebGLRenderer options WebGLRenderer Parameters

showFps boolean false -

Show stats infomation

clearScene boolean false - Clear scene
parallelLoad boolean false -

Enable/disable parallel load models (useful only for multi-model loading). Use this attribute, the process event will be unpredictable

labels array -
const labels = [
  {
    image: "", 
    text: "", 
    textStyle: { 
      fontFamily: "Arial", 
      fontSize: 18, 
      fontWeight: "normal", 
      lineHeight: 1, 
      color: "#ffffff", 
      borderWidth: 8, 
      borderRadius: 4, 
      borderColor: "rgba(0,0,0,1)",
      backgroundColor: "rgba(0, 0, 0, 1)" 
    }, 
    position: {x:0, y:0, z:0}, 
    scale:{x:1, y:1, z:0}, 
    sid: null
  }
]

Add an image/text label and set image to display the image label. Set text to display text labels. Text styles can be set using textStyle. For examples, see the examples/add-label.vue file

Events

event description
mousedown(event, intersects) mouse down, intersect: currently intersecting objects
mousemove(event, intersects) mouse move, intersect: currently intersecting objects
mouseup(event, intersects) mouse up, intersect: currently intersecting objects
click(event, intersects) click, intersect: currently intersecting objects
load load model event
process(event, fileIndex) loading progress, fileIndex: the index of the currently loaded model
error(event) error event

Example

1. Load a 3D model

supports dae/fbx/gltf(glb)/obj/ply/stl models

">

<vue3dLoader
  filePath="models/collada/stormtrooper/stormtrooper.dae"
>vue3dLoader>

<vue3dLoader filePath="/obj/1.obj">vue3dLoader>

2. Loading multiple models in the same scene

Set position Set rotation Set scale
">

<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. Material and texture

">

<vue3dLoader filePath="/obj/1.obj" mtlPath="/obj/1.mtl">vue3dLoader>

<vue3dLoader filePath="/fbx/1.fbx" textureImage="/fbx/1.png">vue3dLoader>

4. Background color and transparency

">
<vue3dLoader
  filePath="/fbx/1.fbx"
  :backgroundAlpha="0.5"
  backgroundColor="red"
>vue3dLoader>

5. Controls

">
<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. Rotate model

">
<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. Events

">
<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. More demos code

Click here to see more demo code

Coming soon

  • Supports Vue3

Bugs

issues

Thanks

This plugin is inseparable from vue-3d-model

GitHub

https://github.com/king2088/vue-3d-loader
You might also like...

Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js

v-viewer Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js Live demo Examples directive component thumbnail

Aug 16, 2022

Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js

Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js

Aug 8, 2022

Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js

v-viewer Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js Live demo Examples directive component thumbnail

Dec 3, 2020

Image viewer component for vue 3.x, supports rotation, scale, zoom and so on, based on viewer.js

v-viewer Image viewer component for vue, supports rotation, scale, zoom and so on, based on viewer.js v-viewer for vue2 Live demo Quick Example direct

Jul 22, 2022

✨ ThreeJS + VueJS 3 + ViteJS ⚡

✨ ThreeJS + VueJS 3 + ViteJS ⚡

✨ ThreeJS + VueJS 3 + ViteJS ⚡

Aug 16, 2022

A rotating earth H5 page with Vue and threejs

A rotating earth H5 page with Vue and threejs

A rotating earth H5 page with Vue and threejs This is a vue clone of the original H5 site How to play open it with chrome mobile debug mode touch and

Aug 9, 2022

A Wrapper of Panolens for building VR applications with Vue based on threejs

A Wrapper of Panolens for building VR applications with Vue based on threejs

A framework for building VR applications with Vue

Aug 9, 2022

Trakr.app - Track car telemetry in 3D space,built using vue and threejs

Trakr.app - Track car telemetry in 3D space,built using vue and threejs

WIP Features Three: Dynamic point cloud prototype Nuxt: Discord login Nuxt: Simp

Apr 30, 2022

3d-earth-orbits - A ThreeJS earth with rotating moons built using vue.js

3D Earth Orbits Warning, this is still a work in progress. Many changes and clea

Jul 23, 2022

📷 vue.js 3D model viewer component

📷 vue.js 3D model viewer component

vue-3d-model vue.js 3D model viewer component, based on threejs, inspired by model-tag 一个展示三维模型的Vue组件,支持模型操作和模型点击事件,能自动缩放模型到合适大小并校正偏移,支持多种格式的模型。 Examp

Aug 17, 2022

A responsive and configurable Marmoset Viewer component for Vue.

A responsive and configurable Marmoset Viewer component for Vue.

Jul 13, 2022

vue.js pdf viewer

vue-pdf vue.js pdf viewer Install npm install --save vue-pdf Example - basic template pdf src="./static/relativity.pdf"/pdf /template scri

Aug 8, 2022

A PDF viewer for Vue using Mozilla's PDF.js

Pdfvuer A PDF viewer for Vue using Mozilla's PDF.js Install npm install --save pdfvuer Example - basic template pdf src="./static/relativity.pdf

Aug 15, 2022

An Mobile-First image viewer for Vue2 / 一个移动端优先的 Vue2 图片预览插件

An Mobile-First image viewer for Vue2  / 一个移动端优先的 Vue2 图片预览插件

img-vuer An Mobile-First image viewer for Vue2 中文 README 🙆‍♀️ Easy to use 👉 Swipe gesture 🔍 Zoom gesture V0.11.0 Now you can use thumbnail~ V0.13.0

Aug 2, 2022

Handy Uploader is a responsive Vue.js file uploader and file viewer with an image compressor. It offers three display options (simple / thumbnail / table).

Handy Uploader is a responsive Vue.js file uploader and file viewer with an image compressor. It offers three display options (simple / thumbnail / table).

Handy Uploader is a responsive Vue.js file uploader and file viewer with an image compressor. It offers three display options (simple / thumbnail / table).

Jul 18, 2022

A simple grid-based web viewer for Formula 1

A simple grid-based web viewer for Formula 1

A simple grid-based web viewer for Formula 1. Simply login with your F1TV credentials, select the season, event, and session, and then drag and drop the channels you want to watch into the grid! Unable to install it? No problem! The application can be fully accessed here

Aug 4, 2022

Viewer de l'émission avec les logs.

Underscore_ Logs Viewer Un petit site pour voir les logs d'Underscore_. Vue 3 + Typescript + Vite This template should help get you started developing

May 4, 2022

Technical (JSON viewer) explorer for XRPL devs. Click on account / hash / ... to zoom in.

XRP Ledger Technical Explorer A technical (geeky) JSON viewing explorer for the XRP Ledger. BETA! Early beta of a new (technical) tx / ledger / object

Feb 11, 2022

Tik Tok popular trends viewer

Tik Tok popular trends viewer

Tik Tok popular trends viewer

Jul 3, 2022
Related tags
A basic vuejs off canvas sidebar component

A basic vuejs off canvas sidebar component

Feb 14, 2020
VueJS Component - drawable 'object-based' canvas

vue-drawable-canvas VueJS Component - drawable 'object-based' canvas Vue3. Install yarn add vue-drawable-canvas Usage To test - clone repo and run: ya

Sep 24, 2021
:dizzy: A Vue.js background component for canvas-nest.
:dizzy: A Vue.js background component for canvas-nest.

vue-canvas-nest A Vue.js component for canvas-nest. Install # install dependencies npm i vue-canvas-nest # or use yarn yarn add vue-canvas-nest Usage

Jul 30, 2022
🖋 Vue Signature Pad Component

Vue Signature Pad Vue component wrap for signature pad Demo Installation $ yarn add vue-signature-pad Usage import Vue from 'vue'; import VueSignature

Aug 5, 2022
A Vue.js wrapper component that turns everything into fun scratch cards.

?? vue-scratchable ??️‍?? ?? Publishing status: A Vue.js wrapper component that turns everything into fun scratch cards. Includes touch support withou

Aug 9, 2022
A simple to use, but extensive, camera component for Vue 3 with Typescript support to create great camera experiences.
A simple to use, but extensive, camera component for Vue 3 with Typescript support to create great camera experiences.

A simple to use, but extensive, camera component for Vue 3 with Typescript support to create great camera experiences.

Aug 9, 2022
A Vue component of a slot machine, made with an HTML5 canvas, RWD
A Vue component of a slot machine, made with an HTML5 canvas, RWD

Vue-SlotMachine A Vue component of a slot machine, made with an HTML5 canvas, RWD. Table of Contents Installation Usage Support Contributing Installat

Jun 16, 2022
OffCanvas (Sidenav/Drawer) component for Vue.js

OffCanvas OffCanvas (Sidenav/Drawer) component for Vue.js Create a smooth off-canvas sidebar that slides in and out of the page. Live examples & Docs

Feb 14, 2020
vue-canvas-element - a Vue component to create a multipurpose canvas card

| vue-canvas-element vue-canvas-element is a Vue component to create a multipurpose canvas card. vue-canvas-element has many options and can be used i

Jan 30, 2019
PicTemplate - A Vue Component for html2canvas
 PicTemplate - A Vue Component for html2canvas

PicTemplate - A Vue Component for html2canvas

Aug 1, 2022