Expanding the size of a Three.js geometry in one direction

I've been experimenting with scaling geometries on the y-axis, but I've run into an issue where my cube scales both up and down. I found that using mesh.transformY to animate the cube up by half of the scaling value can create the illusion of the cube scaling only upwards. I'm curious if there are other methods to achieve this effect?


    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var mesh = new THREE.Mesh(geometry, new THREE.MeshPhongMaterial({
        color: 0xffffff
    }));

    mesh.position.set(0, 2, 0);
    mesh.scale.set(0.98, 0.95, 0.992);
    mesh.castShadow = true;
    scene.add(mesh);

    var tween = new TWEEN.Tween(mesh.scale);
    tween.to({y: 2}, 1000);
    tween.easing(TWEEN.Easing.Elastic.InOut);
    tween.yoyo(true);
    tween.start();

Answer №1

If you're looking to only scale your geometric shape "upwards", simply ensure that the "bottom" of the shape goes through the origin point. In this scenario, you can achieve this by using the translate() method as shown below:

let shape = new THREE.SphereGeometry( 1, 32, 32 );
shape.translate( 0, 0.5, 0 );

let animation = new TWEEN.Tween( object.scale ).to( { y: 2 }, 1000 );
animation.start();

By following this method, the base of the sphere will stay fixed while its height increases.

Utilizing three.js version r.73

Answer №2

When considering a situation where your question pertains to an object existing on a 'ground', such as a 'person' model, it is essential for it to remain grounded regardless of its size. There are two methods to achieve this:

  • One approach, as suggested by Evilzebra in the comment, involves adjusting the mesh's position based on its height. By scaling the mesh in the vertical direction, you can ensure that it maintains its position relative to the ground. This can be achieved by calculating the new position using the formula: height * scale / 2. The following function demonstrates how this can be implemented:

    function scaleY ( mesh, scale ) {
        mesh.scale.y = scale ;
        if( ! mesh.geometry.boundingBox ) mesh.geometry.computeBoundingBox();
        var height = mesh.geometry.boundingBox.max.y - mesh.geometry.boundingBox.min.y;
        
        mesh.position.y = height * scale / 2 ;
    }
    
  • Alternatively, another method involves shifting the origin of the coordinates (local space) to the bottom of the geometry. This allows you to adjust the scale without affecting the position. By aligning the origin with the lowest y coordinate, you can easily modify the scale using ThreeJS's native methods. The following function demonstrates how to move the origin to the bottom of the geometry:

    function originToBottom ( geometry ) {
        var shift = geometry.boundingBox ? geometry.boundingBox.min.y : geometry.computeBoundingBox().min.y;
    
        for ( var i = 0 ; i < geometry.vertices.length ; i++ ) {
            geometry.vertices[ i ].y -= shift;
        }
        
        geometry.translate( 0, -shift, 0);
    
        geometry.verticesNeedUpdate = true;
    }
    

Answer №3

In my case, I found this to be the top result on Google when searching for how to scale a geometry. Let me share the function I use to modify a geometry.

function _alterGeometry(geometry, options) {

    var transformations = [];

    var matrixMultiplier = function (matrices) {
        var matrix = new THREE.Matrix4();
        matrices.forEach(function (m, index) {
            matrix = new THREE.Matrix4().multiplyMatrices(matrix, m);
        });
        return matrix;
    };

    if (options.position)
        transformations.push(new THREE.Matrix4().setPosition(new THREE.Vector3(options.position.x, options.position.y, options.position.z)));

    if (options.rotation && options.rotation.x)
        transformations.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0), options.rotation.x));

    if (options.rotation && options.rotation.y)
        transformations.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0), options.rotation.y));

    if (options.rotation && options.rotation.z)
        transformations.push(new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1), options.rotation.z));

    if (options.scale)
        transformations.push(new THREE.Matrix4().scale(options.scale));

    geometry.applyMatrix(matrixMultiplier(transformations));
    return geometry;

}

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

Setting up an event listener for a newly added list through the use of node appendChild

I am currently working on dynamically adding a select list to my HTML document. While I have successfully added the node to the DOM, I am struggling with creating an event listener in a separate JavaScript file that recognizes the newly created select list ...

The function window.addEventListener('load') functions properly on desktop computers, but does not work on mobile devices

After developing a react website, I noticed that it functions correctly on PC but not on Mobile devices. componentDidMount() { window.addEventListener('scroll', this.onScroll); // This event works fine window.addEventListener('load&a ...

Choose a particular text node from the element that has been selected

Can anyone provide guidance on how to extract the text "Items Description" from the following HTML snippet using jQuery? <div class="items"> "Items Description" <ul> <li>1. One</li> <li>2. Two</li&g ...

Accepting multiple file inputs in a form without using a selector, but instead utilizing the 'this' keyword or finding an alternative approach

When dealing with single file uploads, you can access the file input using this.image <form id="form"> <input type="file" name="image"> <input type="submit" name="submit"> </form> $ ...

What could be causing my GET route to return an empty array?

I've been attempting to retrieve an event by its id, but for some reason, I'm receiving an empty array as a result in Postman. Below is the code snippet of my route: import { events } from '../../../db.json'; const handler = async (re ...

When I click a button in d3 to refresh the data on my bar graph, the text fails to update accordingly

I've successfully created a series of data lists that modify the bargraph. Unfortunately, due to their differing x and y values, they end up printing new values on top of existing ones. Shown below is an image illustrating the issue where x and y val ...

Providing input to a nested mongoose query

I can't figure out why I keep experiencing 504 Gateway timeouts. app.get("/api/exercise/log", function(req,res) { let userId = req.query.userId; let from = req.query.from; let to = req.query.to; let limit = req.query.limit; console.log("lim ...

Display the table upon completion of the form submission

I am trying to create a form where the table #mytable is only displayed after the form has been submitted. If nothing is entered in the form, the table should remain hidden. Any suggestions on how I can achieve this? <form action="" id="myform" method ...

What steps should I take to export a function from a React functional component in order to create a reusable library?

Currently, I am in the midst of developing a React component library and one of my components contains a function that I want to export. The purpose of the addParticle function is to enable users of the library to dynamically insert particles into a cont ...

A step-by-step guide to invoking a function upon submitting a form with an external JavaScript file

How can I execute a function when the user submits a form using an external JavaScript file? index.html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>example</title> ...

Template displaying multiple polymer variables side by side

Here is the date object I am working with: date = { day: '05' } When I use this code: <div>{{date.day}}</div> It generates the following HTML output: <div>05</div> Everything looks good so far. Now, I want to try th ...

Implementing watch functionality with array in Vuejs for bidirectional communication between parent and child components

Here is a simplified version of a parent component I created: // parent component <template> <layout v-for="(value, idx) in array" :pickUpLength="array.length" :idx="idx" :key="idx" > <button @click="addArray">a ...

Having trouble displaying the selected button in React

Is it possible to include multiple functions within an onclick event? Check out the code snippet below: import React from 'react'; class Counter extends React.Component { state = { count: 0, inc: 'Increment', ...

Tips on how to modify database records rather than generating new ones

Currently, my team is developing a web application that utilizes wearables to monitor vital parameters. As part of our integration testing, we are using a Fitbit device. The app itself is built with Angular and JavaScript, while the database is hosted on C ...

Handling JSON Data in JavaScript

In the script below, I have a json object that is being processed: $http({ url: '/mpdValidation/mpdValidate', method: "POST", data: { 'message' : mpdData } ).then(function(response) { console.log(response.data ...

"Typescript: Unraveling the Depths of Nested

Having trouble looping through nested arrays in a function that returns a statement. selectInputFilter(enteredText, filter) { if (this.searchType === 3) { return (enteredText['actors'][0]['surname'].toLocaleLowerCase().ind ...

JavaScript event/Rails app encounters surprising outcome

I have encountered a strange bug in my JavaScript code. When I translate the page to another language by clicking on "English | Русский" using simple I18n translation, my menu buttons stop working until I reload the page. I suspect that the issue ...

What is the process for forming a series of arrays from one singular array?

If I have a large array consisting of numbers from 1 to 18, is there a simple method to split it into pairs like [1,2], [3,4], [5,6], [7,8], [9,10], [11,12], [13,14] for n=2? The special case of n=2 is all I need. ...

Button cannot be activated upon selecting a row

The goal is to activate a button when a row is selected. However, the button remains disabled even after selecting a row. Below is a snippet of the code as well as a screenshot showing the issue [error_1]: onInit: function () { var oViewMode ...

How can I maintain the consistent speed of the Javascript timer even when the .deck is clicked?

Currently, I'm working on creating a memory card game. In this game, the deck of cards is represented by the class .deck. Strangely enough, every time I click on a card, the timer starts to speed up instead of keeping a consistent pace. How can I tack ...