Röksimulering i HTML5

Igår var jag med i en "HTML5 study group" för att se vad den nya standarden har att erbjuda. Inte helt oväntat fastnade jag för Canvas-taggen och som ett experiment provade jag att göra en enkel röksimulator.

Här är koden:

    <canvas id="canvas" width="150" height="150"></canvas> 
    <script type="text/javascript">
var ctx;
particles = [];

var canvas = document.getElementById('canvas'); 
if (canvas.getContext){ 
    ctx = canvas.getContext('2d');
    //Set Refresh Rate 
    setInterval(draw, 40); 
}

// Smoke particle class
function Particle() {

    // Initial y less than 0 to trigger initiation of all variables
    this.y = -1;

    this.reset = function() {

        // Position
        this.x = 75.0;
        this.y = 150.0;
       
        // Speed
        this.dx = Math.random() * 1.0 - 0.5;
        this.dy = Math.random() * 0.2 + 1.8;
        this.dradius = Math.random() * 0.1 + 0.5;

        this.radius = 10.0;

        // Transparency
        this.alpha = 0.15;
    }

    this.render = function() {
       
        if (this.y < 0) {
            this.reset();
        }

        // Change position, radius and transparency of the particle
        this.x += this.dx;
        this.y -= this.dy;
        this.radius += this.dradius;
        this.alpha *= 0.98;

        // Create circular gradient, white in the middle and transparent at the edge
        var radgrad = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.radius);
        radgrad.addColorStop(0, 'rgba(255, 255, 255, ' + this.alpha + ')');
        radgrad.addColorStop(1, 'rgba(255, 255, 255, 0)');
        ctx.fillStyle = radgrad;

        // Draw the particle
        ctx.fillRect(this.x - this.radius, this.y - this.radius, this.radius * 2, this.radius * 2);
    }
}

function draw() {
    // Background
    ctx.fillStyle = "rgb(40, 40, 40)"; 
    ctx.fillRect(0, 0, 200, 200);

    // Create new particles until we have 75
    if (particles.length < 75) {
        particles.push(new Particle());
    }

    // Draw the particles on the canvas
    for (var i = 0; i < particles.length; ++i) {
         particles[i].render(); 
    }

    </script>

Kommentarer

Ej optimerad

Jag kanske ska tillägga att den här koden inte är optimerad på något sätt, så den tar ganska mycket processorkraft. Det är t ex inte optimalt att skapa en ny gradient varje gång en partikel ska ritas ut på skärmen.