6

So here's what I'm trying to do. I have a grid with a lot of images, so I'm using the imagesLoaded library along with masonry.

Here's my CSS:

.grid {
    opacity:0;
}

And HTML:

<div class="grid">
    <div class="grid-sizer"></div>
    <div class="gutter-sizer"></div>
    <div class="item">image</div>
    <div class="item">image</div>
    <div class="item">image</div>
</div>

And here's my JS:

var $container = $('.grid');
// initialize Masonry after all images have loaded  
$container.imagesLoaded( function() {
    $container.masonry({
        columnWidth: '.grid-sizer',
        itemSelector: '.item',
        gutter: '.gutter-sizer'
    });
    $container.masonry('on', 'layoutComplete', function(){
        console.log('got here');
        $container.animate({'opacity':1});
    });
});

My goal is to have the grid hidden until all images are load and the layout is complete, and then fade it in. For some reason in my code above, it's never getting into the on layoutComplete block.

If I move that block outside of imagesLoaded, $container.masonry is undefined that point.

Any ideas?

FIDDLE HERE

If you change the grid opacity to 1 you can see everything is getting laid out fine. Just trying to figure out how to get the layoutComplete to call to set the opacity to 1.

Corey
  • 2,163
  • 4
  • 30
  • 56

3 Answers3

1

You don't need to use the layoutComplete event on masonry. As you can just add your animation code under the masonry initialization .

When all images are loaded, the imageLoaded function will execute. You can then create the masonry object and animate right away like so:

var $grid = $('.grid').imagesLoaded( function() {
// init Masonry after all images have loaded
$grid.masonry({
  columnWidth: 200,
  itemSelector: '.item',
  gutter: 10
});
console.log('got here');
    $('.grid').animate({'opacity':1});
});

Here is a jsfiddle that demonstrate that

sthjerome
  • 695
  • 6
  • 21
  • This seems to work in the fiddle, but it seems odd to me. It seems like it could be possible for `console.log` to fire after images are loaded but before masonry is done laying out. I'll have to test with more and larger images. – Corey Jul 27 '15 at 17:10
  • I would recommend a larger number of image in your test because i doubt that the picture size will affect masonry since they will already be loaded – sthjerome Jul 27 '15 at 18:59
  • After some research, I haven't found any evidence that the masonry() call is non-blocking. So that would mean that function executes until the layout is done. So every time, the animation will execute after the layout is done with the code i provided. – sthjerome Jul 28 '15 at 13:56
  • @Corey If it worked please mark my post as the answer thanks! – sthjerome Aug 03 '15 at 14:13
0
jQuery(document).ready(function($){

     var wdm_wait = function(){

            jQuery("body").find("img").each(function(i) {

                   if(!this.complete)
                   {
                       return false;
                   }

            });
                 // when code reaches here Its assured that all the images are loaded
      clearInterval(waiting);   
      console.log('got here');   
      var $container = $('.grid');

    // initialize Masonry after all images have loaded 
       $container.masonry({
             columnWidth: 100,
             itemSelector: '.item',
             gutter: 10
        });
   $container.animate({'opacity':1}); 
 }

           waiting =  setInterval(wdm_wait,100);


 });

This would certainly assure that your js code executes only after all the images have been loaded (rendered)

Hope this helps! :)

Domain
  • 10,694
  • 2
  • 19
  • 41
  • @Corey , I guess you didn't even try mine. Even this ensures that masonry gets initialized only after all images (not just the ones in the grid but entire body) have been loaded. Check out the fiddle link here https://jsfiddle.net/725nywx4/17/ – Domain Aug 04 '15 at 05:43
0

have you ever try this one, I think this is your answer

var $container = $('.grid').masonry({
        columnWidth: 200,
        itemSelector: '.item',
        gutter: 10
    });
  $container.masonry( 'on', 'layoutComplete', function() {    
        $container.animate({'opacity':1});
    });
$container.masonry();