Source: particle/DefaultParticlePlugins.js

(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);