(function(global) {
"use strict";
if (!global.particle) {
global.particle = {};
}
/**
* @class particle.Position
* @desc This plugin gives every particle a random position within a
* given radius. The inner radius parameter may be used to specify a radius
* that particles must be spawned outside of.
* @param {Number} xval The x value from which the radius should extend.
* @param {Number} yval The y value from which the radius should extends
* @param {Number} radius A radius about the x,y coordinate to spawn
* particles within.
* @param {Number} innerRadius A radius about the x,y coordinate to spawn
* particles outside of. If the innerRadius >= radius, radius will be
* resized to accommodate.
* @constructor
* @author thegoldenmule
*/
global.particle.Position = function(xval, yval, radius, innerRadius) {
this.x = undefined === xval ? 0 : xval;
this.y = undefined === yval ? 0 : yval;
this.innerRadius = undefined === innerRadius ? 0 : innerRadius;
if (undefined === radius) {
radius = 10;
}
if (radius <= this.innerRadius) {
radius = this.innerRadius + 1;
}
this.radius = radius;
};
global.particle.Position.prototype = {
constructor: global.particle.Position,
/**
* @function global.particle.Position#initialize
* @desc Called as part of the particle plugin lifecycle. Initialize is
* called on a particle when a particle is spawned.
*
* Note that particles are reused!
*
* @param {ParticleEmitter} emitter The ParticleEmitter acting upon
* this particle.
* @param {Particle} particle The Particle to initialize.
*/
initialize: function(emitter, particle) {
particle.transform.position.x = this.x + (Math.random() - 0.5) * Math.random() * (this.radius - this.innerRadius);
particle.transform.position.y = this.y + (Math.random() - 0.5) * Math.random() * (this.radius - this.innerRadius);
if (0 !== this.innerRadius) {
var randomAngle = Math.random() * 2 * Math.PI;
particle.transform.position.x += this.innerRadius * Math.sin(randomAngle);
particle.transform.position.y += this.innerRadius * Math.cos(randomAngle);
}
}
};
/**
* @class particle.Rotation
* @desc This plugin chooses a random rotation for each particle between min and max.
* @param {Number} min The minimum value for a rotation.
* @param {Number} max The maximum value for a rotation.
* @constructor
* @author thegoldenmule
*/
global.particle.Rotation = function(min, max) {
this.min = undefined === min ? 0 : min;
this.max = undefined === max ? Math.PI * 2 : max;
};
global.particle.Rotation.prototype = {
constructor: global.particle.Rotation,
/**
* @function global.particle.Rotation#initialize
* @desc Called as part of the particle plugin lifecycle. Initialize is
* called on a particle when a particle is spawned.
*
* Note that particles are reused!
*
* @param {ParticleEmitter} emitter The ParticleEmitter acting upon
* this particle.
* @param {Particle} particle The Particle to initialize.
*/
initialize: function(emitter, particle) {
particle.transform.rotationInRadians = this.min + Math.random() * (this.max - this.min);
}
};
/**
* @class particle.Velocity
* @desc The velocity plugin chooses a velocity using polar notation, i.e.
* given an angle range and a magnitude range, it creates a vector that is
* then assigned as each particle's velocity.
* @param {Number} minAngle The minimum angle of the velocity vector.
* @param {Number} maxAngle The maximum angle of the velocity vector.
* @param {Number} minMagnitude The minimum magnitude of the velocity
* vector.
* @param {Number} maxMagnitude The maximum magnitude of the velocity
* vector.
* @constructor
* @author thegoldenmule
*/
global.particle.Velocity = function(minAngle, maxAngle, minMagnitude, maxMagnitude) {
this.minAngle = minAngle;
this.maxAngle = maxAngle;
this.minMagnitude = minMagnitude;
this.maxMagnitude = maxMagnitude;
};
global.particle.Velocity.prototype = {
constructor: global.particle.Velocity,
/**
* @function global.particle.Velocity#initialize
* @desc Called as part of the particle plugin lifecycle. Initialize is
* called on a particle when a particle is spawned.
*
* Note that particles are reused!
*
* @param {ParticleEmitter} emitter The ParticleEmitter acting upon
* this particle.
* @param {Particle} particle The Particle to initialize.
*/
initialize: function(emitter, particle) {
// pick a random angle
var angle = (this.minAngle + Math.random() * (this.maxAngle - this.minAngle));
var magnitude = (this.minMagnitude + Math.random() * (this.maxMagnitude - this.minMagnitude));
particle.vx = -Math.cos(angle) * magnitude;
particle.vy = -Math.sin(angle) * magnitude;
}
};
/**
* @class particle.Acceleration
* @desc Applies a constant acceleration to each particle throughout a
* particle's lifetime.
* @param {Number} xval Acceleration to apply in the x direction.
* @param {Number} yval Acceleration to apply in the y direction.
* @constructor
* @author thegoldenmule
*/
global.particle.Acceleration = function(xval, yval) {
this.x = xval;
this.y = yval;
};
global.particle.Acceleration.prototype = {
constructor: global.particle.Acceleration,
/**
* @function global.particle.Acceleration#update
* @desc Called as part of the particle plugin lifecycle. Update is
* called every frame to update a particle.
* @param {ParticleEmitter} emitter The ParticleEmitter instance.
* @param {Particle} particle The particle to act on.
*/
update: function(emitter, particle) {
particle.ax = this.x;
particle.ay = this.y;
}
};
/**
* @class particle.Lifetime
* @desc This plugin gives each particle a lifetime between min and max.
* @param {Number} min The minimum lifetime to give each particle.
* @param {Number} max The maximum lifetime to give each particle.
* @constructor
* @author thegoldenmule
*/
global.particle.Lifetime = function(min, max) {
this.min = min;
this.max = max;
};
global.particle.Lifetime.prototype = {
constructor: global.particle.Lifetime,
/**
* @function global.particle.Lifetime#initialize
* @desc Called as part of the particle plugin lifecycle. Initialize is
* called on a particle when a particle is spawned.
*
* Note that particles are reused!
*
* @param {ParticleEmitter} emitter The ParticleEmitter acting upon
* this particle.
* @param {Particle} particle The Particle to initialize.
*/
initialize: function(emitter, particle) {
particle.lifetime = (this.min + Math.random() * (this.max - this.min));
}
};
/**
* @class particle.Attractor
* @desc The Attractor plugin specifies a point which attracts or repels
* particles.
* @param {Number} x The x position to attract to or repel from.
* @param {Number} y The y position to attract to or repel from.
* @param {Number} amount The magnitude of the force of attraction. If this
* is negative it acts as a repelling force.
* @constructor
* @author thegoldenmule
*/
global.particle.Attractor = function(x, y, amount) {
this.x = x;
this.y = y;
this.amount = amount;
};
global.particle.Attractor.prototype = {
constructor: global.particle.Attractor,
/**
* @function global.particle.Attractor#update
* @desc Called as part of the particle plugin lifecycle. Update is
* called every frame to update a particle.
* @param {ParticleEmitter} emitter The ParticleEmitter instance.
* @param {Particle} particle The particle to act on.
*/
update: function(emitter, particle) {
particle.ax = this.x - particle.transform.position.x / this.amount;
particle.ay = this.y - particle.transform.position.y / this.amount;
}
};
/**
* @class particle.ParticlePropertyAnimator
* @desc Animates an arbitrary property on particles.
* @param {String} propName The name of the property to animate.
* @param {AnimationCurve} curve The animation curve that defines the
* animation.
* @param {Number} scale A scalar by which to multiply the AnimationCurve.
* @constructor
*/
global.particle.ParticlePropertyAnimator = function(propName, curve, scale) {
this.propName = propName;
this.curve = curve;
this.scale = scale;
};
global.particle.ParticlePropertyAnimator.prototype = {
constructor: global.particle.ParticlePropertyAnimator,
/**
* @function global.particle.ParticlePropertyAnimator#update
* @desc Called as part of the particle plugin lifecycle. Update is
* called every frame to update a particle.
* @param {ParticleEmitter} emitter The ParticleEmitter instance.
* @param {Particle} particle The particle to act on.
*/
update: function(emitter, particle) {
particle[this.propName] = this.scale = this.curve.evaluate(particle.elapsedTime / particle.lifetime);
}
};
/*
* @class particle.ScaleAnimator
* @desc Animates a Particle's scale.
* @param {AnimationCurve} curve The AnimationCurve instance.
* @param {Number} scale A scalar by which to multiply the AnimationCurve.
* @constructor
* @author thegoldenmule
*/
global.particle.ScaleAnimator = function(curve, scale) {
this.curve = curve;
this.scale = scale;
};
global.particle.ScaleAnimator.prototype = {
constructor: global.particle.ScaleAnimator,
/**
* @function global.particle.ScaleAnimator#update
* @desc Called as part of the particle plugin lifecycle. Update is
* called every frame to update a particle.
* @param {ParticleEmitter} emitter The ParticleEmitter instance.
* @param {Particle} particle The particle to act on.
*/
update: function(emitter, particle) {
var scale = this.scale * this.curve.evaluate(particle.elapsedTime / particle.lifetime);
particle.transform.scale.x = particle.transform.scale.y = scale;
}
};
/**
* @class particle.AlphaAnimator
* @desc Animates a particle's alpha. This class is simply shorthand for
* using a ParticlePropertyAnimator.
* @param {AnimationCurve} curve An AnimationCurve instance to define the
* animation.
* @param {Number} scale A scalar by which to multiply the AnimationCurve.s
* @constructor
* @author thegoldenmule
*/
global.particle.AlphaAnimator = function(curve, scale) {
return new global.particle.ParticlePropertyAnimator("alpha", curve, scale);
};
/**
* @class particle.RotationAnimator
* @desc Animates a particle's rotation.
* @param {AnimationCurve} curve The curve the defines the animation.
* @param {Number} scale A scalar by which to multiply the curve.
*/
global.particle.RotationAnimator = (function() {
var id = 0;
return function(curve, scale) {
this.__guid = "__rotationRate" + id++;
this.curve = curve;
this.scale = scale;
};
})();
global.particle.RotationAnimator.prototype = {
constructor: global.particle.RotationAnimator,
initialize: function(emitter, particle) {
particle[this.__guid] = particle.transform.rotationInRadians;
},
/**
* @function global.particle.RotationAnimator#update
* @desc Called as part of the particle plugin lifecycle. Update is
* called every frame to update a particle.
* @param {ParticleEmitter} emitter The ParticleEmitter instance.
* @param {Particle} particle The particle to act on.
*/
update: function(emitter, particle, dt) {
particle.transform.rotationInRadians =
particle[this.__guid] + this.scale * this.curve.evaluate(particle.elapsedTime / particle.lifetime);
}
};
})(this);