Jump to content
Search Community

Clean styles after tween

nomn test
Moderator Tag

Go to solution Solved by Rodrigo,

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

Hi. I tried to make codepen, but it isn't work... ;(

Please, try to help me without it.

I make simple slider, that have some <li>. Every slid is show 3 <li> (without any row container).

Next button click is tween first 3 <li> and hide it, next it append first 3 <li> to end of <ul> and show next 3 li. - Its work for me, but 2nd click to "next"   will show some noise fast animation and next we will see same <li>'s, that was on 1st "next" click.

I think its because styles of hidden <li>'s isn't cleared. I tried use clearProps:"all", .clear() and removeAttr("style") - don't help.

Sorry for my English!

 

 

 

See the Pen OPwOBO by anon (@anon) on CodePen

Link to comment
Share on other sites

Hi,

 

First, there's an issue with your codepen sample. In this particular part of your code:

$("#slider-next").click(function(){
		append_counter = 0;
		
		TweenLite.set(content, {visibility:"visible"});
		var tl = new TimelineLite();
		tl.clear();

	});

The "content" object being passed to the set() instance is not defined anywhere in your code, so code execution stops there, therefore is impossible to see what could be happening.

 

Second there's no need to call tl.clear(); right after you created the timeline instance. As soon as you instantiated a new TimelineLite() method, that timeline instance is empty, so using the clear() method in that timeline is a waste of code, basically you're removing everything from something that's already emtpy.

 

Finally this part of your code also caught my attention:

// Анимация картинок
		tl.to($(items).eq(0), 0.4, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn});
		tl.to($(items).eq(1), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.2");
		tl.to($(items).eq(2), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.1");

Before in your code you're defining items, like this:

var item_wrapper = $(".slid-container"),
items = $(item_wrapper).find('li'),
items_to_append = 3,
append_counter;

Almost every GSAP method returns the instance, so further methods can be chainable, so there's no need to reference the timeline instance. Then you're creating a jQuery collection when you instantiate the "items" variable, and then you're wrapping it in a jquery statement again $(items), since you created the collection there's no need for that. Also keep in mind that the <li> elements are direct childrens of the ul element, so you can select them directly like this:

var item_wrapper = $(".slid-container"),
    items = $(".slid-container li");

You can chain methods like this:

tl
  .to($(items).eq(0), 0.4, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn})
  .to($(items).eq(1), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.2")
  .to($(items).eq(2), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.1"); 

Then in this GSAP instance you are calling some jquery specific index selecting method:

TweenMax.staggerFrom('.slid-container li:lt(3)', 2, {scale:0.5, opacity:0, delay:0.5, ease:Elastic.easeOut, force3D:true}, 0.2);

Even though GSAP has a small selecting engine running under the hood, what you're passing can't be selected by the engine, you have to wrap it in a jquery element:

TweenMax.staggerFrom($('.slid-container li:lt(3)'), 2, {scale:0.5, opacity:0, delay:0.5, ease:Elastic.easeOut, force3D:true}, 0.2);

Finally you're not calling the changePos() function anywhere in your code, so the other elements are not being animated, you can call the function using an onComplete callback in the timeline or using a call() method at the end of the timeline:

// use an onComplete callback
var tl = new TimelineLite({onComplete:changePos});

// use a call() method
tl
  .to($(items).eq(0), 0.4, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn})
  .to($(items).eq(1), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.2")
  .to($(items).eq(2), 0.2, {y:-300,opacity:0,scale:0.6,ease:Back.easeIn},"-=0.1")
  .call(changePos);

I forked your codepen, but it seems that this still needs some work, but hopefully this will help you get started:

 

See the Pen yyqKgE?editors=001 by anon (@anon) on CodePen

 

Rodrigo.

  • Like 3
Link to comment
Share on other sites

Thank you very much for your answers. I am pleasantly surprised by the friendliness of your community!

Thank you for the mistakes that you have specified.

 

If you look at the code that you have done in codepen, we see that after the first click ">>>" animation loops (for some reason comes only one rectangle. on my local server, come all 3, from 3 <li> to 6 <li>).

And, by and large, the question is that why the animation in a loop?

Function changePos () is called after the TimelineLite is complete: TimelineLite ({onComplete: changePos});

 

 

Watch this:

Click 3-4 times to " >>> "

Link to comment
Share on other sites

I have a small shifts.

Now everything works almost like i need.

 

The only thing - the delay between the disappearance of the first three and the emergence of the next three.

Ie a few seconds can not see anything, and only then take off the next 3.

 

i'l tried to optimize.

My JS now is:


    var item_wrapper = $(".slid-container"),
    items = $(".slid-container li"),
    items_to_append = 3,
    append_counter;

    TweenMax.staggerFrom($('.slid-container li').slice( 0, 3 ), 2,
        {scale:0.5, opacity:0, delay:0.5, ease:Elastic.easeOut, force3D:true},
    0.2);

    $("#slider-next").click(function(){
            TweenMax.staggerTo(
                $('.slid-container li').slice( 0, 3 ), 2,
                {scale:0.6, opacity:0, y:-300,delay:0.2, ease:Elastic.easeOut, force3D:true},
            0.2,changePos);
        return false;
    });

    // Перебор для переноса в конец
    function changePos() {
        console.log("changePos");
        append_counter = 0;

        $(".slid-container li").each(function(indx, element){
            if(indx < items_to_append) {
                $(item_wrapper).append($(element));
            }
        });    

        TweenMax.staggerFromTo($('.slid-container li').slice( 0, 3 ), 2,
            {scale:0.6, opacity:0, y:-300,delay:0.5, ease:Elastic.easeOut, force3D:true},
            {scale:1, opacity:1, y:0,delay:0.5, ease:Elastic.easeOut, force3D:true},
        0.2);
    }
Link to comment
Share on other sites

  • Solution

Hi,

 

Sorry for the delay in the response but I couldn't get to this before.

 

The more I look at your code, I'm getting more convinced that the biggest issue here is how you're selecting and therefore animating stuff.

 

I believe that the main concept you want to achieve is to animate 3 elements out of view and animate in another 3 elements, like that until you reach the final 3 elements and start over again. The main problem is that you're over complicating stuff, something all of us have done at some point (in my case more than once), thus creating this selecting nightmare.

 

Since you're trying to bring some elements into view and removing others, why not wrap those elements into individual containers. For example the first three elements can be contained in a box with a class of slide, then the next three elements in another box with the same class, and so forth. Then all you have to do is call a function that selects the child elements of that box with the class of slide, animate the children of that box out, increases an integer (that should be the index of the container box) and animate the next elements in. And when the final slide is reached return the index number to zero in order to animate in the first set of elements.

 

Because of this I thought that it would take less time for me to create some code that does that, instead of looking and understanding what you're trying to do with your code. I created this codepen, please feel free to fork and adapt it to your scenario:

 

See the Pen ByOyjx by rhernando (@rhernando) on CodePen

 

If you need more help let us know.

 

Happy Tweening!!

  • Like 4
Link to comment
Share on other sites

Rodrigo, thanks a lot for your help. You understand my scenario absolutely right, it's works perfectly!
I fork your codepen and start reading it line by line to understand the algorithm and get some experience!
Thank you!!

Link to comment
Share on other sites

There is a small problem with the solution.

Click and hover events are triggered only on the last line.

This can be corrected by assigning z-Index for the first slide 1 and each time you change a slide to increase z-index for each of the next slide. this solution works, but it may have a more elegant solution?

Edited by nomn
Link to comment
Share on other sites

Hi,

 

I'm going to assume that your slide container has some sort of background. It's just as simple as set the z-index at the right time. Reduce the z-index of the current slide after the elements have been animated out and increase the next slide's z-index before it's elements are animated in:

function thisSlideReverse(){
    
    // set the z-index of the current slide to 20
    slides.eq(currentIndex).css("z-index","20");

    // if this is not the last slide increase the index, otherwise go back to the first slide
    if(currentIndex < slidesAmount - 1){
      currentIndex++;
    } else {
      currentIndex = 0;
    }// conditional end

    var currentSlide = $(".slide").eq(currentIndex),
        currentChild = currentSlide.children(".slide-item");
		
    // set the new slide z-index to be at the top
    currentSlide.css("z-index","40");
    
    TweenMax.staggerTo(currentChild, 2.3, {scale:1, autoAlpha:1, ease:Elastic.easeOut}, 0.3, enableClick);

  }

I've updated the codepen, now every slide has an ugly orange background so you can see it working:

 

See the Pen ByOyjx?editors=001 by rhernando (@rhernando) on CodePen

 

Happy Tweening!!

  • Like 2
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.
×
×
  • Create New...