Mattia
Mattia

Reputation: 3

I'm stuck in a project about snow animation in javascript

I have to create a script that simulates the animation of snow in javascript (I would prefer without using canvas if possible). I'm stuck at this point and I don't know where the mistake is. when I run the program google chrome crashes and the console does not give me errors, I think the error is due to a loop or some incorrect statements, I am attaching the code hoping for your help!

    var direction=true; //true=right false =left
    var active=true;     //if true run the cycle,false stops the cycle
    function startSnow() {

var _snowflakes = new Array(30);    
var wid=50;                       //distance from a snowflake to another
var counterX;                     //var for editing the x position
var counterY;                     //var for editing the y position
for (var i=0; i< 30; i++)         //cycle that initializes snowflakes
{
    _snowflakes[i] = document.createElement("img");   
    _snowflakes[i].setAttribute("src","snowflake.png"); // setting the image
    _snowflakes[i].setAttribute("class", "snowflake"); //setting the css style
    _snowflakes[i].style.visibility ="inherit";       //when the function is running snowflakes have to be visible, when it finishes they have to be invisible
    _snowflakes[i].style.right = (wid*i)+"px";        //set the distance from the left margin
    _snowflakes[i].style.top = "30px";           // set the distance from the top
    document.getElementById("background").appendChild(_snowflakes[i]);
}
while(active)
{
        move();
}
function move()  //function that moves the snowflake
        {
            for(;;)
        {
            if(counterY>=600)   //when the snowflake reaches 600px from the top the function has to stop and hide snowflakes
            {
                for(var i=0;i<30;i++)
                    _snowflakes[i].style.visibility = "hidden";
                active=false;
                break;
            }                
             else
            {
                if ((counterY%50)==0)
                    {
                        direction=!direction   //every 50 Y pixels the snoflake change direction
                    }
                counterY++;
                for(var i=0;i<30;i++)
                    {
                        _snowflakes[i].style.top = counterY+"px";       //Y movement     
                        if (direction==true)
                            {
                                _snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px";      //x right movement
                                counterX++;
                            }
                        else
                            {
                                _snowflakes[i].style.right = (_snowflakes[i].offsetLeft+counterX) + "px";      //x left movement
                                counterX--;
                            }
                    }
            }
        }
    }

}

Upvotes: 0

Views: 75

Answers (1)

trincot
trincot

Reputation: 350841

Indeed, your code gets into an infinite loop because your variable counterY is not initialised and so it has the value undefined. Adding one to undefined gives NaN, and so you never get to that break statement.

But more importantly, you need a different approach, because even if you fix this, you'll never see an animation happening. For actually seeing the animation, you need to give the browser time to update the display. So a while and for(;;) loop are out of the question.

Instead call move once, and inside that function, in the else block, call requestAnimationFrame(move). This will give the browser time to repaint before move is called a gain. Remove the for(;;) loop, and remove the break.

There is also a logical error in how you move horizontally. As you read the current offsetLeft it makes no sense to increment counterX as that will lead to increasing (relative) jumps to the right (or left). Instead you should just add (or subtract) 1 to offsetLeft -- you can do away with counterX. Also, don't assign that to style.right, but to style.left.

So everything put together (cf. comments where there is a change):

var direction=true;
var active=true;

function startSnow() {    
    var _snowflakes = new Array(30);    
    var wid=50;
    // var counterX = 0; -- not used.
    var counterY = 0; // Need to initialise!
    for (var i=0; i< 30; i++) {
        _snowflakes[i] = document.createElement("img");   
        _snowflakes[i].setAttribute("src", "snowflake.png");
        _snowflakes[i].setAttribute("alt", "❄"); // added for when image not found
        _snowflakes[i].setAttribute("class", "snowflake");
        _snowflakes[i].style.visibility = "inherit";
        _snowflakes[i].style.left = (wid*i)+"px"; // assign to style.left
        _snowflakes[i].style.top = "30px";
        document.getElementById("background").appendChild(_snowflakes[i]);
    }

    // No while loop. Just call move    
    move();
    
    function move() {
        //No for (;;) loop
        if (counterY>=600) {
            for (var i=0;i<30;i++) {
                _snowflakes[i].style.visibility = "hidden"; // you forgot the underscore
            }
            active=false;
            // No break -- function will just return
        } else {
            if ((counterY%50)==0) {
                direction=!direction
            }
            counterY++;
            for (var i=0;i<30;i++) {
                _snowflakes[i].style.top = counterY+"px";
                if (direction==true) {
                    // assign to style.left, 
                    _snowflakes[i].style.left = (_snowflakes[i].offsetLeft+1) + "px"; // add 1
                } else {
                    _snowflakes[i].style.left = (_snowflakes[i].offsetLeft-1) + "px"; // sub 1
                }
            }
            requestAnimationFrame(move); // schedule next run of this function
        }
    }
}
 
startSnow(); // Need to start it!
#background { width: 800px; height: 800px }
.snowflake { position: absolute; font-size: 40px }
<div id="background">
</div>

Upvotes: 1

Related Questions