gareth

showing from display none

Recommended Posts

Hi,

 

I often use display:none or $('#mydiv').hide() to hide a div, how can I use GSAP to show the div at a later point. Auto alpha does not do it:

 

TweenLite.to($('#mydiv') , 0.3, {autoAlpha: 1})  

 

  • Like 1

Share this post


Link to post
Share on other sites

TweenLite.to($('#mydiv') , 0.3, {autoAlpha: 1, display:'block'});

should do it.

 

( If you don't have display:none in the CSS, off the top of my head I think display:'' might just clear display from the style tag completely, but don't quote me on that one. )

 

display tweens (since there are no intermediate values between block/inline/inline-block etc and none) occur at the start of the tween if the display value is not none, and at the end if it is none.

  • Like 1

Share this post


Link to post
Share on other sites

thanks Jamie, it works in that is shows the div now, but it is not tweened - I guess i need to set the opacity to 0 as well? 

Share this post


Link to post
Share on other sites

This works for me:

TweenLite.fromTo ($('#mapCaption') , 0.3, {opacity:0}, {opacity:1,display:'block'})  

Share this post


Link to post
Share on other sites

Glad you figured it out. To clarify on autoAlpha, it is the same as opacity, except that when opacity === 0, it will set the elements visibility to hidden, to give a slight performance boost. Whenever opacity !== 0, visibility is set to visible (or is it inherit now?).

 

The difference between visibility:hidden and display:none is that visibility just removes the element from rendering, while it still retains its space on screen. display:none removes the element entirely from the document flow, so it's like the element is not there at all.

  • Like 2

Share this post


Link to post
Share on other sites

as far as emptying a value from a property... your correct Jamie, in jQuery if you pass an empty string as the value: 

$('#mapCaption').css(display,"");

it will remove the display property from the style attribute

 

but with GSAP couldn't you use clearProps?

TweenMax.set($('#mapCaption',{display:""});

// or

TweenMax.set($('#mapCaption',{clearProps:"display"});

or does clearProps only clear properties that have been set with GSAP?

Share this post


Link to post
Share on other sites

clearProps applies once the tween ends, so it is more useful for cleaning up unneeded style attributes after a tween (e.g. you are tweening to the element's default style). If you wanted a fade in from display:none, you need display to become 'not none' at the beginning of the tween.

  • Like 3

Share this post


Link to post
Share on other sites

Unless you have a real good reason for using display over visibility (like you don't want the elements in the document flow at all) I have found setting visibility:hidden in css and then tweening the autoAlpha to work quite well.

 

 

--- CSS ---

#demo {
width: 692px;
height: 60px;
background-color: #333;
padding: 8px;
visibility:hidden;
}
 
--- JS ---
TweenLite.from("#demo", 1, {autoAlpha:0});

//the following works too
//TweenLite.to("#demo", 1, {autoAlpha:1});

http://codepen.io/GreenSock/pen/jxaHJ

 

Again, nothing wrong with using display, but using visibility cuts down on the complexity.

 

You don't have to bother with opacity or worry about when display:none will be removed.

  • Like 3

Share this post


Link to post
Share on other sites

thanks Carl, normally I need to take the div out of the flow, but is there any performance advantage to doing it your way?

Share this post


Link to post
Share on other sites

not that I'm aware of.

Share this post


Link to post
Share on other sites

There probably is a bit of a performance advantage to using visibility:hidden instead of display:none because changing visibility doesn't force the browser to calculate a document reflow whereas altering "display" does. In most real-world scenarios it probably won't make a massive difference, but all things being equal, I'd personally go with visibility:hidden for sure. 

  • Like 3

Share this post


Link to post
Share on other sites

Hi, i was searching around for answer to my issue which is related so i thought Id post here instead of creating a new thread

 

if I'm fading a section with one height longer than the section fading in.. the thing with using visibility hidden is that the browser window still acts as if the first longer section is still there, which i think shouldnt happen because the new section is shorter and doesnt need more room.

 

Is there a way you guys have dealt with this?

 

I see in this thread they recommend display:none but let me know what you think

http://forums.greensock.com/topic/9313-autoalpha-and-full-hiding-the-item/

Share this post


Link to post
Share on other sites

Hey Dwayne,

 

Well I remember running across something like this. One solution was to change the element's height as well as the autoAlpha value, the problem was that it looked a little awkward the window scroll bar growing and shrinking every time. In order to solve that I wrapped the entire site in a <div> element and on the click event (this was a menu) I removed the scroll bars and created a Timeline. At the end of that timeline added a set() instance to add the scroll bars again. Of course this only works if the user has to go to the top of the page, otherwise you'll have to scroll the content to the top.

 

But as Jamie said in the post you mention, adding the display toggles that property at the end/start of the tween, in order to give the appropriate consistency. Is less code and you'll have to evaluate if there's any performance issue by doing it that way. I haven't played a lot with it, so I couldn't tell you.

 

Rodrigo.

  • Like 1

Share this post


Link to post
Share on other sites

Understood.i will give it a shot. Many thanks.

Share this post


Link to post
Share on other sites

visibility:hidden is usefull sometimes, the element is hidden BUT it´s size still affects layout. I prefer display: none;

Share this post


Link to post
Share on other sites

And the solution "TweenLite.to($('#mydiv') , 0.3, {autoAlpha: 1, display:'block'});" breaks the effect first time, i guess because the "display" property is not animated.

Share this post


Link to post
Share on other sites

I don't understand what you mean by "breaks the effect first time"; could you elaborate please? A codepen demo might help you to illustrate what you mean.

 

The display property certainly is animated by GSAP, in the sense that it is toggled at the start or end of the tween. Please read the API, or my earlier comment for more explanation.

Share this post


Link to post
Share on other sites

I have the same problem with the latest version of tweenLite,

 

 

try this:

 

css:

 

#div { display: none; transform: translateX(-100%); }

 

 

js:

 

TweenLite.to("#div", 0.5, {ease: Back.easeInOutSine, force3D: true, x: '0%', display: 'block' });

 

 

worked version:

TweenLite.set("#div", { display: 'block' });

TweenLite.to("#div", 0.5, {ease: Back.easeInOutSine, force3D: true, x: '0%' });

 

 

My guess:

because the dom is default hidden, so gsap cannot get the original value for the first time.

  • Like 1

Share this post


Link to post
Share on other sites

Hi and welcome to the GreenSock forums.

 

Mhh, I don't know what could be the issue but is on other part of your code. The following works ok with GSAP 1.17.0:

TweenLite.to(".box", 1, {x:300, display:'block'});

You can see it here:

 

http://codepen.io/rhernando/pen/ojvRaK

 

If you could set up a reduced sample that clearly demonstrates the issue you're having we might have better look at knowing what could be the problem. Please take a look at this thread:

 

Share this post


Link to post
Share on other sites

http://codepen.io/shtse8/pen/ZbzgWb

 

You can test it here.

red box is the buggy version.

blue box is worked version.

for the first time, the red box animation is missing.

I have made the button can be pressed many time for the later animation.

Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

Hi,

 

Thanks for the codepen sample!!

 

This code works:

 

CSS

.box {
  width:50px;
  height:50px;
  position:relative;
  margin-bottom:2px;
  display:none;
}

.red {
  background-color:red;
}

.blue {
  background-color:blue;
}

JS

TweenLite.set(".box", {xPercent:-100});

function startNow() {
  if (i == 0) {
    TweenLite.to("#redBox", 1, {
      ease: Back.easeInOutSine,
      force3D: true,
      xPercent: 0,
      display: 'block'
    });

    TweenLite.set("#blueBox", {
      display: 'block'
    });
    TweenLite.to("#blueBox", 1, {
      ease: Back.easeInOutSine,
      force3D: true,
      xPercent: 0
    });
    i = 1;
  } else {
    TweenLite.to("#redBox", 1, {
      ease: Back.easeInOutSine,
      force3D: true,
      xPercent: -100,
      display: 'none'
    });

    TweenLite.to("#blueBox", 1, {
      ease: Back.easeInOutSine,
      force3D: true,
      xPercent: -100,
      display: 'none'
    });
    i = 0;
  }
}

As a general rule of thumb, try to avoid mixing CSS translates with subsequent GSAP animations/modifications of those properties. This can cause some weird results because normally CSS transforms use either a translate or translate3d property while GSAP uses either a 2D or 3D matrix to animate those values, which gives much more flexibility. Also for using percentage related values of transforms, such x and y, you can use xPercent and yPercent and the CSS Plugin does everything for you under the hood. See in the code above that I even passed the unit string (%) just the percentage value?.

 

Happy Tweening!!

  • Like 3

Share this post


Link to post
Share on other sites

Hi,

 

Thanks for your worked version, and that's also my using version too.

 

But I want to set the x value using css first because css is loaded before js.

So the box will not be shown after the page is loaded. 

If I set the box using js, the box will be shown for 1 second until the js is loaded.

And for coding style, I don't want to set the same property for twice.

one is for css and one is for js.

 

So it would be great if we can set the display:block to the option for working.

as you can see the blue box version is working too, and we do not need to set the property twice.

but only need to separate the display and xPercent into two lines.

 

Thanks for your help .

  • Like 1

Share this post


Link to post
Share on other sites

Unfortunately I don't really see a great way around this because it breaks if ANY ancestor has display:none, thus we'd have to literally walk up the DOM tree checking every ancestor, record the current state, change it (if necessary), get the computed style, then revert things, etc. It's very messy and CPU-intensive. Plus this strikes me as an edge case because you could just use visibility:hidden for the same effect and that works (as far as I can tell at least). 

 

But Rodrigo is right - it's typically best to always set the transforms using GSAP because it works around so many browser bugs and other issues. You could certainly still set them via CSS initially, but then your first line of JS could be to set() those again through GSAP so that everything is calibrated. 

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for your answer.

 

Setting visibility:hidden is possible unless there is no flash on the box.

Otherwise, the flash is still clickable even the visibility is hidden (flash is always on top) and that is the reason why I need to set it do display:none.

 

How about just apply the non-tweenable properties at the beginning of the tween? it should work too. 

For my best understanding, the current state cannot be checked because the dom is display:none,

so if we set the display:block in the option, and we know the dom is none now, just apply the display:block on the object and get the current state after.

 

 
According to the description, we can set display: block property and it will be applied at the beginning of the tween.

 

nMqsWMV.jpg

TweenLite.to("#div", 0.5, {x: '0%', display: 'block' });

but it doesn't work on my case.

I have to set it before the animation to make this work.

TweenLite.set("#div", { display: 'block' });
TweenLite.to("#div", 0.5, { x: '0%' });

For my best knowledge,

it should be the same as the description - set the display:block at the beginning of the tween.

But why it doesn't work if we make it into one line? but it works if we set the non-tweenable manually first.

 

Thanks.

  • Like 1

Share this post


Link to post
Share on other sites

For the record, it was indeed setting the display:block at the start of the tween; it's just that in the loop internally, the transform happened to come first. I have made a change to the upcoming 1.18.0 release which you can preview [uncompressed] at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/TweenMax-latest-beta.js. I believe that resolves this particular case. 

  • Like 4

Share this post


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.