3

I want a div to fadeIn while it's animating(moving up), and the fadeIn needs to occur during the final 2 seconds of the animation just as it is completes.

Please note that I don't want it to both fadeIn and animate simultaneously, the fadeIn needs to occur halfway through the animation as the div is moving up.

    $('header').delay(1000).fadeIn(1000)

$('header').animate({ 
    'marginTop': '-=200px'
}, 2000);

The animations are just queued one after the other and I can't get them to work halfway through.

Pre-alpha
  • 295
  • 2
  • 14

5 Answers5

1

I would run an animate function twice, something like this:

$('#header').animate({
    'marginTop': '-=100px'
}, 1000, function(){ 
    $('#header').animate({
        'marginTop': '-=100px',
        'opacity': 1
    }, 1000)
});

https://jsfiddle.net/o0w4vhb3/

Davy
  • 553
  • 7
  • 16
  • There's a break between the two animate()s, you can clearly see it if you keep it visible the whole time by adding opacity: 1 in the css. So in the end, it's just the second animate() running along simultaneously with fadeIn() while the first animate() runs hidden. Not the effect I was looking for, sorry :( – Pre-alpha Apr 23 '15 at 12:40
1

To determine when the animation is at its half, you can use the step-option of the .animate()-function.

A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set.

In order to start the second animation (the fadeIn) directly, you have to specify the queue-option of the animation to false or dequeue the different animation manually.

var marginTop = 200;
var flag = false;
$('header').animate({
    'marginTop': '-=' + marginTop  + 'px'
}, {
    queue: false,
    duration: 2000,
    step: function(now){
        if(now <= marginTop/2 && !flag){
            $(this).fadeIn();
            flag = true;
        }
    }
});

Demo

Read more about the jQUery animation-queue here

empiric
  • 7,449
  • 6
  • 35
  • 44
  • Exactly what I was looking for, though I had to do a cartload of tweaking with pixel values and time durations before I got the right effect. – Pre-alpha Apr 23 '15 at 12:10
  • 1
    Has my upvote but I have to comment that the `fadeIn()` fires 100+ times. A switch might be a good idea. – Shikkediel Apr 23 '15 at 12:51
  • @Shikkediel thanks, yes you're right, I didn't thought about that, added a variable to cope with that. – empiric Apr 23 '15 at 13:02
  • I don't understand... how could `fadeIn()` fire 100+ times? – Pre-alpha Apr 23 '15 at 13:05
  • Always looking for a tweak - and a little glad I could spot something in return. :-D – Shikkediel Apr 23 '15 at 13:05
  • @Shikkediel @empiric Can someone show me the light here? How does `fadeIn()` fire 100+ times? – Pre-alpha Apr 23 '15 at 13:10
  • 2
    The step function fires on *every* step of the animation (many times a second) so the `fadeIn()` would be triggered as well (during the second half at least). But adding a variable that serves as a switch to make it only trigger once should be enough. It's definitely the niftiest solution. – Shikkediel Apr 23 '15 at 13:14
0

I would be to do it in two steps, mimicking what .fadeIn() does :

http://codepen.io/anon/pen/wavmBw?editors=011

header {
opacity: 0;
}

$('header')
.animate({marginTop: '-=100'}, 1000, 'linear')
.animate({marginTop: '-=100', opacity: 1}, 1000, 'linear');

Edit - @empiric had a good point in the comments so I've changed the approach a bit to the most direct option. This would have the same result as a fadeIn() (but doesn't seem very necessary) :

http://codepen.io/anon/pen/wavmBw?editors=011

var header = $('header');

header.css({display: 'none', opacity: 0});

// other stuff may be going on first

header
.css('display', 'block')
.animate({marginTop: '-=100'}, 1000, 'linear')
.animate({marginTop: '-=100', opacity: 1}, 1000, 'linear');

Edit - as mentioned in the comments, the animations would need to be linear to appear smooth.

Shikkediel
  • 4,890
  • 15
  • 41
  • 70
  • 1
    Note: this will assume the `header` is hidden through `opacity: 0`. Depending on how the `header` is hidden, you have to set display before the second animation. – empiric Apr 23 '15 at 10:03
  • Good point, I'll add a live example to clear some of that up. – Shikkediel Apr 23 '15 at 10:06
  • @Shikkediel - actually its not true. `fadeIn()` is not sync. and you can chain those animation and run them simultaneously. – Shlomi Hassid Apr 23 '15 at 10:52
  • Really, you gonna downvote over a detail while I'm still editing? – Shikkediel Apr 23 '15 at 10:55
  • Can you temme why you're changing the `display` property from `none` to `block`, and also are `display: 'none'` and `opacity: 0` the same? – Pre-alpha Apr 23 '15 at 11:02
  • 2
    @Jeevan Elements with `display:none` will not reserve any space in the document, whereas `opacity:0` will only make the element invisible but the space is used. – empiric Apr 23 '15 at 11:08
  • Better answer than I posted. ;-) – Shikkediel Apr 23 '15 at 11:10
  • There's a break between the two `animate()`s, you can clearly see it if you keep it visible the whole time by adding `opacity: 1` in the css. So in the end, it's just the second `animate()` running along simultaneously with `fadeIn()` while the first `animate()` runs hidden. Not the effect I was looking for, sorry :( – Pre-alpha Apr 23 '15 at 12:08
  • Yeah I know what causing that... well noticed. It's the default 'swing' animation. I'll update. – Shikkediel Apr 23 '15 at 12:19
0

You can run both animation simultaneously by disabling queuing of the first one like this:

$('.header').css('opacity', 0);
$('.header').show();

$('.header').animate({ 'marginTop': '-=200px' }, {queue: false, duration: 2000});
$('.header').animate({opacity: 1}, 3000 );
.header {
    background-color: red;
    padding: 20px;
    display: none;
    margin-top: 250px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="header">test</div>

Adjust the durations as needed.

Reference: How do you fadeIn and animate at the same time?

Community
  • 1
  • 1
dekkard
  • 3,285
  • 1
  • 13
  • 25
  • There's a break between the two animate()s, you can clearly see it if you keep it visible the whole time by adding opacity: 1 in the css. So in the end, it's just the second animate() running along simultaneously with fadeIn() while the first animate() runs hidden. Not the effect I was looking for, sorry :( – Pre-alpha Apr 23 '15 at 12:40
0

Found!!!

PURE jQuery - fadeIn() + animate()

If you want to use a display:none element and still get the two effects then Simply hide it using jQuery or inline style.

Problems to solve:

  • .animate() can't animate the display property - so we use fadeIn.
  • .animate() is added to an animation queue- so we set queue: false.

$('div').hide();
$('div').fadeIn(3000).animate({ 'marginTop': '-=200px' }, { queue: false, duration: 2000 });
div { margin-top:200px; background-color:blue; height:50px; width:500px; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div></div>

BONUS - only CSS:

Use opacity and delay the animation:

CSS: jsFiddle Demo

#ifade  { 
   margin-top:50px; 
   opacity:0;
   -moz-transition : margin-top 2s linear 0s, opacity 1s linear .6s;   
    -webkit-transition : margin-top 2s linear 0s, opacity 1s linear .6s;   
     transition : margin-top 2s linear 0s, opacity 1s linear .6s;   
}

Have Fun!

Shlomi Hassid
  • 6,230
  • 2
  • 23
  • 39