Updating the dimensions of a Shape in ThreeJS

Is it possible to update the dimensions of a Shape in ThreeJS without the need to recreate the entire shape each time?

I am creating a square based on the user's mouse movement to define the area of zoom. Currently, I recreate the square shape and adjust the mesh with each iteration of onmousemove.

This method doesn't seem to be the most efficient way to achieve my goal. Below is a visual representation of the Shape I am creating (displayed in green). The concept is that it resizes as the user moves their mouse, similar to a basic selection square in Photoshop and other applications.

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

Relevant Code:

elem.bind('mousedown', function(event){
    mouse_down_coords = getElementCoordinates(event);
    mouse_down_coords = convertElementToGLCoordinate((mouse_down_coords.x / elem[0].offsetWidth), (mouse_down_coords.y / elem[0].offsetHeight));
    is_mouse_down = true;
});

var zoom = function(down, up){
    if(!(down.x === up.x && down.y === up.y)){
        var height = Math.abs(up.y - down.y);
        var width = Math.abs(up.x - down.x);
        if(height < ((Math.abs(camera.top) + Math.abs(camera.bottom)) * 0.03) && width < ((camera.left + camera.right) * .02)){
            alert(height + ' < ' + ((Math.abs(camera.top) + Math.abs(camera.bottom)) * 0.01) + '\n' + width + ' < ' + ((camera.left + camera.right) * .02));
            return;
        }
        camera.left = down.x < up.x ? down.x : up.x;
        camera.right = down.x > up.x ? down.x : up.x;
        camera.top = down.y > up.y ? down.y : up.y;
        camera.bottom = down.y < up.y ? down.y : up.y;
        camera.updateProjectionMatrix();
    }
};

//reset camera on double click
elem.bind('dblclick', function(event){
    ...
});

elem.bind('mouseup', function(event){
    mouse_up_coords = getElementCoordinates(event);
    var x_percent = (mouse_up_coords.x / elem[0].offsetWidth);
    var y_percent = (mouse_up_coords.y / elem[0].offsetHeight);
    mouse_up_coords = convertElementToGLCoordinate(x_percent, y_percent);
    is_mouse_down = false;
    scene.remove(rectMesh);
    scene.remove(wf);
    selection_in_scene = false;
    zoom(mouse_down_coords, mouse_up_coords);
});


elem.bind('mousemove', function(event){
    if(is_mouse_down){
        var coords = getElementCoordinates(event);
        coords = convertElementToGLCoordinate((coords.x / elem[0].offsetWidth), (coords.y / elem[0].offsetHeight));
        if(selection_in_scene){
            scene.remove(wf);
            scene.remove(rectMesh);
        }
        rectLength = (coords.y - mouse_down_coords.y);
        rectWidth = (coords.x - mouse_down_coords.x);
        rectShape = new THREE.Shape();
        rectShape.moveTo(mouse_down_coords.x, mouse_down_coords.y);
        rectShape.lineTo(mouse_down_coords.x+rectWidth, mouse_down_coords.y);
        rectShape.lineTo(mouse_down_coords.x+rectWidth, mouse_down_coords.y+rectLength);
        rectShape.lineTo(mouse_down_coords.x, mouse_down_coords.y+rectLength);
        rectShape.lineTo(mouse_down_coords.x, mouse_down_coords.y);
        rectGeom = new THREE.ShapeGeometry(rectShape);
        rect_material = new THREE.MeshBasicMaterial({color:0xffffff, opacity: 0.1, vertexColors: 0xffffff});
        rect_material.transparent = true;
        rectMesh = new THREE.Mesh(rectGeom, rect_material);
        wf = new THREE.EdgesHelper( rectMesh, 0x00ff00 );
        scene.add(rectMesh);
        scene.add(wf);
        selection_in_scene = true;
    }
}); 

Answer №1

Below is an example showcasing how to adjust the proportions of a geometric shape:

"use strict";
var renderer, scene, camera, light, geometry, material, mesh;
var angle, x0, y1, x2, y3;
window.onload = function() {
  renderer = new THREE.WebGLRenderer(); 
  renderer.setSize(750, 750); 
  renderer.setClearColor( 0x102030, 1);  
  document.body.appendChild(renderer.domElement);
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(30, 1);
  camera.position.set(0, 0, 30);
  camera.lookAt(new THREE.Vector3(0,0,0));
  light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.set(10, 10, 20);
  scene.add(light);

  var shape = new THREE.Shape();
  shape.moveTo(-5, -5);
  shape.lineTo( 5, -5);
  shape.lineTo( 5,  5);
  shape.lineTo(-5,  5);
  shape.lineTo(-5, -5);
  geometry = new THREE.ShapeGeometry(shape);
  material = new THREE.MeshBasicMaterial({color:0xffffff, opacity: 0.5, vertexColors: 0xffffff});
  material.transparent = true;
  mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
  animate();
}
function animate() {
  angle = Date.now() / 1000 * 6.2832 / 3; // 3 second period
  x0 = -5 + Math.cos(angle); // upper left
  y1 =  5 + Math.cos(angle); // upper right
  x2 =  5 + Math.sin(angle); // lower right
  y3 = -5 + Math.sin(angle); // lower left
  mesh.geometry.vertices[0].setX(x0);
  mesh.geometry.vertices[1].setY(y1);
  mesh.geometry.vertices[2].setX(x2);
  mesh.geometry.vertices[3].setY(y3);
  mesh.geometry.verticesNeedUpdate = true;
  renderer.render(scene, camera);
  requestAnimationFrame(animate);   
}

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

Determine the total value derived from adding two option values together

I am attempting to calculate the sum of two select options and display the result. So far, my attempts have only resulted in returning the value 1. What I am aiming for is to add the values from n_adult and n_children, and then show the total under Numbe ...

When attempting to add objects to an indexedDB object store, an InvalidStateError is encountered

I have defined IndexedDB and IDBTransaction dbVersion = 1; var db; var dbreq; var customerData = { ssn: "444", name: "Bill", age: 35, email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d2b0bbbebe92b1bdbfa2b3bcabfcb1bdbf"& ...

Learn how to synchronize global packages across multiple computers using npm

After installing several npm global packages on my work computer, I am now looking to synchronize these packages with another device. In a typical project, we utilize a package.json file to keep track of package details, making it easy to install all the ...

Put a pause on running a JavaScript function until the one preceding it has completed

After successfully creating a product using a modal box form on my page, the modal disappears with an effect and the list of products on the page should be updated with the newly added item. However, the animation of the modal disappearing disrupts the fl ...

Is it necessary to utilize Babel with Node.js?

I am aware that Node.js fully supports ES6 now, using version 7.2.1. Recently, I was advised by someone that the current ES6 implementation in Node.js may not be production ready and that I might need to use Babel for a more robust ES6 set-up. After visit ...

What is the best method for sending the styled and checked option via email?

Just finished customizing the checkboxes on my contact form at cleaners.se/home. Here's my question: If I select "telefon," how can I ensure that this option is sent to my email? In Contact Form 7, I used to simply type a shortcode. Is there a simila ...

Inject the content loaded from the server into a div element, and insert that div at the

I am trying to insert the div(#loadmore) element inside the div(#boxchatting) element when the content from "result.php" is loaded into div(#boxchatting). Here is the code I used: $('#loadmore').prependTo('#boxchatting'); $('#boxc ...

What steps can be taken to ensure that the onchange event functions properly with radio input

I am facing an issue with my input field as the value changes automatically when an option is selected. However, I want this functionality to also work the same way when a radio input option is selected. How can I modify the code to achieve this? func ...

Showing Sequelize validation errors in Express API: a comprehensive guide

In my Node.js/Express API with Sequelize ORM running MySQL, I have an Organization model that enforces a 2-100 character rule under validation. When this rule is violated in the first code snippet below, the err item from the catch block in the second code ...

How can you access the index of an object in Vue.js when one of its properties has been modified

Here's the Vue component code I'm working with: data: function () { return { products: [ { product_id: '', price: ''}, { product_id: '', price: ''}, ], ...

Typescript encountering onClick function error during the build process

My current challenge involves creating a submit function for a button in my application. However, when I attempt to build the project, I encounter a typing error that is perplexing me. Despite trying various methods, I am unable to decipher how to resolve ...

Employing multer in conjunction with superagent to enable file uploads from a React application

I am new to using multer and experiencing some difficulties with it. My goal is to upload an image file from a react client using the superagent library to my server. However, the req.file data always shows as undefined in my code: On the server side : ...

Utilizing destructuring and Object.entries for advanced formatting

I'm embarking on a new React project and facing an issue with the JSON data structure returned by my API for meetings. I attempted to utilize destructuring and Object.entries. This is what I currently have: { "meetings": [ ...

What is the best way to retrieve the initial element from a map containing certain data?

I am attempting to retrieve the first image path directory from an API that contains an Image so I can assign the value to the Image source and display the initial image. However, when using fl[0], all values are returned. Below is the code snippet: {useL ...

Remove the content located beside an input element

Seeking assistance for a straightforward query: Snippet of code: <span> <input id="elemento_20_1" name="elemento_20_1" class="elemento text" size="2" maxlength="2" value="" type="text"> / <label for="elemento_20_1">DD</label> < ...

I'm looking for a button that, when clicked, will first verify the password. If the password is "abcd," it will display another submit button. If not, it

<form action="#" method="post" target="_blank"> <div id = "another sub"> </br> <input type = "password" size = "25px" id="pswd"> </br> </div> <button><a href="tabl ...

Update with the string before it in a JSON list

Within a JSON file, I came across an array that requires the 'TODO' placeholder to be replaced with the entry above it. To elaborate, the initial "TODO" should be substituted with "Previous question" and the subsequent one with "Next question". ...

Implementing asynchronous validation in Angular 2

Recently started working with Angular 2 and encountered an issue while trying to validate an email address from the server This is the form structure I have implemented: this.userform = this._formbuilder.group({ email: ['', [Validators.requir ...

ordering the date and time in a reverse sequence using javascript

I am working with dynamically generated date and time data and I am looking to sort them in descending order using JavaScript. Here is an example of the data format I am dealing with: var array= ["25-Jul-2017 12:46:39 pm","25-Jul-2017 12:52:23 pm","25-Ju ...

Create a library with CSS files added, excluding any test files

As I develop a React library, I've encountered an issue where the CSS files are being ignored during the build process. In an attempt to resolve this, I included the --copy-files flag in the build script, which successful copied the CSS files but also ...