Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body>
</body>
</html>
 
var canvas = document.createElement("canvas");
        var ctx = canvas.getContext("2d");
        canvas.width = 500;
        canvas.height = 500;
        document.body.appendChild(canvas);
        var particles = [];
        
        var Emitter = function(x, y, filter) {
            this.filter = filter || {};
            this.x = x;
            this.y = y;
            this.particles = [];
        };
        
        Emitter.prototype.render = function(createNewParticles) {
            if(this.filter().maxParticles > this.particles.length || this.filter().maxParticles == null) {
                if(createNewParticles !== false) {
                    for(var i = 0; i < (this.filter().particles || 1); i++) {
                        var filter = this.filter();
                        filter.x = (filter.x + this.x) || this.x;
                        filter.y = (filter.y + this.y) || this.y;
                        filter.maxParticles = filter.maxParticles || 0;
                        this.particles.push(new Particle(filter));
                    }
                }
            }
            
            for(var i = 0; i < this.particles.length; i++) {
                if(this.particles[i].isDead) {
                    this.particles.splice(i, 1);
                }
                else {
                    this.particles[i].update();
                    this.particles[i].render();
                }
            }
        };
        
        var Particle = function(filter) {
            this.x = filter.x || 0;
            this.y = filter.y || 0;
            this.vx = filter.vx || Math.random() * 6 - 3;
            this.vy = filter.vy || Math.random() * 6 - 3;
            this.type = filter.type || 'arc';
            this.size = filter.size || 2;
            this.realOpacity = this.opacity = filter.opacity || 1;
            this.colorType = filter.colorType || "hsla";
            this.color = filter.color || [Math.floor(Math.random() * 360), "100%", "50%"];
            this.realLife = this.life = filter.life || 100;
            this.isDead = false;
            this.gravity = filter.gravity || 0;
            this.wind = filter.wind || 0;
        };
        
        Particle.prototype.getColor = function() {
            return this.colorType + "(" + this.color[0] + "," + this.color[1] + "," + this.color[2] + "," + this.opacity + ")";
        };
        
        Particle.prototype.update = function() {
            this.opacity = this.life / this.realLife * this.realOpacity;
            this.x += this.vx;
            this.y += this.vy;
            this.vy += this.gravity;
            this.vx += this.wind;
            this.life--;
            if(this.life < 0)
                this.isDead = true;
        };
        
        Particle.prototype.render = function() {
            ctx.fillStyle = this.getColor();
            if(this.type === "arc") {
                ctx.beginPath();
                ctx.arc(this.x, this.y, this.size / 2, 0, 2 * Math.PI);
                ctx.closePath();
                ctx.fill();
            } else if(this.type === "rect") {
                ctx.fillRect(this.x, this.y, this.size, this.size);
            }
        };
        
        
        /* README!!
        This particle system works with some sort of filters.
        How it works:
        x: x position, automatically added to Emitter's x (you can't have a particle floating around without a reference point)
        y: y position
        vx: x velocity
        vy: y velocity
        type: it could be either 'arc' or 'rect'
        size: the size of the particle, if arc, this represents radio * 2
        opacity: self describing
        colorType: could be either 'rgba' or 'hsla'
        color: array containing the first 3 params of rgba/hsla, opacity is automatically added
        particles: the number of particles created every frame, bad performs when reaching the 10 value
        life: the number of frames this particle will live
        gravity: gravity force
        wind: wind force
        
        NO NEED to put every value in a filter, it has fallback values
        */
        
        //Example of a filter.
        var fire = function() {
                        return {
                            vx: Math.random() * 0.2 - 0.1,
                            vy: -1,
                            size: Math.random() * 10 + 5,
                            color: [Math.floor(Math.random() * 20), '100%', '50%'],
                            particles: 3,
                            life: 70,
                            wind: 0.01,
                        };
                    };
        
        var white = function() {
                        return {
                            vx: Math.random() * 0.2 - 0.1,
                            vy: -1,
                            size: Math.random() * 8,
                            color: [Math.floor(Math.random() * 20), '100%', '60%'],
                            particles: 3,
                            life: 40,
                            wind: 0.01,
                        };
                    };
        
        var emitter = new Emitter(canvas.width / 2, canvas.height / 2, fire);
        var emitter2 = new Emitter(canvas.width / 2, canvas.height / 2, white);
        
        var _i = setInterval(function() {
            ctx.globalCompositeOperation = "source-over";
            ctx.fillStyle = "rgba(0,0,0,0.4)";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.globalCompositeOperation = "lighter";
            emitter.render();
            emitter2.render();
        }, 1000 / 60);
Output 300px

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
anonymouspro
0viewers