Mastering the settimeout function for rotating a cube in three.js: Best practices and tips

I am currently developing a program that will rotate a cube based on quaternion data inputted by the user via a CSV file in an HTML format. The JavaScript code cycles through each quaternion in the dataset, applying them to the cube at regular intervals to create a smooth rotation effect of 60 frames per second. To achieve this, I have utilized the setTimeout function in my code.

Below is the snippet of JavaScript code that I've implemented:


    <script>

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    var geometry = new THREE.BoxGeometry(1, 1, 1);
    var material = new THREE.MeshBasicMaterial({ color: 0x00ff70 });
    var cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

    camera.position.z = 5;
    renderer.render(scene, camera);

    var animate = function() {

        quat_data = [];

        var rotate = function(quat) {
            cube.applyQuaternion(quat);
        }

        for (i = 0; i < quat_data.length; i++) {
            time = 16.7;
            var next_quat = quat_data[i];
            setTimeout(rotate(next_quat), time);
        }

    }

    </script>

To trigger the animation process, the user simply clicks a button located at the top of the browser display. Note that the quat_data variable is currently empty. In order to test the functionality of the script, I manually populated it with sample quaternions. However, once I implement the feature to convert and use quaternions from the inputted CSV file, the manual data insertion will be replaced.

The primary issue I'm facing is that although the cube is displayed correctly on running the program, it doesn't rotate as intended despite having appropriate quaternions for rotation. Despite checking console logs for errors, I haven't been able to diagnose the problem. I attempted including 'renderer.render(scene, camera);' at various points within the code, but this didn't address the rotation issue.

If anyone can suggest changes to the animate function to ensure the cube re-renders after each quaternion application or if there's a superior approach using requestAnimationFrame - your guidance would be greatly appreciated.

Answer №1

To start off, it's important to include the renderer.render(scene,camera); inside the rotate function because when adjusting the cube's orientation, the scene needs to be re-rendered.

Another key point is that the way you are using the setTimeout function is incorrect. For a delay of 16.7, 33.4, 50.1 ... milliseconds before calling the rotate function, you should adjust the time passed accordingly. Furthermore, instead of directly calling the function, consider passing a callback function as shown below -

let time = 0;
 for(let i=0; i<quat_data.length; i++) {
     time += 16.7;
     setTimeout(function() { 
         rotate(quat_data[i])
     }, time);
 }

Lastly, it's recommended to steer clear of using the setTimeout function for animation and opt for window.requestAnimationFrame instead. This function is invoked by the browser prior to the next repaint cycle, enabling you to modify the cube's orientation within this function and render the scene. See the code snippet below for a sample implementation -

let i= 0;
var animate = function () {
    requestAnimationFrame( animate );

    i++;
    if (i >= quat_data.length)
        i = quat_data.length - 1;

    let quat = quat_data[i];
    cube.applyQuaternion(quat);

    renderer.render( scene, camera );
};

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

Accessing Route Parameters from Any Component

If my URL follows this structure: /blog/[post_id]/something What's the best practice for passing $post_id to any component within the tree? I'm familiar with retrieving route parameters using getInitialProps, but I struggle with passing values ...

scroll both horizontally and vertically

I came across a tutorial on creating a scrolling page using jQuery and I followed it successfully for horizontal scrolling. However, I'm now wondering if it's possible to implement both horizontal and vertical scrolling on the same page. For in ...

Use CSS specifically for codeigniter viewpage

I am unsure if it is possible, but I would like to load CSS and JavaScript within a view page instead of on include.php. Currently, the CSS file is loading on include.php and it is working correctly. What I want to achieve now is to load it directly inside ...

"Provide information, then open a new webpage by clicking on a button. Perform various actions with the form by using type

Is there a way to quickly submit form entries to my database and then automatically redirect to a new page? My current situation requires that submitted information is stored in the DB before directing users to a thank you page, all in one seamless click! ...

Is there a method in AngularJS to submit form data when the input fields are pre-populated using a GET request?

How do I submit form data in AngularJS? I have a div that populates the input field from a GET request. Now, I want to send this data using a POST method. How can I achieve this? Below is the form div: <div class="row" ng-app="myApp" ng-controller="myC ...

Selecting an object dynamically to add a new property in JavaScript

I am faced with a scenario where I have two objects and I need to add new properties to them. The challenge is that I want to be able to choose which object to work with first before adding the new properties. Here's the proposed logic : let customiz ...

Unable to include a controller in an Angular project generated by Yeoman

I'm currently utilizing the Yeoman scaffolding to develop an Angular application and I'm encountering some difficulties when trying to add a controller. The about and main controllers are automatically added and function properly. However, whenev ...

The error message you are encountering is: "Error: Unable to find function axios

Can't figure out why I'm encountering this error message: TypeError: axios.get is not functioning properly 4 | 5 | export const getTotalPayout = async (userId: string) => { > 6 | const response = await axios.get(`${endpoint}ge ...

React is unable to identify the `activeKey` property on a DOM element

First and foremost, I am aware that there have been a few inquiries regarding this particular error, although stemming from differing sources. Below is the snippet of my code: <BrowserRouter> <React.Fragment> <Navbar className=& ...

Vue.js framework is experiencing an issue where button click events are not firing as expected

I am working with two files here. One is an HTML file that contains the button definition, and the other is a JavaScript file that implements the button event using the Vue.js framework. The concept behind this example is that when the button is clicked, a ...

Ways to verify browser rollover support (as some mobile devices lack a cursor)

I am currently exploring options to determine if rollover events are supported for navigation. If not, I plan to switch to click events. I have reviewed jQuery.Support and Modernizr but haven't come across anything that directly addresses my issue. T ...

Searching for the index of an element in an array using JavaScript

I am working with an array where each element is another array: var array = [ [0,1], [0,2], [0,3], [0,0] ]; However, when I try to use the indexOf method on this array like so: array.indexOf([0,1]); it returns -1. ...

Update the available choices in one select field based on the choice made in another

I am working on a feature where users can select their country, either USA or Canada. Currently, I have all the American states listed in one dropdown menu. However, I want this dropdown to change to display Canadian provinces when users select Canada. Bel ...

What is the best way to specify svg attributes in virtual-dom?

Can attributes be added to SVG nodes using virtual-hyperscript in a virtual dom? Like this: var h = require('virtual-dom/h') h('svg', [ h('circle', {cx: 100, cy: 100}, 'some text') ]) I attempted this but the ...

The profound responsiveness of properties in Vue.js components

I am working on creating a basic page builder that includes row elements, their child column elements, and finally the component that needs to be called. To accomplish this, I have designed an architecture where the dataset is defined in the root component ...

What could be causing the Javascript redirect code to malfunction in Internet Explorer 8?

My JavaScript code redirects users successfully in FireFox and Chrome browsers, but it does not seem to work in IE8. window.location ="/public/index/offer?act=search"; I would appreciate any assistance with this issue. Thank you. ...

Printing log statements in iWebInspector

Has anyone figured out how to get console.log() calls working in the remote debugging tool when using iWebInspector or Safari with PhoneGap 1.4.1? It seems that console calls only show up in XCode, indicating that phonegap may be altering the console&apos ...

When JavaScript is used to create HTML elements, they mysteriously vanish

I've encountered another issue after resolving the previous one XML file reading problem: always the same result While dynamically creating HTML elements and assigning values read from an XML file, the elements disappear right after creation. Any in ...

Utilize vuex v-model to define the value of an object component

Coordinating input elements with object keys in Vuex state is my current challenge. Imagine I have this object: myObj: { foo: 1, bar: 2 } Within a component, I have a computed property set up like so: myObjVals: { get(){ return this.$store.state.myObj ...

Automatically bundle and release an NPM package using the libnpm library

My goal is to automate publishing to NPM within my CI/build system. I came across libnpmpublish, which appears to be the right tool for the job. However, it clearly states that it does not package code into a tarball, even though the publish API requires a ...