我必须创建一个脚本来模拟javascript中雪的动画(如果可能,我希望不使用画布)。我被困在这一点上,我不知道错误在哪里。当我运行程序谷歌浏览器崩溃且控制台没有给我错误时,我认为该错误是由于循环或某些不正确的语句所致,我附上了代码,希望对您有所帮助!
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 :(得分:1)
实际上,由于变量counterY
没有初始化,因此它的值为undefined
,因此代码进入了无限循环。在undefined
中添加一个将得到NaN
,因此您永远不会遇到该break
语句。
但更重要的是,您需要一种不同的方法,因为即使您解决了此问题,也永远不会看到动画的发生。为了实际观看动画,您需要给浏览器一些时间来更新显示。因此,while
和for(;;)
循环是不可能的。
请一次调用move
,然后在该函数内的else
块中调用requestAnimationFrame(move)
。这将使浏览器有时间在move
被称为增益之前重新绘制。删除for(;;)
循环,然后删除break
。
水平移动也存在逻辑错误。当您阅读当前的offsetLeft
时,增加counterX
毫无意义,因为这会导致向右(或向左)跳跃(相对)跳跃。取而代之的是,您只需要在offsetLeft
上加上(或减去)1即可取消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>