我会重写您的部分代码以启用此功能。例如我会重写你的Ring类如下:
var Ring = defclass({
constructor: function (x, y, r) {
this.x = x;
this.y = y;
this.r = r;
},
draw: function (context) {
context.beginPath();
context.arc(this.x, this.y, this.r, 0, Math.PI * 2);
context.stroke();
return this;
},
addRadius: function (r) {
return new Ring(this.x, this.y, this.r + r);
}
});
您的Ring 类构造函数现在采用x、y 和半径r。 addRadius 函数返回一个新的Ring,而不是改变原来的。这很好,因为不变性使您的代码更易于使用。哦,defclass 被声明为:
function defclass(prototype) {
var constructor = prototype.constructor;
constructor.prototype = prototype;
return constructor;
}
然后我们为您的眼睛创建两个环:
var radius = 10;
var delta = 0.1;
var left = new Ring(cx - (cx / 3.6), cy - 5, radius);
var right = new Ring(cx + (cx / 3.6), cy - 10, radius);
之后我们调用动画循环:
var interval = 50 / 3;
var start = Date.now();
loop(start, [left, right]);
由于我们希望以 60 FPS 的速度播放,因此间隔为 1000 / 60,可以简化为 50 / 3。动画循环定义如下:
function loop(last, rings) {
var next = last + interval;
context.clearRect(0, 0, width, height);
var newRings = rings.map(function (ring) {
return ring.draw(context).addRadius(delta);
});
var now = Date.now();
setTimeout(loop, next - now, next,
Math.floor((now - start) / 1000) === rings.length / 2 ?
[left, right].concat(newRings) : newRings);
}
这是发生了什么:
- 首先我们清除屏幕。
- 然后我们绘制所有环并增加它们的大小。
- 如果一秒钟过去了,我们会向数组中添加两个新环。
- 最后,我们计算何时再次调用
loop,以便在正确的interval 之后触发。
查看演示:http://jsfiddle.net/LAr76/