Using Three.JS 'OrbitControls' in VueJS application results in a black screen appearing?

Currently, I've been delving into the basic cube exercise on Three.js, and incorporating the three.js cube into my Vue.JS application.

Initially, everything was functioning smoothly, with my cube rotating as intended using animate, etc.

However, things take a turn for the worse when I introduce OrbitControls. I've experimented with three different versions of npm packages: three-orbitcontrols, three-orbit-controls(THREE), and now orbit-controls-es6.

No matter which one I opt for, upon uncommenting:

controls = new OrbitControls(camera, renderer.domElement)
my canvas screen goes dark...

I've attached my code below so you can analyze what I have scripted. Despite dedicating hours today to testing and troubleshooting, I'm still at a loss.

Fingers crossed someone out there can shed some light on where I'm going wrong.

Many thanks in advance!

<template>
    <div id="container"></div>
</template>

<script> 
import * as Three from "three";
import OrbitControls from 'orbit-controls-es6';

export default {
  name: 'ThreeWindow',
  data() {
    return {
      camera: null,
      scene: null,
      renderer: null,
      mesh: null
    }
  },
  methods: {
    init() {
        let container = document.getElementById('container');

        this.camera = new Three.PerspectiveCamera(70, container.clientWidth/container.clientHeight, 0.01, 10);
        this.camera.position.z = 1;

        this.scene = new Three.Scene();

        let geometry = new Three.BoxGeometry(0.2, 0.2, 0.2);
        let material = new Three.MeshNormalMaterial();

        this.mesh = new Three.Mesh(geometry, material);
        this.scene.add(this.mesh);

        //var controls = new OrbitControls(camera, renderer.domElement);
       //This line here breaks the code and sends canvas black with no cube.

        this.renderer = new Three.WebGLRenderer({antialias: true});
        this.renderer.setSize(container.clientWidth, container.clientHeight);
        container.appendChild(this.renderer.domElement);

    },
    animate() {
        requestAnimationFrame(this.animate);
        //controls.update();
        this.mesh.rotation.x += 0.01;
        this.mesh.rotation.y += 0.02;
        this.renderer.render(this.scene, this.camera);
    }
  },
  mounted() {
      this.init();
      this.animate();
  }
}
</script>

<style scoped>
    #container {
        width: 1000px;
        height: 1000px;
    }
</style>

[Cube Image Provided.][1]


[1]: https://i.stack.imgur.com/UwEEi.png

Answer №1

Agree with the previous response, here is how you can import orbit controls:

import * as Three from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

However, there are other errors that need to be addressed:

Since you are using a VueComponent object, make sure to adjust your camera and renderer variables when passing them into the OrbitControls constructor using the this reference to access the component variables.

Replace

var controls = new OrbitControls(camera, renderer.domElement);

with

this.controls = new OrbitControls(this.camera, this.renderer.domElement);

and ensure to move this line below where you declare this.renderer

so it should look like this:

this.renderer = new Three.WebGLRenderer({antialias: true});

this.controls = new OrbitControls(this.camera, this.renderer.domElement);

Similarly, in your animate() function,

replace controls.update() with this.controls.update()

Answer №2

To utilize OrbitControl, make sure to import it in the following manner:

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

Answer №3

To start troubleshooting, review the browser console for any errors that may be present.
A notable issue is the order in which you are passing arguments to the OrbitControls constructor. Currently, you are using renderer.domElement, however, the renderer object is instantiated after this line of code.
Consider moving the OrbitControls call to a point after the renderer has been created.
For example:

this.renderer = new Three.WebGLRenderer({antialias: true});
this.renderer.setSize(container.clientWidth, container.clientHeight);
var controls = new OrbitControls(camera, renderer.domElement); /*<-- moved to after renderer is created*/

A while back, I dabbled with Three.js and Vue as part of a project. You might find my experience documented on GitHub advantageous or insightful.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Building multi-dimensional array checkboxes in AngularJS - a step-by-step guide

I am working with a multi-dimensional array and I need to display all the data using checkboxes. The array below contains dietary requirements, and I want to create checkboxes for each entry where the value is true. How can I use ng-repeat to iterate over ...

Utilizing Angular to automatically extract keys from nested objects in a response

In my Angular application, I am facing a challenge with accessing nested responses from the server. The data structure contains multiple responses within one parent object, and I am struggling to dig deeper into it. Here is the code snippet I have so far: ...

Inconsistent behavior between Vue.JS and Rails-UJS / Jquery-UJS causing issues with Vuex mutations

During a tutorial, I noticed that two of my view mutations (addCard and addList) are working fine, but the third mutation (editCard) is not functioning properly in Vue. When I attempt to edit a card, the changes are saved correctly in Rails but do not upda ...

Navigating through property objects in Vue: accessing individual elements

I am a newcomer to Vue and after reviewing other questions on this platform, I am struggling to figure out how to pass an object to a child component and reference individual elements within that object. My goal is to have access to all elements of the obj ...

What could be causing my Vue Router to not direct to my component?

Hey there, I'm fairly new to Vue and trying my best to navigate without diving into NPM. Please bear with me as I may ask some basic questions. Let's skip the template for now since I have a component set up and tested outside of routing: var T ...

Troubleshooting ASP.NET Ajax Error Code 0

Starting from scratch with asp.net and hoping to incorporate infinite scrolling using jQuery Ajax and ASP.NET MVC. Here's the progress so far: <div id="container"></div> <div id="progress" style="display:none"> <h4>Loading ...

Error encountered in production mode - TypeError: o is not a function in Vue/webpack/Laravel Mix

Good day. I am utilizing Vue 2 alongside Laravel Mix/Webpack and Node version 14.18.1. Running 'npm run dev' works perfectly fine for me. However, when I execute 'npm run production', I encounter an error saying: TypeError: o is not a ...

Can you offer advice on creating jasmine tests for an Angular controller and service similar to this?

I've been struggling with this issue for hours, mainly because I'm still new to Jasmine and AngularJS. The problem lies within my controller. angular.module('toadlane.controllers', []). controller('MainController', functi ...

Choose particular spreadsheets from the office software

My workbook contains sheets that may have the title "PL -Flat" or simply "FLAT" I currently have code specifically for the "PL -Flat" sheets, but I want to use an if statement so I can choose between either sheet since the rest of the code is identical fo ...

Order of Rendering GLTF in THREE.js

Consider these two code snippets - both versions of three, 0.113.2 and the latest 0.147.0. Make sure to adjust the camera for a clear view of the issue. Both codes are importing a GLTF file, but the rendering looks incorrect in 0.147.0. It seems that the ...

What is the best way to emphasize case-insensitive searchtext matches in JavaScript?

If I have data containing words like Krishna, krishna, KRISHNA and I enter the search text as 'krish', it will retrieve all three words. However, when I want to highlight the matching result, only the exact matching part of the string is highligh ...

Display problem with Backbone view

I'm having trouble loading views on my page while using underscore for templating. I've tried navigating to the page and loading the view in the initialize function, but neither approach has worked. The majority of this code is from an example. ...

Unexpected behavior: Vue toast from Bootstrap disappears instantly

My attempt to show a toast message has been unsuccessful. Despite trying all the example codes provided on https://getbootstrap.com/docs/5.1/components/toasts/, when I click the button to display the toast, it appears briefly and then disappears immediatel ...

What is the best way to enclose a block of content with <div> and </div> tags using the append() function?

My goal is to add an outer div container by first appending it, then adding content, and finally appending the closing tag. However, I'm encountering an issue where the div I added at the beginning automatically closes itself, resulting in two separat ...

Unexpected behavior: Angular post request does not include the expected request body

Embarking on my initial solo Angular project... I am endeavoring to make a post request to my freshly created web service and have implemented the following code: headers = new HttpHeaders( {'Content-Type':'text/plain'} ); l ...

Error message: Attempting to access the property '_layerAdd' of an undefined object in the context of vue and leaflet integration

Encountering an issue while attempting to include a feature group on my map: TypeError: Cannot read property '_layerAdd' of undefined The section of code causing the error: <l-map id="mapid" :zoom="zoom" :center="center" /> var ...

Image placed as background for registration form

In my Vue project, I am trying to create a login form with an image as the background. However, I am facing an issue where the image is not displaying on the page. Can someone guide me on how to add a picture behind the form? HTML: Below is the HTML code ...

The second parameter of the filter function is malfunctioning

I'm currently delving into the "filter" function in AngularJS. Upon reviewing the documentation, I've discovered that it can also take a second parameter. When set to "true", it carries out a strict comparison. HTML <fieldset> <leg ...

The functionality of logic seems to cease once the .then function is executed

I encountered an issue with my Login endpoint that returns a JSON response. I am using vue-router to send a POST request and save the token in localStorage. However, after the POST request is made, the JSON message displays on the screen: {"success":false ...

Scrolling vertically without the appearance of a scrollbar

I've searched all over the internet for a solution to my problem, but nothing seems to work for me. I want to keep vertical scrolling ability while hiding the scrollbar from view in the y direction all the time. The challenge is to make my #content-m ...