4

See the following fiddle:

[edit: updated fiddle => http://jsfiddle.net/NYZf8/5/ ]

http://jsfiddle.net/NYZf8/1/ (view in different screen sizes, so that ideally the image fits inside the %-width layouted div)

The image should start the animation from the position where it correctly appears after the animation is done. I don't understand why the first call to setMargin() sets a negative margin even though the logged height for container div and img are the very same ones, that after the jqueryui show() call set the image where I would want it (from the start on). My guess is that somehow the image height is 0/undefined after all, even though it logs fine :?

js:

console.log('img: ' + $('img').height());
console.log('div: ' + $('div').height());

$('img').show('blind', 1500, setMargin);

function setMargin() {
    var marginTop =
    ( $('img').closest('div').height() - $('img').height() ) / 2;

    console.log('marginTop: ' + marginTop);

    $('img').css('marginTop', marginTop + 'px');
}

setMargin();
kontur
  • 4,934
  • 2
  • 36
  • 62
  • Did you define the img's height in the HTML? Perhaps the JS is firing before the image has completely loaded, so the browser is grabbing the wrong height. – skybondsor Jan 21 '12 at 22:23
  • I am useing percentual resizing for the image - not sure if this would work with setting height and width in the img tag then. So, no, I haven't, but I can give it a shot. – kontur Jan 21 '12 at 22:25
  • @kontour this fires your animation, but it still isn't quite right: http://jsfiddle.net/NYZf8/2/ – scottm Jan 21 '12 at 22:29
  • also, there is no need to add 'px' to the css value. jquery adds it. – timing Jan 21 '12 at 22:34
  • You might want to try forcing load() on the img and then doing your setup on the callback. Check the first answer here http://stackoverflow.com/questions/3877027/jquery-callback-on-image-load-even-when-the-image-is-cached – skybondsor Jan 21 '12 at 22:40
  • @scrottm, that basically just sets marginTop to 0, so this is not quite what I am looking for. @skybondsor, thanks for the hint, I wrapped the first call to `setMargin()` in a load listener for `img`, but to no effect: http://jsfiddle.net/NYZf8/5/ – kontur Jan 21 '12 at 22:54
  • I don't think you implemented fully what the answer on that other question was suggesting. I did so here, and there's no negative margin for me: http://jsfiddle.net/Ez5WK/ – skybondsor Jan 21 '12 at 23:41
  • no negative margin indeed, but what I want is for the image's animation to start with a marginTop that is has at the end of the animation, i.e. the top border of the image would not move during/before/after the animation. [edit: the negative margin comes to be only because the image's height seems to be 0, even though logged differently] – kontur Jan 21 '12 at 23:47
  • The question for me now is why the image doesn't load at width:80%, but only jumps to that after the animation. I see no reason why it should be doing that... – skybondsor Jan 22 '12 at 03:52

1 Answers1

2

Interesting problem...after playing around with your code for a while (latest update), I saw that the blind animation was not actually firing in my browser (I'm testing on Chrome, and maybe it was firing but I wasn't seeing it as the image was never hidden in the first place), so I tried moving it inside the binded load function:

$('img').bind('load', function() {
    ...
    $(this).show('blind', 500);
});

Now that it was animating, it seemed to 'snap' or 'jump' after the animation was complete, and also seemed to appear with an incorrect margin. This smacks of jQuery not being able to correctly calculate the dimensions of something that hadn't been displayed on the screen yet. On top of that, blind seems to need more explicit dimensions to operate correctly. So therein lies the problem: how to calculate elements' rendered dimensions before they've actually appeared on the screen?

One way to do this is to fade in the element whose dimensions you're trying to calculate very slightly - not enough to see yet - do some calculations, then hide it again and prep it for the appearance animation. You can achieve this with jQuery using the fadeTo function:

$('img').bind('load', function() {

    $(this).fadeTo(0, 0.01, function() {

        // do calculations...

    }
}

You would need to work out dimensions, apply them with the css() function, blind the image in and then reset the image styles back to their original states, all thanks to a blind animation that needs these dimensions explicitly. I would also recommend using classes in the css to help you manage things a little better. Here's a detailed working example: jsfiddle working example

Not the most elegant way of doing things, but it's a start. There are a lot more easier ways to achieve seemingly better results, and I guess I just want to know why you're looking to do image blinds and explicit alignment this way? It's just a lot more challenging achieving it with the code you used...anyways, hope this helps! :)

Chris Kempen
  • 9,491
  • 5
  • 40
  • 52
  • That is exactly what is so confusing about this problem. It logs the image dimensions properly, but jqueryui's animating seems to not grab those properly, starting from a 0/undefine, I guess. You solution works perfectly, and exactly the way I intended it. Not this particular setup of css and animation might not be what I go for in the end, but I had different approaches (for instance, scale image to fit), that failed for the same underlying reason, which is this animation weirdness with the "uninstantiated" images. Seeing how "clumsy" code I'd have to unitize, I might rethink the animation.ty – kontur Jan 22 '12 at 10:30