ThreeJs interactive grid

Looking to create a rectangular "support" grid that allows users to hover over and place objects on specific tiles. For example, hovering over (x:0 y:15) and clicking will result in an object being placed at (x:0 y:15).

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

This grid was initially created with a PlaneGeometry and displayed as a wireframe in version r58.

new THREE.PlaneGeometry(x, y, 16, 9);
var mat = new THREE.MeshBasicMaterial({
    color: 0x004488,
    wireframe: true
});
mat.color.r = r;
mat.color.g = g;
mat.color.b = b;

However, upon updating the code base to r94, triangles started appearing instead of quads for each tile of the plane.

I have attempted:

Drawing lines: I tried creating a rectangular version based on GridHelper's source code. The appearance is great, but the hit detection of a tile seems off. It appears that with lines, detection only occurs if the mouse is directly over a line. With PlaneGeometry, the entire tile area was properly detected.

Drawing a PlaneGeometry with a Texture: Another approach was using a PlaneGeometry with a custom texture like this:

let canvas = document.createElement('canvas');
let context = canvas.getContext('2d');
canvas.height = 32;
canvas.width = 32;
context.beginPath();
context.rect(0, 0, 32, 32);
context.lineWidth = 2;
context.strokeStyle = color.getStyle();
context.stroke();

// Using canvas contents for texture
let texture = new THREE.Texture(canvas);

texture.needsUpdate = true;

let material = new THREE.MeshBasicMaterial();
material.map = texture;
material.flatShading = true;
material.fog = false;
material.lights = false;
material.side = THREE.DoubleSide;
material.transparent = true;

return material;

While hit detection now works well, similar to r54, the appearance is not ideal when viewed from a flat angle:

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

Seeking suggestions on creating a visually appealing grid that functions like a PlaneGeometry in terms of hit detection while ensuring only squares are drawn instead of triangles.

TL;DR; Need a grid that mimics PlaneGeometry (including hit detection) but displays squares instead of triangles.

Answer №1

In order to create a grid made of lines, you can generate a grid using THREE.PlaneBufferGeometry() and modify its .index property. Then, utilize this geometry with THREE.LineSegments().

https://i.sstatic.net/51zvg.png

For further information, visit this link.

To adjust the indices in the source code:

Object.assign(THREE.PlaneBufferGeometry.prototype, {
  toGrid: function() {
    let segmentsX = this.parameters.widthSegments || 1;
    let segmentsY = this.parameters.heightSegments || 1;
    let indices = [];
    for (let i = 0; i < segmentsY + 1; i++) {
      let index11 = 0;
      let index12 = 0;
      for (let j = 0; j < segmentsX; j++) {
        index11 = (segmentsX + 1) * i + j;
        index12 = index11 + 1;
        let index21 = index11;
        let index22 = index11 + (segmentsX + 1);
        indices.push(index11, index12);
        if (index22 < ((segmentsX + 1) * (segmentsY + 1) - 1)) {
          indices.push(index21, index22);
        }
      }
      if ((index12 + segmentsX + 1) <= ((segmentsX + 1) * (segmentsY + 1) - 1)) {
        indices.push(index12, index12 + segmentsX + 1);
      }
    }
    this.setIndex(indices);
    return this;
  }
});

Implementation:

var planeGeom = new THREE.PlaneBufferGeometry(10, 5, 10, 5).toGrid();
var gridPlane = new THREE.LineSegments(planeGeom, new THREE.LineBasicMaterial({color: "yellow"}));

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

Using directive to access service values directly

I am in need of utilizing a directive to fetch and display data using ng-repeat from a service. The anticipated result will be <ul>Days <li>Monday</li> <li>Tuesday</li> ... <ul> <ul>Month <li>January</li ...

Unable to click a button on HTML file

In my current project, there is a piece of code responsible for checking if the user is logged in or not. If the user hasn't logged in yet, they are redirected to the login page. Once the user logs in successfully, they should be able to upload conten ...

Tips for effectively utilizing Mongoose models within Next.js

Currently, I am in the process of developing a Next.js application using TypeScript and MongoDB/Mongoose. Lately, I encountered an issue related to Mongoose models where they were attempting to overwrite the Model every time it was utilized. Here is the c ...

Pause page scrolling temporarily in JavaScript while allowing the scrollbar to continue scrolling until the pause is lifted

I'm currently working on achieving a similar effect to the one found on this website: . On that site, as you scroll down, the 'HELLO' text moves to the side. I've managed to do that part successfully, but I'm facing an obstacle reg ...

When two divs are activated, the third div goes into invisible mode

I attempted this code, but it doesn't appear to be functioning correctly. if(div1)&& (div2)==display:none { div3=display:none; } else { div3=display:block; } ...

"Using JavaScript to initiate a popup window that displays a specific destination link

Whenever I view this code, the iframe popup automatically opens. But I want the iframe to open only when I click the "click me" button. Can someone please assist me with this? I believe it's a simple trick, but as a JavaScript amateur, I am struggling ...

Creating a reusable field for reactive forms in Angular: A step-by-step guide

I need assistance with creating a versatile field component for reactive forms, but I am facing challenges in retrieving the value from the custom-input element. <form [formGroup]="form" (ngSubmit)="submit()"> <custom-input i ...

Different approach for binding in Vue.js

Seeking Alternatives I am curious to find out if Vue.js offers a different approach for outputting data beyond the conventional curly braces. Is there a syntax similar to Angular's ng-bind directive that I could utilize? Although Vue.js primarily ut ...

Guide to executing a chain of parallel API calls with changing parameters using nodejs

I am working on a project that involves making multiple API calls while changing a single parameter value in the URL based on values stored in an array. Currently, I have about 30-40 values in the array and I am using NodeJS and Express for this task. Belo ...

The format provided is not utilized by Datetimepicker

I've encountered an issue with the Date Time Picker provided by JQuery. Despite setting a specific format, it seems to be using its default date format which results in the following error appearing in the console: Uncaught TypeError: F.mask.replace i ...

It is advised not to use arrow functions to assign data when fetching API data with axios in Vue.js 2

Trying to retrieve data from a URL using Axios in my Vue app is resulting in the error message: Error: Arrow function should not return assignment Complete error message: Error: Arrow function should not return assignment (no-return-assign) at src\co ...

The error message "Uncaught TypeError: Unable to retrieve the 'lat' property of an undefined object when serializing leaflet data using $.param()" is displayed

Being a complete novice in JavaScript, I am experimenting with posting user location and map bounds using Leaflet and an AJAX call. While my event handler stateUpdater.onLocationFound successfully logs the user coordinates and map bounds, I encounter an is ...

Maintain the functionality, but disable all stylesheets and scripts

I have 4 separate pages, each with their own distinct stylesheets and scripts that I switch between using ajax and historyPopState. The issue is that downloading them repeatedly can be inefficient. I am seeking a solution to keep the stylesheets and scri ...

Unable to build a React Native library

For the past month, I've been diligently working on a react native component library, and I believe it's finally in a state where I can publish it as a package on npm. After pushing it to GitHub and running npm publish, everything seemed to be ru ...

Issue encountered with JavaScript AJAX involving a Cross Domain ASMX Web Service JSONP Request

I have been working on a local web service that I believe fits the criteria for making cross-domain JavaScript calls to access external data within Dynamics CRM. However, I am facing some challenges in creating the JavaScript AJAX code needed to connect wi ...

Follow button on LinkedIn is secure with Google Chrome's Content Security Policy set to script-src report-sample

Having an issue trying to add a LinkedIn Follow button to the website. It works perfectly in Firefox, but is not functioning in Chrome. The Console displays the following error: The source list for Content Security Policy directive 'script-src&apos ...

Stop users from refreshing or closing the window while an axios request is being processed

I'm in the process of creating a dynamic Web Application that involves utilizing Axios.get requests. Given that Axios operates asynchronously, my approach includes an async function along with await axios.all: async handleSubmit(){ const ...

What is the method to retrieve response text?

This is the content of my register.js file: var formdata = new FormData(); formdata.append("name", name.value); formdata.append("username", username.value); formdata.append("email", email.value); formdata.append("password", password.value) ...

Guide on how to display a tetrahedron with distinct textures on every face in three.js?

I've been attempting various methods, but I'm still stumped.. Is there a way to apply different textures to each face of a tetrahedron? Initially, I went about it like this. import * as THREE from 'three'; window.onload = () =&g ...

Sending Django Variable With Javascript

As a newcomer to Javascript, I am grappling with retrieving the value of a variable from my HTML form. My current code seems to be somewhat functional - I added an alert to test the logic and found that the else statement is working fine. However, I'm ...