Having difficulties getting basic cube rolling animations to function properly in three.js

I am a beginner in the world of THREEJS and currently working on moving a cube using arrow keys. Take a look at this fiddle: https://jsfiddle.net/mauricederegt/y6cw7foj/26/

Everything is functional, I can move the cube with arrow keys and even rotate it correctly around the axis. The issue arises with animations. I am struggling to make them work smoothly. Currently, when the left arrow key is pressed, the cube moves to the left and rotates around the axis, but the transition is abrupt instead of fluid.

My goal is to have a smooth transition while the cube moves and rotates. I have included the requestAnimationFrame at the end of the code, but it doesn't seem to solve the issue. I also have a fiddle showcasing my attempt using CSS for animations, where they work but the rotation direction is incorrect: https://jsfiddle.net/mauricederegt/5ozqg9uL/3/ This demonstrates the desired animations.

What am I missing in THREEjs? Any help is greatly appreciated.

Answer №1

In the world of animation, there's a technique known as "tweening," which involves creating intermediary steps between key frames instead of jumping directly to the final result. While there are JavaScript libraries available to handle this for you, I'll walk you through the basics of implementing tweening on your own.

Let's take an example. Imagine that when you press the left arrow key, you want to move a mesh by 1 unit along the -x axis and rotate it by -PI/2 about the +y axis. Instead of making these movements instant, consider breaking them down into smaller steps over a set duration.

For instance, if you want the animation to last for 500ms (half a second) and the browser runs at around 60 frames per second, you can divide the animation into 30 frames (since 60fps equals about 500ms). This means that for each frame, you would move the object by 1/30 units and rotate it by -PI/60. After 30 frames, the object should be close to its intended position.

However, relying solely on the browser's frame rate can lead to variations in speed. To address this issue, you can implement a real timer to handle the animation steps rather than tying them to the browser's rendering cycle.

By breaking the animation into smaller update steps (e.g., 50 steps within the 500ms duration), you can ensure a smoother and more consistent movement. This approach allows you to update the object's position by 1/50 units and rotate it by -PI/100 in each step.

let animationId = setInterval(() => {
  // update position by 1/50 units
  // update rotation by -PI/100
}, 10); // every 10ms

As the interval runs, it will progressively update the object, while the animation loop continues to generate new frames whenever possible.

To see this concept in action, I've provided a complete example below with support for left arrow key input:

// JavaScript code snippet
// Three.js setup for animation
// CSS code snippet
// Styles for HTML elements
<script src="https://threejs.org/build/three.min.js"></script>

While this method offers smoother animations, there may be occasional issues like skipped updates or duplicate frames. To address these concerns, you can dynamically calculate the frame rate during rendering and adjust the step sizes accordingly, although this may impact performance.

Handling Key Input for Directional Changes

With the animation and rendering processes decoupled, you'll need to introduce a flag to indicate the current action based on key inputs. The key press event will set this flag, which the update function will use to determine the appropriate action:

// JavaScript code snippet
// Handling key input and setting action flags

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

Nested scrolling bars within each other

Currently, I am importing photos from a Facebook page and displaying them on my jQuery mobile webpage using the photoSwipe plugin. However, there seems to be an issue with the final appearance of the images. Pay attention to the image where the red arrow ...

Anomalous behavior of buttons in react-redux

Currently, I have a basic counter set up in react-redux as part of my learning process with these frameworks. My goal is to create a pair of number input fields that determine the payload for an increment/decrement action sequence. The intended outcome is ...

Generate a D3.js vertical timeline covering the period from January 1, 2015 to December 31, 2015

I am in need of assistance with creating a vertical timeline using D3.js that spans from the beginning of January 2015 to the end of December 2015. My goal is to have two entries, represented by colored circles, at specific dates within the middle of the t ...

Having difficulty updating the border color of Material UI Input when it is in focused or unfocused state

I can't seem to figure out why this code isn't working as expected. I'm trying to target the MuiInputBase-root element, specify that it should have a blue border by default, and then change the border color to red when focused. Can someone h ...

Adjust the position if the height exceeds 100 pixels

Can someone help with this code issue? $(document).ready(function () { if ($('.pi-img').height() > 100) { $(this).css('top' , '30%'); console.log('yeah'); } }); I am encountering difficu ...

Tips for avoiding a 500 GET error due to an empty request during page loading

I recently encountered an issue with a form containing a dependent drop-down menu that reloads after form submission to preselect the main choice that was made before submission. The problem arises when the page initially loads without any parameters being ...

Tips for setting up Code Coverage in a Cypress environment for testing a NextJS build simultaneously

We are currently exploring the possibility of integrating code coverage into our setup utilizing cypress and nextjs. Within our cypress configuration, we utilize the next() function to mimic backend requests within nextjs. The cypress.config.ts file is st ...

Combining td elements within a table

Currently, I am working on creating a weekly calendar using a combination of JavaScript and PHP to interact with an SQL table. The process involves generating an empty table structure in JavaScript and then populating specific cells with data retrieved fro ...

Is there a discrepancy in performance when running a function on an individual element versus a group of elements within jQuery?

Imagine having the choice between applying a function to an individual DOM element or a list of them: For Individual Elements: $('#element1').click(function () { $(this).hide(); return false; }); $('#element2').click(functi ...

One can pass parameters to a promise's success callback within AngularJS using $q

I have encountered a situation that is similar to the one described in this post, but I am still unsure about how to implement it. I could use some assistance with setting up a successful callback. This is the current functioning code: function getStuff( ...

The problem with the Next.js 14 generateStaticParamsparams parameter is that it is currently

I'm using this documentation as a reference to extract parameters from the URL in my generateStaticParams function: https://nextjs.org/docs/app/api-reference/functions/generate-static-params#generate-params-from-the-bottom-up This is the route I am w ...

Grin schedule module JSON stream

I have integrated a Smile timeline widget on my website and successfully customized it following several tutorials. However, I am struggling to utilize a Json service instead of relying on data stored in a global variable within a JavaScript file. Despite ...

Merge two distinct arrays of objects based on a shared field

I have two arrays of objects that I need to merge, with the expected output as: [ { "scenario": [ { "errorname": "Error 01", "status": 5, "desc_1" : "test", "desc_2" : "testing" }, ...

What is the process for incorporating a new URL into the routes.js file of a preexisting Node.js project that was developed with locomotive?

module.exports = function routes() { this.root('pages#main'); this.match('/status', 'pages#status'); this.resources('paper'); this.resources('tempform'); this.match('/paper/domain', 'pages#n ...

Enter key not triggering submission in jQuery UI autocomplete field

I'm currently working on implementing the autocomplete feature following a tutorial, and while it's functioning, I'm facing an issue with submitting the form when the user selects an item and hits enter. Below is the Coffeescript code that I ...

Exploring the method to retrieve data on the server side through Express when it is shared by the client within a put request

Here is the angular http put request I am working with: sendPutRequest(data) : Observable<any>{ return this.http.put("http://localhost:5050", data).pipe(map(this.handleData)); } After making this call, the server side method being invoked is ...

Importing multiple exports dynamically in Next.js

My current setup involves using a third-party package that I load dynamically in Next.js: const am5 = dynamic(() => import("@amcharts/amcharts5"), {ssr: false}) The imported amcharts5 consists of various exports and imports, such as: export { ...

Is there a way to set up a listener for a particular property of a recoil state object?

Is it possible to create a listener for a specific property within a state object? Let's look at an example: type ExampleAtomProperties = { id: number; description: string; }; const ExampleAtom = atom< ExampleAtomProperties>({ key: &quo ...

Which is the better option for opening a link in a button: using onclick or href?

What is the most effective way to open a link using a button? <button type="button" onclick="location='permalink.php'">Permalink</button> <button type="button" href="index.php">Permalink</button> ...

Trouble with downloading files using the anchor (a) tag in React

Every time I try to click on the a tag to download the file named approved_leads.zip, I keep receiving an error message saying "failed - no file". It seems like the path is correct, so I'm not sure what is causing the issue. <a href="../../ass ...