我正在做一个小的JavaScript动画,希望小div
可以沿着正弦波移动,而目前水平路径工作正常(只是直线)。我几乎可以确定Y
轴的数学公式是错误的。我试图用我发现的一些例子来纠正它,但它们都没有为我工作。在我尝试的所有可能性中,Y
轴被忽略,小盒子只是水平移动。
我怎样才能解决这个问题,所以这个动作沿着正弦波传播?我知道使用jQuery或使用html 5可以更容易地做到这一点,但我只是想知道我的原始代码有什么问题......如果可能的话我宁愿解决这个问题。
function animate() {
xnow = item.style.left;
item.style.left = parseInt(xnow)+1+'px';
ynow = item.style.top;
item.style.top = ynow + (Math.sin((2*Math.PI*xnow)/document.width))*document.heigth;
setTimeout(animate,20);
}
这里的完整代码: JSFiddle
答案 0 :(得分:7)
我发现您的代码有几个问题:
xnow
包含以下格式的字符串:###px
您无法将其相乘,因此请在parseInt()
来电中使用Math.sin()
。ynow
,它需要parseInt()
。px
。2*Math.PI
与xnow
(仅包含整数)相乘时,sin()
函数将始终返回0
。所以你不会得到正弦运动。您需要将xnow
除以您想要用来执行完整正弦运动的x步数Math.sin()
返回介于-1和+1之间的值,因此您需要将其乘以振幅才能看到(更清晰)效果。为了保持它与你设计的一样多,它会变成这样的东西(需要50个移动步骤来完成正弦并使用10像素的振幅):
function animate() {
xnow = parseInt(item.style.left);
item.style.left = (xnow+1)+'px';
ynow = parseInt(item.style.top);
item.style.top = (ynow+Math.sin(2*Math.PI*(xnow/50))*10) + "px";
setTimeout(animate,20);
}
如上所述:使用包含值的一些全局变量(而不是一直使用parseInt()
)要好得多。
答案 1 :(得分:7)
sin函数的形式为y = a * sin(b * x)+ c,其中c是函数的y-中点(或函数振荡的水平线),其中a是幅度(从y = c的最大y偏移量)和b是周期(每个波的x = 2 * pi段的数量)。
鉴于此,并且我们知道sin波从-a到+ a振荡,我们知道我们的偏移量(c)应该是1)是常数,2)在我们的上限和下限之间。为此,我们可以使用
c = document.height / 2;
如果您希望对象遍历整个屏幕,您的幅度将与c的值相同。在测试中,你会发现这会让它超越页面的底部,所以让我们把它做到90%。
a = 0.9 * c;
对于整个页面的1周期,你需要使b乘以一个因子,使得它将是2 * pi的分数。在这种情况下
b = 2*Math.PI/document.width;
在每次迭代中,不需要获取ynow
的值,它是xnow
的函数。你可以按照
xnow = parseInt(item.top.left) + 5;
然后用
计算新的y ynow = c + a * Math.sin(b * xnow);
。
然后设置项目的样式。
item.style.left = xnow + 'px';
item.style.top = ynow + 'px';
如果有什么不清楚,请告诉我。问候。
答案 2 :(得分:2)
您需要在parseInt()
上使用xnow
。您还需要将“px”添加到数字的末尾,以生成格式正确的字符串。
此代码有效:
function animate() {
xnow = parseInt(item.style.left);
item.style.left = xnow+1+'px';
item.style.top = 200 + (Math.sin((2*Math.PI*xnow)/200))*document.height+'px';
setTimeout(animate,20);
}
答案 3 :(得分:1)
有几个错误:
height
拼写错误xnow
解析为int ynow
解析为int(尽管实际上并不需要,请参见下文)"px"
添加到item.style.top
我建议从(400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px"
开始,然后再玩它。 400
是基于正弦波的水平轴。如果使用ynow
代替常数,则会产生累积效果(波浪将比您想要的高得多,或者水平轴会随着时间的推移而变化)。
document.width
是一个完整句点的宽度。 200
是峰值幅度(从水平到峰值的距离 - document.height
会在两个方向上将屏幕推离屏幕)。插入此功能代替当前功能,然后您可以使用数字:
function animate() {
xnow = parseInt(item.style.left);
item.style.left = xnow+1+'px';
item.style.top = (400 + Math.sin(2*Math.PI*xnow/document.width) * 200) + "px";
setTimeout(animate,20);
}