Jump to content
GreenSock

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

:first selection never update when tweening on repeat then pushing to bottom of stack

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

im trying to make a photo slideshow that fades the top image to 0 move it to the bottom of the ul stack and then set the opacity back to one and then fade the new top image to zero

when it repeats tho its still thinking  :first element thats now at the bottom of the stack is still at the top.

 

 

This is the js

TweenMax.to($this.children(':first') , 1, { alpha:0 , repeat: -1, repeatDelay:3, onRepeat: reset });
        
                

                
            }
             function reset() {
                 console.log($this.children(':last').css('zIndex') - 1);
                $this
                           .children(':first')
                           .css('opacity', 1) // Return opacity back to 1 for next time.
                           .css('zIndex', $this.children(':last').css('zIndex') - 1) // Reduces zIndex by 1 so that it's no longer on top.                    
                          .appendTo($this); // move it to the end of the line.
                        }

this is the html

 <ul id="slider">
          <li>
            <img src="img/demos/demo1.png" />        
            
        </li>
        <li>
          <img src="img/demos/demo2.png" />        
          
        </li>
        <li>
        <img src="img/demos/demo3.png" />        
        
        </li>
        </ul>

... after it runs once, demo1.png is at the bottom, but then the tweenmax call still tweens that image as if its first...

 

and for reference this is the setinterval function that i got the code from that i wanted to rewrite using greensock

setInterval(function() {


					$this.children(':first').animate({'opacity' : 0}, options.speed, function() {	
							console.log ($this.children(':first'))
						  		$this
						   .children(':first')
						   .css('opacity', 1) // Return opacity back to 1 for next time.
						   .css('zIndex', $this.children(':last').css('zIndex') - 1) // Reduces zIndex by 1 so that it's no longer on top.					
						   .appendTo($this); // move it to the end of the line.
					})
				}, 1000);

I know im missing something important here, anyone have an idea as to how to make the Tweenmax repeat see the new :first element?

Link to comment
Share on other sites

Hello have you tried using onComplete instead of onRepeat.. and also adding clearProps:"all" say after alpha:0 in your to() method

 

maybe something like this:

TweenMax.to($this.children(':first') , 1, { css:{alpha:0, clearProps:"all"} , repeat: -1, repeatDelay:3, onComplete: reset });
you could also try this inside your reset fucntion
TweenMax.set($this.children(':first'),{clearProps:"all"});
or you might have to use any of the available kill methods to wipe the existing recorded target value, within your callback

 

http://api.greensock.com/js/com/greensock/core/Animation.html#kill()

http://api.greensock.com/js/com/greensock/TweenMax.html#killAll()

http://api.greensock.com/js/com/greensock/TweenMax.html#killChildTweensOf()

http://api.greensock.com/js/com/greensock/TweenMax.html#killDelayedCallsTo()

http://api.greensock.com/js/com/greensock/TweenMax.html#killTweensOf()

 

if you can create an example via codepen or jsfiddle it will help us be able to better help you find a solution.. thx :)

  • Like 1
Link to comment
Share on other sites

 

and after getting advice from Jack.. he suggested that I need to use one of the kill methods on the tween, If I want to re-declare a new target/selector.

 

He explained that when a tween is run, you can not change the tweens target, since the animation is technically running in memory.

 

So after following Jacks advice, I killed the tween after its completion and then re-declared it with a new selector. After that I was able to animate the new target.

Link to comment
Share on other sites

Solved!

		TweenMax.to($this.children(':first') , 5, { alpha:0 , delay:2, onComplete: reset});
		 

			 function reset() {


				TweenMax.killTweensOf($this.children(':first')); 
	 
				$this
						   .children(':first')
						   .css('opacity', 1) // Return opacity back to 1 for next time.
						   .css('zIndex', $this.children(':last').css('zIndex') - 1) // Reduces zIndex by 1 so that it's no longer on top.					
						  .appendTo($this); // move it to the end of the line.
						TweenMax.to($this.children(':first') , 2, { alpha:0 , delay:2, onComplete: reset});

						}
Link to comment
Share on other sites

Hi Dwayne!

 

Glad to see this got resolved.

 

Just for some clarification, the reason your first attempt didn't work is because when your tween repeated it was not re-evaluating what the target of the tween should be.

 

When the tween was first created it stores a reference to its target (the first child). On repeat it just alters properties of that same object and the tween literally has no idea that you shifted its target's position in the DOM.

  • Like 2
Link to comment
Share on other sites

Thanks Carl for the helpful answer. Is there way to let the tween know that the position was shifted, or is my hacky workaround a good way?

Link to comment
Share on other sites

 Is there way to let the tween know that the position was shifted?

Not that I can think of. Once the tween saves its reference to its target it really has no concern for where the target is in the DOM, nor does it have any way of tracking that. 

 

The solution of creating a new tween for each element that needs to be animated is the way to go.

  • Like 1
Link to comment
Share on other sites

Hi Dwayne

 

Well the engine has the updateTo() method to change the tween values after the instance has been created and played or even during execution, you can check the api reference here:

 

http://api.greensock.com/js/com/greensock/TweenMax.html#updateTo()

 

But in your case, since what's changing is the tween's target, the kill method is the way to go, because the updateTo method acts on the tween vars and not the element being animated.

 

Another choice would be to create a function that takes that element, in this case the first children of the collection, creates and executes the animation, then onComplete calls another function to change the element's  and it's next sibling CSS (here you could add an "active" or "first" class to the next and remove it from the first one) and finally call the function that creates the tween again.

 

Although is not the same thing Chrysto created a great sample of recycling one function to animate a series of elements based on selectors, you can see it here:

See the Pen LckBh by bassta (@bassta) on CodePen

 

Rodrigo.

  • Like 1
Link to comment
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.
×