DOM Particle System

by Teddy Kishi / @teddytdk

DOM vs Canvas ?

not at all

It's hard to cover the performance differences, it depends on the job and everything will vary from a browser to an other.

set the area


var stage = {
    element : document.getElementById("stage"),
    color : "black",
    x : 0,
    y : 0,
    width: 200,
    height: 200,
    update : function() {
        this.element.style.top = this.y + "px";
        this.element.style.left = this.x + "px";
        this.element.style.width = this.width + "px";
        this.element.style.height = this.height + "px";
        this.element.style.backgroundColor = this.color;
    }
}
//optional
stage.width = window.innerWidth;
stage.height = window.innerHeight;
stage.update();
                    

create a particle


var Particle = {
    x: 0, 
    y: 0,
    width : 10, 
    height : 10,
    maxSpeed : 10, 
    speedX: 0, 
    speedY: 0,
    color : "yellow",
    appendTo: function (parent) {
        this.element = document.createElement("div");
        this.element.style.top = this.y + "px";
        this.element.style.left = this.x + "px";
        this.element.style.width = this.width + "px";
        this.element.style.height = this.height + "px";
        this.element.style.backgroundColor = this.color;
        parent.appendChild(this.element);
    }
};
                    

create many particles

using Object.create()


var particlesArray = [];

for (var i = 0; i < 100; i++) {

    var particle = Object.create(Particle);

        particle.x = stage.width/2;
        particle.y = stage.height/2;

        particle.speedX = randomRange(-particle.maxSpeed, particle.maxSpeed);
        particle.speedY = randomRange(-particle.maxSpeed, particle.maxSpeed);

        particle.appendTo(stage.element);
        particlesArray.push(particle);
}

                    

make them move


var update = function () {
    for (var i = 0; i < particlesArray.length; i++) {

        var particle = this.particlesArray[i];

            particle.x += particle.speedX;
            particle.y += particle.speedY;

            particle.element.style.left = Math.round(particle.x)+ "px";
            particle.element.style.top = Math.round(particle.y)+ "px";
    }
}

setInterval(update, 1000/60);
            
                  

the frame rate


window.requestAnimFrame = (function() {
    return  window.requestAnimationFrame   ||
        window.webkitRequestAnimationFrame ||
        window.mozRequestAnimationFrame    ||
        function( callback ){
            window.setTimeout(callback, 1000/60);
        };
}

source : Paul Irish

make them move in 3D !


 
var move3D = function(obj) {
    obj.element.style.transform = "translate3d("+obj.x +"px,"+obj.y+"px,"+obj.z+"px)";
}                   

complex update


 
var insaneUpdate = function(obj) {
    obj.element.style.transform = "translate3d("+obj.x +"px,"+obj.y+"px,"+obj.z+"px) 
                                   scale("+obj.scale+") 
                                   rotate("+obj.rotation+"deg)";
}                   

very complex update


 
var youMustBeKidding = function(obj) {
    obj.element.style.transform = "translate3d("+obj.x +"px,"+obj.y+"px,"+obj.z+"px) 
                                   scaleX("+obj.scaleX+") 
                                   scaleY("+obj.scaleY+")
                                   scaleZ("+obj.scaleZ+") 
                                   rotateX("+obj.rotateX+"deg)
                                   rotateY("+obj.rotateY"deg)
                                   rotateZ("+obj.rotateZ+"deg)
                                   skewX("+obj.skewX+")
                                   skewY("+obj.skewY+")";
}                   

many ways to move

Top Left

Translate 2D

Translate 3D


which one is the fastest ?

jsPerf : translate3d-vs-xy

it depends on the browser

let's see...

Testing for CSS 3D Transforms Support


function has3d(){
    var el = document.createElement('p'),
    has3d,
    transforms = {
        'webkitTransform':'-webkit-transform',
        'OTransform':'-o-transform',
        'msTransform':'-ms-transform',
        'MozTransform':'-moz-transform',
        'transform':'transform'
    };
    // Add it to the body to get the computed style
    document.body.insertBefore(el, null);
    for(var t in transforms){
        if( el.style[t] !== undefined ){
            el.style[t] = 'translate3d(1px,1px,1px)';
            has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
        }
    }
    document.body.removeChild(el);
    return (has3d !== undefined && has3d.length > 0 && has3d !== "none");
}
                    

source : Lorenzo Polidori

transitions & animations

collisions

gravity

math animations

special effects

want to learn ?

A Quick Look Into The Math Of Animations With JavaScript
by Christian Heilmann

libraries

gsap by Greensock

sprite3D by Boblemarin

THANK YOU

Teddy Kishi / @teddytdk

Q&A