views:

309

answers:

7

I was trying to make a kind of background in which some clouds were moving, but after I got the clouds moving I found that I should either make them stop and return when reaching the browser's max width, or make them disappear. I was trying to get their position but I can't manage to get all the positions dynamically. Right now (for the sake of simplicity) I'm only using 1 cloud to test and I do this:

$(function(){

    var p = $('.clouds').position();
    var w = $("#sky").width();
    while(p < w);
     $('.clouds',this).stop().animate({left:"+=50000px"},{queue:false, duration:90000});

});

the thing is, that position isn't dynamically refreshed, it sticks with the first one it gets and I have tried to move it inside the while loop but it didn't work...so I'm kinda stuck at the moment...anyone has an idea of how I can achieve this? The image of the cloud is originally set at top:0 left:0

+1  A: 

why not use a looping background image and modify the background-position css property?

edit: I don't know if there's a jquery plugin to do this automatically, but it should be easy enough in old fashioned javascript with setInterval and modulus.

for example, your background image is 400 pixels wide, the css would be:

body { 
    background: transparent url(yourbackground.png) repeat-x scroll 0 0;
}

and javascript would be:

var BGPosition = 0;
var resetSize=400;
function scrollBodyBG() {
    BGPosition = ++BGPosition % resetSize;
    $('body').css("background-position", (-1 * BGPosition) + "px 0px");
}

var si = setInterval(scrollBodyBG,100)

Edit: Tested and working (without jquery) as

var BGPosition = 0;
var resetSize=400;
function scrollBodyBG() {
    BGPosition = ++BGPosition % resetSize;
    document.body.style.backgroundPosition = (-1 * BGPosition) + "px 0px";
}

document.addEventListener("DOMContentLoaded",function() { setInterval(scrollBodyBG,100);},false);

obviously this would need to change for IE event listener support

Jonathan Fingland
+1  A: 

Is the code you've posted a direct copy of what you're using? If so, then the call to animate isn't included in the while loop since it's cut short by the semi-colon. Try to use curly braces; it makes it much easier to maintain and look at. :)

while(p < w) {
     $('.clouds',this).stop().animate({left:"+=50000px"},{queue:false, duration:90000});
}


Also, I don't think that loop will ever complete. Neither of those variable's values are changing during iteration so it's never-ending. In order for it to work you'll need to modify (update) the 'p' variable within the loop, on every iteration.


EDIT: Actually, scratch that, the loop won't even begin because elem.position() returns an object, not a number (NaN). To make it work you'll need elem.position().left.

J-P
A: 

How about:

 while($('.clouds').position().left < $("#sky").width())
 {
       // do stuff
 }
Stobor
There's no point in testing for the width on every iteration; I don't think it changes...
J-P
@J-P: it may, it may not... That's not really clear from the snippet shown. Agreed that if it's known to be unchanging, then it can be factored out to a variable for performance...
Stobor
A: 

The only way to do this reliably is to listen property changes on DOM elements, using mutation events DOMAttrModified (for ex.) and the proprietary "onpropertychange" on IE.

Someone ported this to Jquery, here's the article.

http://www.west-wind.com/Weblog/posts/453942.aspx

SleepyCod
A: 

Put it all in a function, let's say moveCloud()

Then use the callback of the animate position and call that function. At the beginning of the function check the position of the cloud:

-If it is 0 move it to the right until it reaches maxwidth

-If it is the maxwidth, move it to the left until it reaches 0

Once the animation is done, the callback executes and calls again the function, which will move the cloud to the other side of the screen.

Olivvv
+1  A: 

I think this code will be useful to u.Try this out!

$('.clouds').animate({ top:0},{queue:false, duration:90000});
setInterval(function(){
if($(".clouds").position().top==0) alert("Rain");
},5000)

for every 5 seconds it will check for the position of a "cloud" class,if it is zero it will give alert!

for multiple clouds u can use below code

 setInterval(function(){
if($(".clouds").position().top==0){
 $(".clouds").each(function(){
  if($(this).position().top==0) $(this).remove();
 });
}
},1000)
Srikanth