1 function Particle(stage)
2 {
3     this.stage = stage;
4     this.rotater = Stage.randomRotater();
5     this.reset();
6     this.move();
7 }
9 Particle.prototype =
10 {
11     reset: function()
12     {
13         var randSize = Math.pow(Math.random(), 4) * 25 + 15;
14         this.size = new Point(randSize, randSize);
15         this.maxPosition = this.stage.size.subtract(this.size);
16         this.position = new Point(this.stage.size.x / 2, this.stage.size.y / 4);
18         var angle = Stage.randomInt(0, this.stage.emitSteps) / this.stage.emitSteps * Math.PI * 2 + Date.now()/1000*this.stage.emissionSpin;
19         this._velocity = new Point(Math.sin(angle), Math.cos(angle))
20             .multiply(Stage.random(.8, 1.2));
21     },
23     animate: function(timeDelta)
24     {
25         this.rotater.next(timeDelta);
28         this._velocity.y += 0.03;
30         // If particle is going to move off right side
31         var maxX = this.stage.size.x - this.size.x;
32         if (this.position.x > this.maxPosition.x) {
33             if (this._velocity.x > 0)
34                 this._velocity.x *= -1;
35             this.position.x = this.maxPosition.x;
36         } else if (this.position.x < 0) {
37             // If particle is going to move off left side
38             if (this._velocity.x < 0)
39                 this._velocity.x *= -1;
40             this.position.x = 0;
41         }
43         // If particle is going to move off bottom side
44         if (this.position.y > this.maxPosition.y) {
45             // Adjust direction but maintain magnitude
46             var magnitude = this._velocity.length();
47             this._velocity.x *= 1.5 + .005 * this.size.x;
48             this._velocity = this._velocity.normalize().multiply(magnitude);
49             if (Math.abs(this._velocity.y) < 0.7)
50                 this.reset();
51             else {
52                 if (this._velocity.y > 0)
53                     this._velocity.y *= -0.999;
54                 this.position.y = this.maxPosition.y;
55             }
56         } else if (this.position.y < 0) {
57             // If particle is going to move off top side
58             var magnitude = this._velocity.length();
59             this._velocity.x *= 1.5 + .005 * this.size.x;
60             this._velocity = this._velocity.normalize().multiply(magnitude);
61             if (this._velocity.y < 0)
62                 this._velocity.y *= -0.998;
63             this.position.y = 0;
64         }
66         this.move();
67     },
69     move: function()
70     {
71     }
72 }
74 ParticlesStage = Utilities.createSubclass(Stage,
75     function()
76     {
77         Stage.call(this);
78         this.particles = [];
79     }, {
81     initialize: function(benchmark, options)
82     {
83         Stage.prototype.initialize.call(this, benchmark, options);
84         this.emissionSpin = Stage.random(0, 3);
85         this.emitSteps = Stage.randomInt(4, 6);
86     },
88     animate: function(timeDelta)
89     {
90         var offset = (Date.now() / 2000) % 1;
91         this.element.style.background = [
93             offset * 360,
94             "deg, hsl(",
95             offset * 360,
96             ", 50%, 80%), hsl(",
97             (offset + .1) * 360,
98             ", 50%, 80%))"
99         ].join("");
101         timeDelta /= 4;
102         this.particles.forEach(function(particle) {
103             particle.animate(timeDelta);
104         });
105     },
107     tune: function(count)
108     {
109         if (count == 0)
110             return;
112         if (count > 0) {
113             for (var i = 0; i < count; ++i)
114                 this.particles.push(this.createParticle());
115             return;
116         }
118         count = Math.min(-count, this.particles.length);
120         if (typeof(this.willRemoveParticle) == "function") {
121             for (var i = 0; i < count; ++i)
122                 this.willRemoveParticle(this.particles[i]);
123         }
125         this.particles.splice(0, count);
126     },
128     complexity: function()
129     {