Jump to content
GreenSock

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

Reverse animation on click to the same element

Recommended Posts

Hello,

 

I am doing and interactive map with different elements and I want on click on each element to do different animations and to show the content. I am starting and i found the way with this code to play the animation:

 

var Anim = new TimelineMax({paused:true});
Anim.to(".element-container", 0.8, {css:{marginLeft:60}, ease:Power2.easeOut});
Anim.to(".default-container", 0.8, {autoAlpha:0},'-=1');
Anim.set('.elements', {className: '+=element-active'},'-=1');
$(".elements").click(function(){Anim.play() });

So I want to use the same element to reverse the animation If you click again on it so I was trying (because I don't know a different way) to add a class "element-active" and then create another animation with the class element-active onclick to do the reverse:

 

var AnimBack = new TimelineMax({paused:true});
AnimBack.to(".element-container", 0.8, {css:{marginLeft:-5000}, ease:Power2.easeIn});
AnimBack.to(".default-container", 0.8, {autoAlpha:1},'-=1');
AnimBack.set('.elements', {className: '-=element-active'},'-=1');
$(".element-active").click(function(){AnimBack.play() });

 

But is not doing anything with this.

 

Any idea how can I do this?

 

Thanks!

 

Share this post


Link to post
Share on other sites

Great, thank you Barule. Is working perfectly with this .elements.

 

Now I have another problem. When the element container is on screen there is also a "close" button on it, so you can choose to click on the element or click on the close button on the element-container. But if you click on the close button and then click on the element is going to do again the "reverse" animation as is still with the "active" class.

 

So what I am trying to do is to remove also the active class on the .elements when I click to the .close button inside the element so to reset all the animation in order to start again from the beginning if I click to an element again. I don't know if this is the right way to do it.

 

So I am trying to do this adding the .removeClass to elements in the close function but is not working...

 

$('.elements').each( function(){
  this.tl = new TimelineMax({paused:true});
  this.tl.to(".element-container", 0.8, {css:{marginLeft:60}, ease:Power2.easeOut});
  this.tl.to(".default-container", 0.8, {autoAlpha:0},'-=1');

  $(this).click( function(){
    // Any others in active state should go back to inactive
    $('.elements').not( $(this) ).each( function(){
      $(this).removeClass('active');
      this.tl.reverse();
    });
    // If this is active, reverse ... if not make it active
    if( $(this).hasClass('active') ){
      $(this).removeClass('active');
      this.tl.reverse();
    }else{
      $(this).addClass('active');
      this.tl.play();
    }
  });
});

$('.close').each( function(){
  this.tl = new TimelineMax({paused:true});
  this.tl.to(".element-container", 0.8, {css:{marginLeft:-5000}, ease:Power2.easeIn});
  this.tl.to(".default-container", 0.8, {autoAlpha:1},'-=1');

  $(this).click( function(){
    // Any others in active state should go back to inactive
    $('.close').not( $(this) ).each( function(){
      $(this).removeClass('active');
      $('.elements').removeClass('active');
      this.tl.reverse();
    });
    // If this is active, reverse ... if not make it active
    if( $(this).hasClass('active') ){
      $(this).removeClass('active');
      $('.elements').removeClass('active');
      this.tl.reverse();
    }else{
      $(this).addClass('active');
      this.tl.play();
    }
  });
});

Thanks a lot for the fast help! 

Share this post


Link to post
Share on other sites

OK, that makes sense :)

 

To prevent the "active" class from being removed before a full reverse(), we can use the onReverseComplete and onReverseCompleteParams to fire a function that removes the class after reverse() is complete.

 

See the Pen mdbmxMo by sgorneau (@sgorneau) on CodePen

 

Hope this helps!

 

EDIT: I've also added in a method to allow another element to trigger the reverse().

 

  • Thanks 1

Share this post


Link to post
Share on other sites
1 hour ago, Shaun Gorneau said:

OK, that makes sense :)

 

To prevent the "active" class from being removed before a full reverse(), we can use the onReverseComplete and onReverseCompleteParams to fire a function that removes the class after reverse() is complete.

 

 

 

 

Hope this helps!

 

EDIT: I've also added in a method to allow another element to trigger the reverse().

 

 

 

Hello, make sense. Now is working almost well done but I had to change all my code to approach this problem this way. Let me show you how I am now:

 

So I have this and is working almost okay. The thing is that this new "close" that is being created for each element appears too early comparing to the animation of the .element container. I need to see the close button later. I tried to add a delay with the '+=2' but is not doing anything. I am not sure where to add it so the element is added to the .element-container at the right time and not before is on screen.

 

$('.elements').each( function(){
  $(this).wrap('<div class="wrapper">');
  $(this).parent().prepend('<span class="close">X</span>');
  TweenMax.set( $(this).parent().find('.close') , {autoAlpha:0},'+=2' );
  this.tl = new TimelineMax({paused:true, onReverseComplete: removeActive, onReverseCompleteParams: [$(this)] });
  this.tl.to(".element-container", 0.8, {css:{marginLeft:60}, ease:Power2.easeOut});
  this.tl.to(".default-container", 0.8, {autoAlpha:0},'-=1');
  
  $(this).click( function(){
    // Any others in active state should go back to inactive
    $('.elements').not( $(this) ).each( function(){
      $(this).removeClass('active');
      this.tl.reverse();
    });
    // If this is active, reverse ... if not make it active
    if( $(this).hasClass('active') ){
      this.tl.reverse();
      TweenMax.to( $(this).parent().find('.close') , 1 , {autoAlpha:0},'+=2' );
    }else{
      $(this).addClass('active');
      TweenMax.to( $(this).parent().find('.close') , 1 , {autoAlpha:1},'+=2');
      this.tl.play();
    }
  });
  
  var elScope = this;
  $(this).parent().find('.close').click( function(){
    TweenMax.to( $(this).parent().find('.close') , 1 , {autoAlpha:0},'+=2' );
    elScope.tl.reverse();
  })
  
});

function removeActive(el){
  el.removeClass('active');
}

 

Also now I have a new problem to solve let me explain:

 

So imagine that I have a map with different .elements you can click. For each element there is one .element-container that have to be opened with different information. With this code I see that all .element.containers are being opened. 

 

To be more clear about this here is the HTML you can see when the website is online:

 

<div class="interactivo">
  		<div class="interactivo-content">
        
          <div class="mapa">
          <span class="mapita"><img src="../img/mapa.png"></span>
          
            <div class="container-element">
            <div class="wrapper">
              <span class="close" style="visibility: hidden; opacity: 0;">X</span>
              <div class="elements element_1"></div>
			</div>
            <div class="element-container" style="margin-left: -1914px;">content1</div>
          </div>
            
          <div class="container-element">
            <div class="wrapper">
            	<span class="close" style="visibility: hidden; opacity: 0;">X</span>			 
				<div class="elements element_2"></div>
			</div>
            <div class="element-container" style="margin-left: -1914px;">content2</div>
          </div>
        </div>
          
        <div class="default-container" style="visibility: inherit; opacity: 1;">
          <div class="logo"><img src="../img/logo@2x.png"></div> 
        </div>
  		</div>
  	</div>

 

So as you can see I have:

 

1. One map.

2. Over the map I have all the container-elements that is a wrap that includes the wrapper that is being created with the code you are helping me (is not by default) with the close and the element and then the element-container that by default is outside of the window that will includes all the information of that element. 

3. With the animation what I want to be able to do is to show the element-container that are inside EACH container-element but not all of them like at the moment because now the code is showing me ALL the element-containers of the website at the same time.

 

So I am not very sure how can I solve this so the animation shows only the right container on each time. 

 

EDIT: Actually the animation is giving me problems when I click to the 2nd element. I think if all the elements are the same like in your example works perfectly but when the elements are differents (with same-type animations) then this is giving problems.

 

To be easier to understand here is the Codepen of the project: https://codepen.io/MZBS/project/editor/ZvgWaz#

 

Thank you so much! 

 

Share this post


Link to post
Share on other sites
19 minutes ago, MZBS said:

I tried to add a delay with the '+=2' but is not doing anything.

 

You're trying to use the position parameter on a standalone tween. That will only work for a timeline tween. You'll want to use a delay on that tween.

:)

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites
10 hours ago, PointC said:

 

You're trying to use the position parameter on a standalone tween. That will only work for a timeline tween. You'll want to use a delay on that tween.

:)

 

 

Perfect, now is working like this:

 

      TweenMax.to( $(this).parent().find('.close') , 1 , {delay: 0.9, autoAlpha:1});

Thanks! 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×