Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
voxels

Threejs tween with sound in RAF

Go to solution Solved by Dipscom,

Recommended Posts

Hi everybody,

im new on gsap...playing with threejs, tween and audio visualizer.

 

I have a group with some mesh as child 

 

1 - I would like to animate each element of the mesh with a value created in RAF .

2 - I would like to make endless tween on rotation (unfortunally , "repeat: -1" its not working). 

 

Is there another elegant / better solution for do that.

Thanks in advance for any help...

 

On RAF i have some function:

 

1 for render() three scene and one for analyze the sound and pass the value on tween.

 

So this...

// The sound analyzer .

function soundAnalyzer() {

if ((cristal)&&(frequencyData)){

tl_cristal_rotationX = new TimelineMax({repeat:-1 });

analyser.getByteFrequencyData(frequencyData);

if(typeof frequencyData === 'object' && frequencyData.length > 0) {

        scale_value = 9000 - frequencyData[1] * 35 ;
        scale_value_Low = 1800 - frequencyData[1] * 5 ;

cristal.traverse( function ( child ) {   
if ( child instanceof THREE.Mesh ) {    
tl_cristal_rotation = new TimelineMax();
tl_cristal_rotation.to(child.rotation, scale_value_Low, { ease: Linear.easeNone, x:  -360 , y: -360, repeat:-1 })
       }
   });

tl_cristal_rotationX.to(cristal.rotation, scale_value , { ease: Linear.easeNone, x: -360  })
}
}

}

// and here RAF loop and Render

// animation loop
function animate() {
  if(dae) {
    soundAnalyzer()
  }
  requestAnimationFrame( animate );

  render();
  stats.update();

}


TweenLite.ticker.addEventListener("tick", render);

//and  render the scene

function render() {
  renderer.clear(); 
  camera.position.x += ( mouseX - camera.position.x ) * .015;
  camera.position.y += ( - mouseY - camera.position.y ) * .015;
  camera.lookAt(scene.position);
  composer.reset();
  composer.render(scene, camera);
  composer.pass(OldVideoPass);
  composer.pass(BrightnessContrastPass);
  composer.pass(RGBSplitPass);
  composer.toScreen();

}

Thank u very much and sorry for my English.. hope is readable..

 
 

See the Pen xgoBOB by phosl (@phosl) on CodePen

Link to post
Share on other sites

Hi voxels

 

Welcome to the forums!

 

It's going to be hard to debug this, we can't go over an entire website worth's of code to review it. Specially minified code.

 

If you could provide a much smaller demo version of it, that highlights only the problem you are trying to solve then, I'm sure more people will chime in to help.

 

Looking at the code you have provided, I would ask: are you aware the RAF is called around 60 times per second? 

 

You appear to be calling your soundAnalyser every frame once your dae is present. Meaning, you are creating a brand new timeline every frame and immediately overwriting it in the next frame. So, no animation will ever happen.

 

Also, you have added a call to the render() inside the RAF and again inside GSAP's 'tick' event. You're calling render() twice in each frame that way.

  • Like 1
Link to post
Share on other sites

Hi Dipscom,

thanks a lot for your reply.. I remove the 'tick' event. 

 

Anyway i need RAF because

1 - i need to render the 3D scene constantly

2 - i call soundAnalyser also because i need to read the frequencyData of the sound "in realtime".

 

Sincerely the code work, and its fine.. i had sync audio with tween..  ( repeat:-1 on TimelineMax  created in RAF function its not working anyway)

 

but im just worried about perfomance..

Expecially on soundAnalyzer when i create a TimelineMax  every frame and immediately overwriting it in the next frame.

 

So when you say overwriting, you mean that there aren't problem around performance ? 

 

Thanks!

Link to post
Share on other sites

Hey Voxels,

 

The codePen helps a ton. Thank you.

 

I don't think the code is working correctly. But then, I could be wrong. As it depends on what you are trying to achieve.

 

What is the effect you are looking for? I can't understand why you are creating a timeline on every frame and overwriting it immediately on the following frame.

 

Are you trying to make the cube spin in tune to the audio? To twist around according to the frequency? Or to just rotate as long as there is an audio playing?

 

The fact that you have repeat:-1 at the timeline level and again at the tween level is also not necessary. In fact, I can't see why you even need to create a timeline at all.

 

This bit here in your code is really not achieving much:

sphereAnimationRotation.to(sphere.rotation, high_value, {
   ease: Linear.easeNone,
   y: 200,
   repeat: -1
})

Because you are calling soundAnalyzer() on your render() method - Setting a brand new tween on each frame but then, you give it a duration of 'high_value' which, when traced is floating around 70 and 150 at the start of the audio. GSAP will read those numbers as seconds, it will never render more than one frame before being overwritten.

 

It only looks like it works because GSAP is smart enough and whenever you use the .to() method it starts tweening from the current position the element is in "to" its target position. If you are going to use GSAP inside a method that's called as frequently as your soundAnalyzer, you really should use .set().

 

I have forked your pen and tweaked it a tiny bit to illustrate what I mean.

 

See the Pen RKXVRe?editors=0011 by dipscom (@dipscom) on CodePen

 

Does that help?

  • Like 1
Link to post
Share on other sites

Hi Dipscom,

thanks a lot for the reaply, help me a lot ! anyway...

 

with a SCALE VALUE and set... its work fine.. I dont have any issue.

 

I have a problem with a ROTATION VALUE...

 

I try to explain clean here: start at this point .. 

 

1 - I would like to rotate a cube endless.

2 - on a sound beat i would like to give to rotation something like acceleration.. as my codepen 

 

See the Pen xgoBOB by phosl (@phosl) on CodePen

 

Thank again for your time

Link to post
Share on other sites

Now we're getting somewhere.

 

I changed to scale because rotation was way to epileptic to my liking.

 

I think I get what you are trying to achieve. We can tackle it with this setup but just ever so slightly...

 

You still want to set the rotation to happen with a .set() call and you still don't need a timeline for that.

 

See the Pen zNgjQB by dipscom (@dipscom) on CodePen

 

Better?

  • Like 2
Link to post
Share on other sites

Definitely better!!

Thank u very much!

 

Its look perfect!

(so is this much more performant ? )

Link to post
Share on other sites

It will be, don't know by how much. But definitely better than having RAF and GSAP's ticker calling render twice and creating timelines only to overwrite them in the next frame.

 

Now you do a super simple Tween without assigning it to a variable. It should be garbaged collected as soon as the tick is done with it.

  • Like 1
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×