The squares in Threejs are presented in the form of rectangles

Currently, I am working on a vue-cli project that involves three.js. In this project, I have created three square surfaces that are perpendicular to each other, with each side measuring 2 units. To view and control the camera's perspective, I have implemented a Camera and OrbitControl. However, the output is not as expected:

https://i.sstatic.net/rCTyI.png

Instead of showing two square planes, the display shows them as rectangular planes.

Below is the code for my vue component:

<template>
  <canvas id="canvas" ref="canvas" class="w-100 h-100">

  </canvas>
</template>

<script>
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';

export default {
  name: 'Canvas',
  data: function() {
    return {
      strokes: [],
      paint: false,
      scene: {},
      renderer: {},
      camera: {},
      controls: {},
      mouse: {},
      planes: [],
      planeMaterial: {},
    };
  },
  mounted: function() {
    let self = this; // reference to Vue "this"
    let canvas = this.$refs.canvas; // reference of canvas DOM

    this.scene = new THREE.Scene();
    this.scene.background = new THREE.Color(0xf0f0f0);

    this.renderer = new THREE.WebGLRenderer({ canvas: this.$refs.canvas });
    this.renderer.setSize(canvas.offsetWidth, canvas.offsetHeight);
    
    // setting up the camera and orbitControl
    this.camera = new THREE.PerspectiveCamera(15, canvas.offsetWidth / canvas.offsetHeight, 1, 1000);
    this.camera.position.z = 50;
    this.camera.target = new THREE.Vector3();
    this.controls = new OrbitControls(this.camera, this.renderer.domElement);
    this.controls.minDistance = 50;
    this.controls.maxDistance = 200;
    this.controls.mouseButtons = {
      MIDDLE: THREE.MOUSE.PAN,
      RIGHT: THREE.MOUSE.ROTATE,
    }

    // material for plane
    this.planeMaterial = new THREE.MeshBasicMaterial({ color: 0x000000, side: THREE.DoubleSide, opacity: 0.1, transparent: true });
    
    // creating the square planes
    // points used for constructing the planes
    let origin = new THREE.Vector3(0, 0, 0);
    let p1 = new THREE.Vector3(2, 0, 0);
    let p2 = new THREE.Vector3(0, 2, 0);
    let p3 = new THREE.Vector3(0, 0, 2);
    let p4 = new THREE.Vector3(2, 2, 0);
    let p5 = new THREE.Vector3(0, 2, 2);
    let p6 = new THREE.Vector3(2, 0, 2);

    // creating the planes
    let planeGeometry1 = new THREE.PlaneGeometry();
    let planeGeometry2 = new THREE.PlaneGeometry();
    let planeGeometry3 = new THREE.PlaneGeometry();
    planeGeometry1.vertices = [];
    planeGeometry2.vertices = [];
    planeGeometry3.vertices = [];
    planeGeometry1.vertices.push(origin, p1, p2, p4);
    planeGeometry2.vertices.push(origin, p1, p3, p6);
    planeGeometry3.vertices.push(origin, p2, p3, p5);
    let plane1 = new THREE.Mesh(planeGeometry1, this.planeMaterial);
    plane1.name = "Front";
    let plane2 = new THREE.Mesh(planeGeometry2, this.planeMaterial);
    plane2.name = "Bottom";
    let plane3 = new THREE.Mesh(planeGeometry3, this.planeMaterial);
    plane3.name = "Left";

    // adding the planes to the scene
    this.scene.add(plane1);
    this.scene.add(plane2);
    this.scene.add(plane3);

    // other code and events

    // animate function for three.js
    let animate = function() {
      requestAnimationFrame(animate);      
      self.renderer.render(self.scene, self.camera);
    }
    animate();
  },
}

Do you think there is an issue with how I defined the Camera or the OrbitControl? If yes, how do you suggest I fix it?

Answer №1

The issue lies in how the geometry is being generated. Simply replacing vertices in an instance of PlaneGeometry may not align with face definitions. To verify, inspect geometry.faces.

It is recommended to utilize BufferGeometry instead of PlaneGeometry, and define square faces implicitly using three consecutive vertices. This approach will result in a non-indexed geometry.

let camera, scene, renderer;

init();
animate();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.z = 2;

  scene = new THREE.Scene();

  const p1 = new THREE.Vector3(0, 0, 0);
  const p2 = new THREE.Vector3(1, 0, 0);
  const p3 = new THREE.Vector3(1, 1, 0);
  const p4 = new THREE.Vector3(0, 1, 0);

  const geometry = new THREE.BufferGeometry();
  const positions = [];
    
  positions.push( p1.x, p1.y, p1.z );
  positions.push( p2.x, p2.y, p2.z );
  positions.push( p3.x, p3.y, p3.z );
    
  positions.push( p3.x, p3.y, p3.z );
  positions.push( p4.x, p4.y, p4.z );
  positions.push( p1.x, p1.y, p1.z );

  geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );

  const material = new THREE.MeshNormalMaterial();

  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);
    
}

function animate() {

  requestAnimationFrame(animate);
  renderer.render(scene, camera);

}
body {
  margin: 0;
 }
 canvas {
  display: block;
}
<script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9aeef2e8ffffdaaab4ababa2b4ab">[email protected]</a>/build/three.js"></script>

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

Utilizing PHP and JavaScript to Transmit Multiple MySQL Result Sets from a Popup Window

I am attempting to transfer multiple sets of MySQL data through JavaScript from a popup page to the main page. Here is my progress so far: In my popup.php page: $sql = mysql_query("SELECT * from item where category like '$catego ...

Exhilarating Javascript document with fresh lines and line breaks

In my current project, I am dynamically generating a JavaScript page using PHP and .htaccess to convert .php files into .js files. Everything is functioning properly, except for the output of the JavaScript code. For example: $data = array('one&apo ...

Guide on developing a command line display viewer using JavaScript?

I am looking for a solution to display the output of a specific bash command (such as ls -la) in my web application. I need more than a simple black and white style display because the output includes characters that require a bash terminal to render corre ...

Issue with scrolling feature on chrome browser

I've noticed that this piece of code functions correctly in Firefox, but unfortunately doesn't seem to be working in Chrome. In Chrome, the scrolling feature is not functioning as expected - the click event fires, but it fails to move to the posi ...

Creating an interactive animation of bouncing balls within an HTML5 canvas using JavaScript

function refBalls(){ var c = document.getElementById("myCanvas"); var ctx = c.getContext("2d"); var circles = [{x:40,y:100,r:20,color:'black',vx:5,vy:10}] function draw(){ ctx.beginPath(); ctx.arc(circles[0].x, circles[0].y, circles[0].r, ...

AngularJS Error: $parse:ueoe Encounter Unexpected Termination of Expression error

I've been experimenting with a bit of AngularJS on my front-end, but I keep encountering issues when trying to push data from my backend. My backend setup consists of Node.js/Express/Mongoose/Mongo with Handlebars templating. The problem arises when ...

What is the process for browserifying the net.Socket module in Node.js?

I'm exploring ways to connect and query my MS SQL database from JavaScript in a web browser (specifically Chrome, not IE as I don't want to use ActiveX controls). I came across this Node library called Tedious and Browserify to help with this tas ...

ReactJS | Display or Conceal an Array of Objects depending on a specified condition

The Challenge: I am currently working on a task that involves hiding/showing react elements dynamically based on a property of the constructed Object. To be more specific, let's consider the Array of Objects below: const Apps = [ {name: App1, permi ...

Error: The function wrapper.find().simulate('keypress', {key: 'Enter', keycode: 13}) is not working as expected

Let's discuss further about this query vue-btn isn't triggering on pressing the enter key I have designed a sign-in page where users can log in by pressing 'Enter' on the keyboard. Now, I aim to perform a unit test that simulates pres ...

How to pass the Exact property in React MaterialUI Button with RouterLink Component?

I came across this code snippet: <Button activeClassName={classes.active} className={classes.button} component={RouterLink} exact={true} to="/app/certificates" > Certificates </Button> <Button activeClassName={classe ...

Utilizing NodeJS and Express to efficiently share sessions across various routes

I have a Node.js web application built with Express that has multiple routes. These routes need to be able to access and share the session data when interacting with users. The routes are separated into different js files from the main app file, app.js. I ...

Utilizing Jquery for Selecting Multiple Classes and Importing External Content

I'm faced with a challenge involving 2 links, both having the class dynamicLoad. <ul class="navbar"> <li><a href="Page3-News.html" class="dynamicLoad news">NEWS</a></li> <li><a href="Page2-Events.html" ...

What is the best method for extracting a value from a JSON file within an array using electron and node.js?

Hey there, I'm currently working with a JSON file that contains an array of value sets. I'm trying to figure out how to extract the first value from the initial set, specifically the value 3 under the key "pink". This is all being done in Node.js ...

What are the benefits of using a combination of design patterns in JavaScript?

Currently, I am working on a personal project for learning purposes, which is a simple To-Do List. I am implementing the modular pattern (specifically, the revealing module pattern). The image below showcases my general idea of how I intend to build it. V ...

Fade into the world of jQuery with text gracefully appearing and disappearing, only to be replaced by new captivating

I am diving into the world of jQuery for the first time. Even though I'm taking an online class on it, using it in a website is completely new to me. My aim for the homepage is to have "Hello there" appear for 2 seconds, then fade out and be replaced ...

Unit testing in Typescript often involves the practice of mocking

One challenge with mocking in Typescript arises when dealing with complex objects, as is the case with any strongly-typed language. Sometimes additional elements need to be mocked just to ensure code compilation, such as using AutoFixture in C#. In contras ...

Trimming down JSON API responses effectively

I am trying to extract a specific value from an API query and looking for the most efficient way to achieve this. This returns: {"lamports":291171461600,"ownerProgram":"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA","type& ...

Issue with the functionality of socket.io callback functions

Previously, I used to utilize the socket.io emit callback in the following manner: On the client side: mysocket.emit('helloworld', 'helloworld', function(param){ console.log(param); }); On the server side: var server = r ...

Update the directive automatically whenever a change occurs in the root scope property

I am facing an issue with a directive that generates a random number. My goal is to reload or refresh this directive when a checkbox is toggled. Below is the code I have been using, but unfortunately, it's not working as expected. var app = angular. ...

"Stored on the server: A preview of a musical masterpiece

I am working on a website concept where users can preview a 30-second snippet of a song before making a purchase decision. My plan is to store all the mp3 files below the root folder to prevent direct access. My main concern is whether I can enable the 30 ...