I’m really confused about the way vue and THREE.js work together. I am using the exact same obj, once in a plain js environment – where it works perfectly fine – and once in vue.js, where the canvas stays empty and the dev console shows several warnings.
The code I used in js is the exact same as in vue (see below). I also attached a screenshot of the warnings I get in the developer tool from chrome.
I assume the problem is related to the path to the OBJ since some unexpected lines are clearly out of a HTML file. I also tried various alternatives like "./assets/threeD/harrie.obj"
or using let ha = require("../assets/threeD/harrie.obj");
, however the latter causes a compilation error as below:
Failed to compile. ./src/assets/threeD/harrie.obj 1:0 Module parse failed: Unexpected character '#' (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders > # This file uses centimeters as units for non-parametric coordinates. | | v -1.860180 5.269862 2.275461
Deleting the first line doesn’t change anything, the error just shifts to the next line with content
The most confusing thing however is that some kind of geometry seems to get loaded, however no matter the scaling or rotation of the camera, there is absolutely nothing in the canvas. THREE was installed via npm
import * as THREE from "three"; import {OrbitControls} from "three/examples/jsm/controls/OrbitControls"; import {OBJLoader} from "three/examples/jsm/loaders/OBJLoader"; export default { name: "Project1", data: function () { return { mesh: null } }, methods: { harriethree: function () { let w = document.getElementById("threejsview").offsetWidth; let h = document.getElementById("threejsview").offsetHeight; const sceneContainer = document.getElementById("threejsview"); const container = document.getElementById("scene"); document.body.appendChild(container); let scene, camera, renderer, loader; scene = new THREE.Scene(); scene.background = new THREE.Color('#1d1c1c'); camera = new THREE.PerspectiveCamera(75, w / h, 0.1, 1000); camera.translateX(-10); renderer = new THREE.WebGLRenderer(); renderer.setSize(w, h); renderer.domElement.id = "harrieCanvas"; sceneContainer.appendChild(renderer.domElement); let directionalLight = new THREE.DirectionalLight("white", 1); scene.add(directionalLight); let orb = new OrbitControls(camera, renderer.domElement); orb.update(); loader = new OBJLoader(); loader.load("../assets/threeD/harrie.obj", (obj) => { scene.add(obj); console.log(obj); renderer.render(scene, camera); }) animate(); function animate() { requestAnimationFrame(animate); // required if controls.enableDamping or controls.autoRotate are set to true orb.update(); renderer.render(scene, camera); } } }, mounted() { this.$nextTick(function () { this.harriethree(); }) } }
#pro1Top { margin: 20vh 2vw 20vh 2vw; display: grid; grid-template-columns: 47vw 47vw; grid-template-rows: 80vh 80vh; grid-column-gap: 2vw; } #threejsview { grid-row: 1 /span 1; grid-column: 1 /span 1; width: 100%; height: 100%; } #pro1content { grid-row: 1 /span 2; grid-column: 2 /span 1; background-color: green; }
<template> <div id="pro1Top"> <div id="threejsview"> <div id="scene"></div> </div> <div id="pro1content"> <h1>Harrie</h1> <p>Harrie was created during</p> </div> </div> </template>
Advertisement
Answer
in vue apps, your code will be compiled by webpack before running. the root of your app will usually be /dist/index.html
, so the url you provided will not be a valid one, which cause the server return a html page, hence the error message in your screenshot.
to properly point to the model, you should first import the model:
import ha from '../assets/threeD/harrie.obj'
this ha
will be the final url, use it to load the model:
loader.load(ha, ...
but you will probably need to give webpack instruction on how to handle an object
file, otherwise webpack will not include them in the bundle.
add a file loader rule which includes obj
will do the trick, should be something like this:
{ test: /.(png|jpg|gif|mp4|ogg|svg|woff|woff2|ttf|eot|glb|obj|gltf|hdr)$/, loader: 'file-loader' },