When the mouse is clicked, stop the rotation tween and start the tween effect

I have a rotating object on the z-axis. When the mouse is clicked (onMouseDown), the rotation stops, and when the mouse is released (onMouseUp), the rotation resumes after a 2-second delay. Is there a way to make the rotation resume slowly, like easing in for CSS?

Here is the code snippet for starting and stopping the rotation:

if (etaj1 !== undefined) {
    etaj1.rotation.z += delta * 0;
    if (!isMouseDown){
        etaj1.rotation.z += delta * 0.05 ;
    }
}

Additionally, there is a condition for resetting the timer if a new click occurs before the 2-second delay:

var timerHandle = setTimeout(wait, 2000);
function resetTimer() {
    window.clearTimeout(timerHandle);
    timerHandle = setTimeout(wait, 2000);
}

function onMouseDown(){
    console.log("Mouse DOWN");
    isMouseDown = true;               
}

function onMouseUp(){                   
    window.clearTimeout(timerHandle);
    timerHandle = setTimeout(wait, 2000);                 
}

function wait (){
    resetTimer;
    console.log("Mouse UP");
    isMouseDown = false;
}

The objective is to create transitions for isMouseDown = false; and isMouseDown = true;.

Essentially, I want to halt the rotation of the object with a quart.out tween, wait for 2 seconds, and then resume the rotation smoothly with a quart.in tween.

You can view the animation example at the following link:

Thank you.

Answer №1

Although I am not well-versed in three.js, the concept you are inquiring about can be applied to various other areas. Here is a general solution that I will outline for you. To begin with, here is a proof of concept:

https://jsfiddle.net/ibowankenobi/u4xwnLam/4/

I will start by declaring the necessary global variables and encapsulating them as needed:

var rotation = 0;
var bar = document.getElementById("bar");
var container = document.getElementById("container");

For the demonstration without three.js, a container and an object to rotate are required. In your context, the object being rotated would correspond to etaj1.rotation.z.

The initial step involves creating a function that maps values from 0-1 to 0-1 non-linearly through interpolations. The commonly used interpolation method tends to provide a "slow in slow out" effect:

 function slowInSlowOut(t){
    if(2*t<<0){
        return 4*(t-1)*(t-1)*(t-1)+1;
    } else {
        return 4*t*t*t;
    }
}

To further utilize this function, another animation function needs to be written:

function changeSpeed(obj,newSpeed){
    var oldSpeed = obj.__oldSpeed || 0;
    var startTime;
    newSpeed = newSpeed || 0;
    obj.__currentFrame && window.cancelAnimationFrame(obj.__currentFrame);
    obj.__currentFrame = window.requestAnimationFrame(anim);
    function anim(t){
        startTime = startTime || t;
        var elapsed = t - startTime,
            parametric = slowInSlowOut(elapsed/2000);
        if(parametric>=1){
            obj.__oldSpeed = newSpeed;
        } else {
            obj.__oldSpeed = newSpeed + (oldSpeed-newSpeed) * (1-parametric);
            obj.__currentFrame = window.requestAnimationFrame(anim);
        }
    }
}

This function enables an object to have a custom property named __oldSpeed. The parameter newSpeed signifies degrees per 17ms intervals. In your case, the object would be represented by etaj1.

In order to continuously monitor the __oldSpeed property of the object and take relevant action, a third function is developed:

function animate(obj){
    rotation += (obj.__oldSpeed || 0);
    rotation = rotation % 360;
    obj.style.transform = "rotate("+rotation+"deg)";
    window.requestAnimationFrame(function(){animate(obj)});
}

Here, the object refers to etaj1 and the rotation corresponds to etaj1.rotation.z. Using DOM manipulation demands the use of styles, which can be adapted according to your specific scenario.

To trigger the animation, it must be initiated:

window.requestAnimationFrame(function(){animate(bar)});

Subsequently, event listeners can be added as per your specifications:

container.addEventListener("mousedown",function(){changeSpeed(bar,0)},false);
container.addEventListener("mouseup",function(){changeSpeed(bar,12)},false);

An initial speed value is assigned to kickstart the process:

changeSpeed(bar,12);

This setup should provide you with a starting point on how to achieve the desired outcome. Users employing different technology stacks may also adapt this approach to suit their requirements.

PS:

If there is a need for a delay, slight modifications can be made to the changeSpeed function:

function changeSpeed(obj,newSpeed,delay){
    delay = delay || 0;
    var oldSpeed = obj.__oldSpeed || 0;
    var startTime;
    newSpeed = newSpeed || 0;
    obj.__currentFrame && window.cancelAnimationFrame(obj.__currentFrame);
    obj.__currentFrame = window.requestAnimationFrame(anim);
    function anim(t){
        startTime = startTime || t;
        var elapsed = t - startTime;
    if(elapsed < delay) {
       return obj.__currentFrame = window.requestAnimationFrame(anim);
    }
        var parametric = slowInSlowOut((elapsed-delay)/2000);
        if(parametric>=1){
            obj.__oldSpeed = newSpeed;
        } else {
            obj.__oldSpeed = newSpeed + (oldSpeed-newSpeed) * (1-parametric);
            obj.__currentFrame = window.requestAnimationFrame(anim);
        }
    }
}

A sample implementation with a 2-second delay can be found in this fiddle:

https://jsfiddle.net/ibowankenobi/u4xwnLam/10/

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

Retrieving JSON information using Ajax to enhance Cytoscape visualization

Looking to share a network using Cytoscape web or, if possible, cytoscape.js. Due to the size of my data, I find it easier to export it from Cytoscape desktop and grab it using ajax in my HTML. Previously, before version 3.1.0 of Cytoscape, I could export ...

Updating the Model in Angular 2: A Step-by-Step Guide

When receiving a data model through a service: return this.http.get(queryUrl, opts) .map((response: Response) => { return (<any>response.json()).data.map(el => { return new User({ id: item.id, name : item.name ...

Different methods to obscure solely URLs in AngularJS

Is there a way to effectively obfuscate URLs in AngularJS? Currently, I am using base 64 encoding as a method of obscuring my URLs. For example, let's say my URL is: I encode and decode it like this: aHR0cDovLzE5Mi4wLjAuMC9teS91cmwv However, when ...

Modify the data in the local storage and showcase it on the webpage without the need to refresh the page

Currently, I am working on a project using Angular 8. One of the issues I am facing is with a variable called 'cartproductitems'. I want this variable to update automatically whenever a user adds a new product to the cart, so that the number of i ...

The directives for ion-slide-page within ion-slides are experiencing rendering issues

Currently, I am working on an Ionic App (using an Ionic 1 codebase) and trying to incorporate the ion-slides/ion-slide-page directives into a page. However, I am facing difficulty in getting each individual ion-slide-page directive to sit horizontally next ...

Utilizing Ternary Operators with User Input

In my latest project, I am developing a cutting-edge app that converts text to sound, utilizing input text from react-native-elements along with ternary operators. My main challenge now is figuring out how to validate whether the text input box is empty ...

Leveraging Dynamic Information within a Regex Pattern

I have a unique collection that appears as follows: listA = ["Physics","English","Chemistry","Biology","History","Human Values","None"] The website displays a textArea for users to input data like :- Hello, I really enjoy studying <<English>&g ...

Utilize the v-if directive with nested object properties for dynamic conditional rendering

I need to verify if the item object has a property called 'url' set. If it's not present, I would like to display a placeholder image. Here is an example of what I want to achieve: <img v-if="item.relationships.main ...

The search box output will be the same as the JSON result

I have a server in Node.js that is able to read and process a JSON file containing various data, including unique user IDs. I have incorporated a search box into my HTML page, and I am seeking assistance with creating a jQuery method (which will require AJ ...

Displaying JSON data received from an AJAX request on the screen

Our server is located in Europe. Occasionally, a user based in America reports an issue when using the $.getJSON function. Instead of passing the JSON response to JavaScript, the user's browser simply displays it. The AJAX call appears as follows: ...

Oops! There seems to be an issue with trying to access the 'map' property of undefined within the render method

While working on my project, I encountered an issue with a table from react material ui. The problem arises when attempting to populate the table with data from the state, resulting in an error message stating "cannot read property 'map' of undef ...

Swap the comma for a period as you type out jQuery code

Hey there, I'm trying to figure out how to use jQuery to replace a comma with a dot while typing in a text input field. Currently, my code looks like this: $(document).on('change', '.unitprice', function() { $(this).val().replac ...

Is the zero-height navigation bar still apparent on the screen?

I am currently working on a portfolio website and I have a specific idea in mind for how I want the work to be displayed. I would like it to slide up onto the screen when the user clicks on the portfolio section, similar to how a navigation bar slides over ...

What is the method for incorporating custom or outdated attributes into styled-components?

I'm currently working on a tool to create newsletters. This requires me to utilize many outdated HTML4/XHTML1 tags and attributes. For instance, I aim to generate an element like the following: <table align="center" cellpadding="0&qu ...

Having trouble installing Moment and Material Moment Adapter in Angular?

To customize the date format in datepicker controls, I need to have both Material and Material-Moment-Adapter installed. Here is how I installed moment: npm install moment --save And for Material-Moment-Adapter: npm i @angular/material-moment-adapter How ...

Zurb Foundation's sections have a strange issue where navigating between them introduces unexpected whitespace

I'm feeling frustrated as I try to work with Zurb Foundation sections. I've updated to the latest version 4.3.1. Following the documentation provided here: but encountering strange behavior while navigating through results. Refer to the screen ...

Easily load events into a responsive calendar widget with w3widgets. No

When attempting to load events dynamically, I encountered an issue where the output was not displaying correctly. I used AJAX to retrieve data in the following format: var datalist = "2015-09-22":{} $(".responsive-calendar").responsiveCalendar({ eve ...

Different Techniques for Defining Functions in an AngularJS Controller Using the controllerAs Method

When using the 'controller as' approach instead of $scope, I am encountering issues with method calling from HTML. My question is, how many ways are there to declare and call functions using this approach? First: (For executing something initial ...

The issue arises when attempting to format the date in React before passing it as a parameter in the API

Issue with passing date time value as URL parameter to backend Java API via GET method. The API is only receiving part of the date time string, with the rest being cut off. My React code: const handleStartDate = date => { setStartDate(date); ...

Invoke the ngrx component store's Effect in a synchronous manner

In the ComponentStore of ngrx, we have two effects. readonly startAndUpdateProgress = this.effect<void>( (trigger$) => trigger$.pipe( exhaustMap(() => this.numbersObservable.pipe( tapResponse({ next: (p ...