var ColorPalette = require('colorpalette'),
Item = require('burner').Item,
Mover = require('./mover'),
System = require('burner').System,
Utils = require('burner').Utils,
Vector = require('burner').Vector;
/**
* Creates a new ParticleSystem.
*
* @constructor
* @extends Mover
*/
function ParticleSystem(opt_options) {
Mover.call(this);
}
Utils.extend(ParticleSystem, Mover);
/**
* Initializes Particle.
* @param {Object} world An instance of World.
* @param {Object} [opt_options=] A map of initial properties.
* @param {number} [opt_options.width = 0] Width
* @param {number} [opt_options.height = 0] Height
* @param {string|Array} [opt_options.color = [255, 255, 255]] Color.
* @param {number} [opt_options.borderWidth = 0] Border width.
* @param {string} [opt_options.borderStyle = 'none'] Border style.
* @param {string|Array} [opt_options.borderColor = [255, 255, 255]] Border color.
* @param {number} [opt_options.borderRadius = 0] Border radius.
* @param {boolean} [opt_options.isStatic = true] If set to true, particle system does not move.
* @param {number} [opt_options.lifespan = 1000] The max life of the system. Set to -1 for infinite life.
* @param {number} [opt_options.life = 0] The current life value. If greater than this.lifespan, system is destroyed.
* @param {number} [opt_options.burst = 1] The number of particles to create per burst.
* @param {number} [opt_options.burstRate = 1] The number of frames between bursts. Lower values = more particles.
* @param {number} [opt_options.emitRadius = 3] The ParticleSystem adds this offset to the location of the Particles it creates.
* @param {Array} [opt_options.startColor = [255, 255, 255]] The starting color of the particle's palette range.
* @param {Array} [opt_options.endColor = [255, 0, 0]] The ending color of the particle's palette range.
* @param {Object} [opt_options.particleOptions] A map of options for particles created by system.
*/
ParticleSystem.prototype.init = function(world, opt_options) {
ParticleSystem._superClass.init.call(this, world, opt_options);
var options = opt_options || {};
this.width = options.width || 0;
this.height = options.height || 0;
this.color = options.color || [255, 255, 255];
this.borderWidth = options.borderWidth || 0;
this.borderStyle = options.borderStyle || 'none';
this.borderColor = options.borderColor || [255, 255, 255];
this.borderRadius = options.borderRadius || 0;
this.isStatic = typeof options.isStatic === 'undefined' ? true : options.isStatic;
this.lifespan = typeof options.lifespan === 'undefined' ? -1: options.lifespan;
this.life = typeof options.life === 'undefined' ? -1 : options.life;
this.burst = typeof options.burst === 'undefined' ? 1 : options.burst;
this.burstRate = typeof options.burstRate === 'undefined' ? 4 : options.burstRate;
this.emitRadius = typeof options.emitRadius === 'undefined' ? 3 : options.emitRadius;
this.startColor = options.startColor || [255, 255, 255];
this.endColor = options.endColor || [255, 0, 0];
this.particleOptions = options.particleOptions || {
width : 15,
height : 15,
lifespan : 50,
borderRadius : 100,
checkWorldEdges : false,
acceleration: null,
velocity: null,
location: null,
maxSpeed: 3,
fade: true,
shrink: true
};
if (this.particleOptions.acceleration) {
this.initParticleAcceleration = new Vector(this.particleOptions.acceleration.x,
this.particleOptions.acceleration.y);
}
var pl = new ColorPalette();
pl.addColor({ // adds a random sampling of colors to palette
min: 12,
max: 24,
startColor: this.startColor,
endColor: this.endColor
});
this.clock = 0;
this.beforeStep = function () {
var location, offset,
initAcceleration = this.initParticleAcceleration;
if (this.life < this.lifespan) {
this.life += 1;
} else if (this.lifespan !== -1) {
System.remove(this);
return;
}
if (this.clock % this.burstRate === 0) {
location = new Vector(this.location.x, this.location.y); // use the particle system's location
offset = new Vector(1, 1); // get the emit radius
offset.normalize();
offset.mult(this.emitRadius); // expand emit radius in a random direction
offset.rotate(Utils.getRandomNumber(0, Math.PI * 2, true));
location.add(offset);
for (var i = 0; i < this.burst; i++) {
this.particleOptions.world = this.world;
this.particleOptions.life = 0;
this.particleOptions.color = pl.getColor();
this.particleOptions.borderStyle = 'solid';
this.particleOptions.borderColor = pl.getColor();
this.particleOptions.boxShadowColor = pl.getColor();
if (initAcceleration) {
this.particleOptions.acceleration = new Vector(initAcceleration.x, initAcceleration.y);
}
this.particleOptions.location = location;
System.add('Particle', this.particleOptions);
}
}
this.clock++;
};
};
/**
* Updates the corresponding DOM element's style property.
* @function draw
* @memberof ParticleSystem
*/
ParticleSystem.prototype.draw = function() {
var cssText = this.getCSSText({
x: this.location.x - (this.width / 2),
y: this.location.y - (this.height / 2),
angle: this.angle,
scale: this.scale || 1
});
this.el.style.cssText = cssText;
};
/**
* Concatenates a new cssText string.
*
* @function getCSSText
* @memberof ParticleSystem
* @param {Object} props A map of object properties.
* @returns {string} A string representing cssText.
*/
ParticleSystem.prototype.getCSSText = function(props) {
return Item._stylePosition.replace(/<x>/g, props.x).replace(/<y>/g, props.y).replace(/<angle>/g, props.angle).replace(/<scale>/g, props.scale) + ';';
};
module.exports = ParticleSystem;