Мне нужно создать скрипт, который имитирует анимацию снега в javascript (я бы предпочел не использовать canvas, если это возможно). Я застрял в этой точке, и я не знаю, где ошибка. Когда я запускаю программу, Google Chrome аварийно завершает работу и консоль не выдает ошибки. Я думаю, что ошибка связана с циклом или неправильными утверждениями. Я прилагаю код, надеясь на вашу помощь!

    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--;
                            }
                    }
            }
        }
    }

}

0
Mattia

1 ответ

Действительно, ваш код попадает в бесконечный цикл, потому что ваша переменная counterY не инициализирована и поэтому имеет значение undefined . Добавление одного в undefined дает NaN , поэтому вы никогда не доберетесь до этого оператора break .

Но что более важно, вам нужен другой подход, потому что даже если вы исправите это, вы никогда не увидите анимацию. Чтобы реально увидеть анимацию, вам нужно дать браузеру время обновить дисплей. Таким образом, цикл while и for (;;) исключен.

Вместо этого вызовите move один раз, а внутри этой функции в блоке else вызовите requestAnimationFrame (move) . Это даст браузеру время для перекраски, прежде чем move будет назван усилением. Удалите цикл for (;;) и удалите break .

Существует также логическая ошибка в том, как вы двигаетесь по горизонтали. Когда вы читаете текущий offsetLeft , нет смысла увеличивать counterX , поскольку это приведет к увеличению (относительному) переходу вправо (или влево). Вместо этого вы должны просто добавить (или вычесть) 1 к offsetLeft - вы можете покончить с counterX . Кроме того, не присваивайте это style.right , а style.left .

Итак, все вместе (см. Комментарии, где есть изменения):

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>
58582350