Issue with Tweening in Three.js: Initial value does not change

Having trouble with tweening my camera position. I've set up a Codepen with minimal code to showcase the issue, complete with annotations and plenty of console.log() statements for debugging purposes.

Check out the Codepen

The starting point of my camera position is:

camera.position.z = 30;

My first tween, tween001:

var tween001 = gsap.to(camera.position,{ delay:2, duration:5, z:60, onUpdate:function(){
    camera.updateProjectionMatrix();
    console.log("play");
  }, onComplete:function(){console.log("complete");}, ease:"elastic"});

So, this tween moves the camera from z=30 to z=60. It works perfectly, but...

If the user interacts with the 3D scene (move, over, click), it triggers an event listener which pauses the tween using "tween001.pause()". I want the tween to use the current camera position when it resumes, rather than the position it had when the tween was initially triggered.

This is because when tween001 is played again or resumed from a pause, it starts from the default position x=0, y=0, z=30.

An idle function is in place to play tween001 again:

window.setInterval(checkTime, 1000); // Check the time every 1 second

function checkTime() {
    if (idlecounter < timeout) { // Increment the counter every second until timeout
        idlecounter++;
    } else if (idlecounter == timeout) { // When timeout is reached, play tween001 again
        tween001.play();
        console.log('timeout');
    }
}

Answer №1

It's important to note that GSAP operates under the assumption that it is the sole controller of the camera.position. When you set

gsap.to(camera.position, {z: 60})
, GSAP internally records the starting position (30) and the target position (60) to create its timeline. This means that GSAP is unaware of any changes made to the z-position via mousewheel scrolling. Consequently, when you call .play(), GSAP will still try to animate from 30 to 60.

To address this, you need to create a new tween each time to ensure that GSAP picks up the updated starting position for replay:

var tween001;
function doTween() {
    tween001 = gsap.to(camera.position, { delay:2, duration:5, z:60, ease:"elastic", onComplete:function(){
      // camera.updateProjectionMatrix();
      console.log("complete");
    }});
}
  • It's worth noting that I declared var tween001 globally outside the function so that you can easily pause it using tween001.pause() when needed.
  • Updating the projection matrix is unnecessary when adjusting position.

When you're ready to restart the animation, instead of using tween001.play(), you should call doTween() to generate a new timeline that considers the camera's current z-position for the animation start:

// ...
else if (idlecounter == timeout) {
    doTween();
    idlecounter = 0;
}

Check out the updated codepen here

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

Encountering an error where property 'onClicked' is not defined when attempting to utilize chrome.action or chrome.browserAction in Chrome

I am currently developing a Chrome extension that will automatically redirect me to a specific URL when I click on the browser action icon. Here is the code snippet that I am trying to implement: chrome.browserAction.onClicked.addListener However, I am ...

The functionality of the Jquery mobile panel ceases to work properly when navigating between pages within a multi-page

Within a multi-page template setup in a jQuery mobile application, an issue arises after navigating away from the first page using panel navigation. Upon returning to the first page through another form of navigation, the panel appears "hanged." Upon clos ...

Tips for avoiding flickering in a background image when it is being changed

Utilizing JavaScript, I am setting a repeated background image from a canvas to a div in the following way: var img_canvas = document.createElement('canvas'); img_canvas.width = 16; img_canvas.height = 16; img_canvas.getContext('2d' ...

Tips for avoiding event listeners from being triggered multiple times

Implemented an event listener on an HTML element that was retrieved by className within the render method of highcharts, but for some reason, the listener is being triggered twice. The issue seems to be with the onClick handler in the highchart's rend ...

Inspect JavaScript files on your mobile or tablet device

Looking to view JavaScript code on a mobile or tablet device? With Chrome browser, simply click the F12 key and navigate to the sources tab. ...

The jQuery find and replace feature is causing my entire content to be replaced instead of just specific paragraphs

Within this section, there are multiple paragraphs and an input field. The concept is simple: the user inputs text into the box, then hits "ENTER" to trigger a jquery function below. The process involves identifying matches between the paragraph content a ...

Discover how to prevent a link or text from appearing if a user has already browsed a particular webpage

Is there a way to hide a link to another page if the user has previously visited that page? For example, I have 3 options - A, B, and C. If a user selects option A, links to pages B and C are displayed at the bottom of the page. However, if they then navi ...

Having difficulty using the forEach() method to loop through the array generated by my API

During my troubleshooting process with console.log/debugger, I discovered that I am encountering an issue when attempting to iterate over the API generated array in the addListItem function's forEach method call. Interestingly, the pokemonNameList ar ...

Utilizing separate JavaScript files in Bootstrap 5: A guide to implementation

I am currently using Bootstrap, but I am looking to decrease the size of the Javascript files being used. My main requirements are dropdown/collapse and occasionally carousel functionalities, so I only want to include those specific scripts. Within the "d ...

Leveraging jQuery plugins within an AngularJs application

I am currently trying to implement the tinyColorPicker plugin from here in my Angular app, but I am facing difficulties with it. An error message keeps appearing: TypeError: element.colorPicker is not a function In my index.html file, I have included th ...

Selenium unfortunately does not fully function with JavascriptExecutor

When I attempt to input text using JavascriptExecutor, the code snippet below is what I use: private void inputWorkDescription(WebDriver driver, int rawNumber) throws IOException, GeneralSecurityException { if (!getWorkDescriptionFromSheets(rawNum ...

Submitting data from a dropdown menu using Ajax in Struts 2: A step-by-step guide

I have a select tag with the s:select element inside a form. My goal is to send a post request to the specified action using Struts 2 json plugin. I do not have much knowledge in javascript or jquery. <s:form action="selectFileType" method="post" ...

Incorporating external function from script into Vue component

Currently, I am attempting to retrieve an external JavaScript file that contains a useful helper function which I want to implement in my Vue component. My goal is to make use of resources like and https://www.npmjs.com/package/vue-plugin-load-script. Thi ...

Is it possible to trigger a textbox text change event after autocompleting using jQuery

I recently implemented a jquery autocomplete plugin for a textbox: $('#TargetArea').autocomplete({ source: '@Url.Action("GetTarget", "Ads", new { type = "Zip", term = target })' }); The implementation is working as expected. ...

Using httpRequest to handle binary data in JavaScript

Having trouble deciphering the response of an http request that is a binary datastream representing a jpeg image, despite numerous attempts. Edit: Including the full code snippet below: xmlhttp = false; /*@cc_on@*/ /*@if (@_jscript_versio ...

Is it possible in Angular JS to only load a service in the specific JS file where it is needed, rather than in the app.js file

I attempted to do something like: var vehicle_info = angular.module('psngr.vehicle_info', []).factory('vehicle_info', ['$rootScope', '$timeout', '$q', vehicle_info]); var name = vehicle_info.getNameOfVclas ...

What is the process for executing code on a server by clicking a button?

In my Next.js application, there is a file named dummy.js with the following content: class Dummy extends React.Component{ static async getInitialProps(ctx){ return { dummy : 'abc'}; } displayHelloWorld(params) { cons ...

Guide on utilizing ajax to post data when the URL parameter changes, all without refreshing the page

As the URL parameter changes, the values in my HTML also change. I am passing these values to a JSON file, but they are getting erased when the page refreshes due to the post request. I have attempted to use event.preventDefault(), however, it seems to n ...

Exploring the intersection of onBeforeUnload and node.js

I just started learning about node.js. I'm curious if onbeforeunload can be used in node.js. If so, will the "no script" plugin for Firefox block scripts created by node.js? I want to inform my visitors with a message before they leave the page withou ...

Transmit a JSON array from a controller to a JavaScript variable

I have retrieved a JSON array from a database and it is set up in a controller like this: public ActionResult highlight() { var statesHighlight = db.Jobs .Select(r => r.State); return Json(statesHighlight , JsonRequestBehavi ...