Generate seamless rotation within a specified time frame (+- x%)

I need to rotate a cube in my scene with a specific initial speed within a specified timeframe.
The end angle of the cube must match the starting angle. To account for potential variations, I am allowing for a deviation of up to 5% in the timeframe.

Currently, here is the status of my project: http://jsfiddle.net/5NWab/1/.
Everything is working as expected at the moment. However, if I alter the timeframe, for example to '3000': http://jsfiddle.net/5NWab/2/.

The crucial move() method of my cube is as follows:

Reel.prototype.move = function (delta) {
    if (this.velocity < 0 && this.mesh.rotation.x == 0) {
        return false;
    }

    // Create smooth end rotation
    if (this.velocity < 0 && this.mesh.rotation.x != 0) {
        this.mesh.rotation.x += Math.abs(delta * this.speedUp * 0.5 * this.timeSpan);
        if (Math.abs(this.mesh.rotation.x - 2 * Math.PI) < 0.1) {
            this.mesh.rotation.x = 0;
        }
    }

    else {
        this.mesh.rotation.x += delta * this.velocity;

        this.time -= delta;
        this.velocity = this.speedUp * this.time;
    }
}

I am struggling to find a solution or method to achieve the desired outcome. The challenge would be much easier if the delta variable remained constant.
Ideally, it should be around 60fps = 1000/60 due to my use of requestAnimationFrame().

I came across this question which may provide some insight.

I believe the code needs to either

  • slow down the rotation before reaching the desired angle, especially if the final angle is slightly greater than the intended starting angle.

  • or speed up the rotation after surpassing the desired angle, particularly if the final angle is slightly less than the intended starting angle.

But how should it behave if the angle is exactly halfway from the desired one (e.g. 180° or PI)?

To clarify, here are the variables I know and those I am still unsure about:

Known:

  • Initial speed
  • Time interval
  • Starting angle (usually 0)

The goal is for the cube to return to its initial angle/position by the end of the rotation. Given the fluctuating FPS count, adjusting the time interval may be necessary to achieve the desired position for the cube.

Answer №1

For precise control over the rotation ending at a specific angle and time, it is recommended to set the target time and rotation during the animation initialization instead of continuously decreasing the rotation as shown in your current code. To calculate the correct rotation for each frame recalculation, consider using a sine-shaped speed curve for smooth easing in and out.

// Initializing
var targetTime = now + animationTime;
var timeFactor = Math.PI / animationTime;
var startAngle = ...
var endAngle = ...
var angleChange = endAngle - startAngle;

// During animation
var remainingT = targetTime - t;
if (remainingT <= 0) {
    var angle = endAngle;
} else {
    var angle = startAngle + Math.cos(remainingT * timeFactor) * angleChange;
}

[Edited to include startAngle in angle calculation]

The cosine function being symmetric, as t nears targetTime, the angle moves from pi back to 0 on the curve resulting in an easing effect at the end. Any framerate fluctuations are accounted for by explicitly setting the angle to zero at or past the targetTime to prevent an infinite loop.

Answer №2

One approach that could be considered is to gradually reduce the speed based on the remaining time, although it may not be optimal: http://jsfiddle.net/5NWab/8/

The concept involves decreasing the speed in relation to the remaining time until the cube needs to rotate back to its original position (0). Once the distance the cube needs to rotate exceeds the potential rotation based on current velocity and remaining time, the focus shifts to slowing down the velocity proportionally to the remaining rotation without considering the time left.

While this method is effective for certain time intervals, it may result in a slower ending animation for other cases.

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

Go to a different webpage containing HTML and update the image source on that particular page

I am facing an issue with my html page which contains multiple links to another page. I need to dynamically change the image references on the landing page based on the link the user clicks. The challenge here is that the link is inside an iframe and trigg ...

What is the best way to incorporate Drift bot JS code into a static React NextJs application, such as a landing page?

I'm a beginner with ReactJS and I recently created a static website using ReactJS & NextJs. I decided to integrate a chatbot called 'Drift', but when following the installation instructions to insert JavaScript code in the <head> of HT ...

When information is provided, record the values in a separate input field

I'm struggling to come up with an appropriate title... Here's the issue: if a user inputs anything into the "Accompanying Person" field, the "Accompanying Person Price" field will automatically be set to 260€. I have no clue on how to achieve ...

Make sure to execute a function prior to the ajax beforeSend

Before I upload a file using 'fileuploader', I attempted to check the file first in my beforeSend function: beforeSend: function(item, listEl, parentEl, newInputEl, inputEl) { var file = item.file; let readfile = functio ...

Verification is required for additional elements within the div block once a single checkbox has been selected

Currently, I am working in PHP using the CodeIgniter framework. I have a question regarding implementing a functionality with checkboxes and validation using jQuery. Here is the scenario I want to achieve: There are four checkboxes, and when one checkbox ...

Basic use of AJAX for sending the value from jQuery's datepicker

As a novice in JavaScript and AJAX, I'm hoping for your patience as I navigate my way through. In the scope of this project, I am utilizing the CodeIgniter framework. My objective is to implement a datepicker and transmit its value via AJAX. Below is ...

Creating a dynamic form field using JavaScript

I'm struggling with a JavaScript issue that requires some assistance. I have a form sending an exact number of inputs to be filled to a PHP file, and now I want to create a preview using jQuery or JavaScript. The challenge lies in dynamically capturin ...

Is there a Page Views tracker in sinatra?

Help needed with implementing a page views counter using Sinatra and Ruby. I attempted using the @@ variables, but they keep resetting to zero every time the page is reloaded... Here's an example: Appreciate any advice! ...

The functionality of the slick slider seems to be malfunctioning

I've been trying to integrate the slick slider into my website, but it just won't work. I've double-checked everything multiple times, but I can't seem to find the issue. It's driving me crazy! If anyone can help me identify the pr ...

Preventing input in one textbox if another textbox has a filled value in HTML

Apologies for asking this question, but is there a way to disable one text box if another text box has a value? I've attempted using the following code, but it doesn't seem to work. Sorry for the inexperienced inquiry T_T function disableTextbox ...

Exploring the Depths of Google Chrome: Unleashing the Power of

While a similar question has been posed previously, I am encountering difficulties debugging Javascript in Google Chrome. When I navigate to Page > Developer, the "Debug Javascript" function (Ctrl+Shift+L) is not active. Even trying Alt + ` does not se ...

EJS: Dynamically linking CSS and JS files according to specific page conditions

Is there a way to conditionally call CSS/JS files based on specific page conditions in EJS? Can we use a flag from the router or base it on the URL in the EJS file? Note: The code below works perfectly when accessing the /editor page, but it will cause er ...

Creating a unique WooCommerce product category dropdown shortcode for your website

I am having trouble implementing a WooCommerce categories dropdown shortcode. Although I can see the drop-down menu, selecting a category does not seem to trigger any action. Shortcode: [product_categories_dropdown orderby="title" count="0" hierarchical=" ...

If I click on a different VueJS menu, make sure to close the current menu

When using a component menu, each item is displayed independently. However, I would like the open items to close automatically when I click on another item with the menu. I employ a toggle functionality on click to control the opening and closing of the c ...

What steps can be taken to resolve the error message: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data?

I'm facing an issue while trying to retrieve data for my map using an AJAX call. The error message I receive is: SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON data. Interestingly, two previous datasets in my applicatio ...

"Utilizing the v-autocomplete component with on-select and on-remove events in Vuet

Are there any on-select or on-remove properties available in v-autocomplete from Vuetify? I need to manually handle these events. I have tried using @change, but it does not inform me whether an option has been added or removed. <v-autocomplete : ...

Is it possible for me to reconstruct the "reducer" each time the useReducer hook is rendered?

Here is an example taken from: https://reactjs.org/docs/hooks-reference.html#usereducer const initialState = {count: 0}; function reducer(state, action) { switch (action.type) { case 'increment': return {count: state.count + 1}; ...

JS script for clicking various icons on a webpage that trigger the opening of new tabs

I am working on a webpage where I have 9 icons with the same class. I am trying to write JavaScript code that will automatically open all 9 icons when the webpage loads. I tried using the code below, but it only clicks on the first icon and stops. let ...

Fetch information from the input field and send it to the Redux state

Looking for a solution - I'm working on a simple todo app where I need to store user input value in the redux state. The input value is currently stored in local state until the user clicks the "add" button. The main issue : How can I pass this input ...

Tips for correcting a React (functional component) error: "Signup Error: TypeError: Cannot read properties of null (reading 'protocol')"

My partner and I successfully developed a complex multi-step registration form that displays all user input data at the end. However, when the user tries to submit the form to create their account, an error occurs with the message "Signup Error: TypeErro ...