Мне нужно создать скрипт, имитирующий анимацию снега в javascript (я бы предпочел без использования холста, если это возможно). Я застрял на этом этапе и не знаю, в чем ошибка. когда я запускаю программу, 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--;
}
}
}
}
}
}
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>
Похожие вопросы
Новые вопросы
javascript
По вопросам программирования на ECMAScript (JavaScript/JS) и его различных диалектах/реализациях (кроме ActionScript). Обратите внимание, что JavaScript — это НЕ Java. Включите все теги, относящиеся к вашему вопросу: например, [node.js], [jQuery], [JSON], [ReactJS], [angular], [ember.js], [vue.js], [typescript], [стройный] и т. д.