track : function(x, y, top, ampl) {
return {
top : top + 2,
x : x + ampl * Math.sin(top / 20),
y : (top / this.screenHeight < 0.65) ? y + 2 : 1 + y + ampl * Math.cos(top / 25)
};
}
这个程序发送雪花以正弦波方式飞行。
但它是如何做到的?请解释一下。
Math.sin
使用x
;和Math.cos
y
,但我见过的其他片段以相反的方式使用它们。为什么?为什么要top/20
和top/25
?
整个代码:
<script type="text/javascript">
var snowflakes = { // Namespace
/* Settings */
pics : [
['snow.gif' , 24, 24],
['snow2.gif', 24, 24],
['snow3.gif', 24, 24]
],
track : function(x, y, top, ampl) {
return {
top : top + 2,
x : x + ampl * Math.sin(top / 20),
y : (top / this.screenHeight < 0.65) ? y + 2 : 1 + y + ampl * Math.cos(top / 25)
};
},
quantity : 30,
minSpeed : 20, // 1 - 100, minSpeed <= maxSpeed
maxSpeed : 40, // 1 - 100, maxSpeed >= minSpeed
isMelt : true, // true OR false
/* Properties */
screenWidth : 0,
screenHeight : 0,
archive : [],
timer : null,
/* Methods */
addHandler : function(object, event, handler, useCapture) {
if (object.addEventListener) object.addEventListener(event, handler, useCapture);
else if (object.attachEvent)object.attachEvent('on' + event, handler);
else object['on' + event] = handler;
},
create : function(o, index) {
var rand = Math.random();
this.timer = null;
this.o = o;
this.index = index;
this.ampl = 3 + 7*rand;
this.type = Math.round((o.pics.length - 1) * rand);
this.width = o.pics[this.type][1];
this.height = o.pics[this.type][2];
this.speed = o.minSpeed + (o.maxSpeed - o.minSpeed) * rand;
this.speed = 1000 / this.speed;
this.deviation = o.maxDeviation * rand;
this.x = o.screenWidth * rand - this.width;
this.y = 0 - this.height;
this.top = this.y;
this.img = document.createElement('img');
this.img.src = o.pics[this.type][0];
this.img.style.top = this.y + 'px';
this.img.style.position = 'absolute';
this.img.style.zIndex = 10000;
this.img.style.left = this.x + 'px';
this.img.obj = this;
if (o.isMelt) this.img.onmouseover = function() {
clearTimeout(this.obj.timer);
this.obj.timer = null;
this.parentNode.removeChild(this);
}
document.body.appendChild(this.img);
this.move();
},
init : function() {
this.screenWidth = window.innerWidth ? window.innerWidth : (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.offsetWidth);
this.screenWidth = navigator.userAgent.toLowerCase().indexOf('gecko') == -1 ? this.screenWidth : document.body.offsetWidth;
this.screenHeight = window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight);
this.screenScroll = (window.scrollY) ? window.scrollY : document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
this.archive[this.archive.length] = new this.create(this, this.archive.length);
clearTimeout(this.timer);
this.timer = null
this.timer = setTimeout(function(){snowflakes.init()}, 60000 / this.quantity);
}
};
snowflakes.create.prototype = {
move : function() {
var newXY = this.o.track(this.x, this.y, this.top, this.ampl);
this.x = newXY.x;
this.y = newXY.y;
this.top = newXY.top;
if (this.y < this.o.screenHeight + this.o.screenScroll - this.height) {
this.img.style.top = this.y + 'px';
this.x = this.x < this.o.screenWidth - this.width ? this.x : this.o.screenWidth - this.width;
this.img.style.left = this.x + 'px';
var index = this.index;
this.timer = setTimeout(function(){snowflakes.archive[index].move()}, this.speed);
} else {
delete(this.o.archive[this.index]);
this.img.parentNode.removeChild(this.img);
}
}
};
snowflakes.addHandler(window, 'load', function() {snowflakes.init();});
snowflakes.addHandler(window, 'resize', function() {snowflakes.init();});
</script>
答案 0 :(得分:10)
基本正弦函数定义为:
f(x) = A sin(wt + p)
其中
这些因素决定了f的图形如何。
幅度可以被认为是比例因子,A越大,f的峰值和低点越大(绝对值)。
频率决定正弦函数在其重新开始之前运行所有值的速度 - 正弦是一个周期函数。 k越大,f越快就会经历一个周期。
p是阶段,将其视为“移动”函数的起点向右(正p)或左(负)。很难用文字解释,看看here的图表。
您在示例中提供的功能是
的通用版本f: R->R², f(t)=(sin(t), cos(t))
parametrizations of the unit circle 中的哪一个({1}}。如果你单调地增加t并绘制x(sin(t))和y(cos(t)),你将在一个半径为1的圆上飞行一个点。
您的广义功能
f: R->R², f(t) = (A sin(1/wt), A cos(1/wt)), w > 1
在你的情况下,对于x坐标,A = ampl,t = top,w = 20,对于y坐标,w = 25。 w的这些轻微偏差使得运动变得紧张,因此它不再是一个完美的圆形,而是一些“扭曲的”椭圆形 - 我想,雪花片不会落入完美的圆形中。此外,这使得片状物的路径看起来比直线完美的圆圈更随机。虽然这是一种幻觉,但这也是非常确定的并且仍然是周期性的 - 只是x和y运动是“不同步的”所以它需要更长的时间才能完成一个周期。
w被选择&gt; 1“减慢”圆周运动。你选择w越大,频率越低,你的移动点就会慢得多。
您选择的A越大,您的圆圈就越大。
答案 1 :(得分:5)
它只会使正弦波更大,因此可以更容易地观察到曲线。
这是我尝试制作的小提琴。如果我将20和25更改为1,则运动变得不那么有趣。 http://jsfiddle.net/AbM9z/1/
了解调用函数的值将会有所帮助。