How to create a mystery missile trail with HTML5


On Monday the 8th of November a large condensation trail was visible in the skies of California. It was rumoured that the trail was caused by a missile, however the pentagon have since stated they believe it to have been created by an aircraft.

I thought that it would be interesting to see if I could recreate the effect of a vapour trail using a HTML5 canvas.

In the demo below press and then drag the mouse over the canvas and a vapour trail will be drawn. One problem… it’s not very realistic. I’d love you guys to rework this example and provide a more realistic effect. If you do come up with anything better be sure to post it in the comments.

Click here to view the demo

Below are the steps I took to create this demo:

Step 1

As with all my demos, firstly add a reference to Jquery

<script src="http://ajax.microsoft.com/ajax/jquery/jquery-1.4.2.min.js" language="javascript"
type="text/javascript"></script>

Step 2

Next add a function that will be called when the page is ready. Also add in a few global variables which we will use to save objects into later. In the example below I have used the jQuery ready function to fire a JavaScript function called setUpVapour()

var canvas;
var ctx;
var paint;
var images;

$(document).ready(function () {
    setUpVapour();
});

Step 3

The setUpVapour function firstly gets a reference to the canvas element and saves it into the canvas variable we set up in step 1. We then call the getContext function and save the result into the variable ctx that we created in step 1. This ctx gives us a reference to the canvas which we will be able to use to draw.

We then call drawBackground() this function draws the sky image on the background of the canvas.

Attach mousedown, mouseup and mouseleave functions to the canvas. All these functions do is keep track of whether we should be painting or not. We keep track by setting the paint variable to true when the mouse goes down and false when the mouse comes up or leaves the canvas. This will give us the effect of painting only when the mouse button is held down.

Next we add added the mousemove event to the canvas. As the mouse moves we determine if we should be painting by checking if paint is true. If it is we capture the x and y coordinates of the mouse and pass them to the generateRandomParticles(mouseX, mouseY) function.

function setUpVapour() {

    canvas = $("#canvas").get(0);
    ctx = canvas.getContext('2d');
   
    drawBackground();

    $('#canvas').mousedown(function (e) {
        paint = true;
    });

    $('#canvas').mouseup(function (e) {
        paint = false;
    });

    $('#canvas').mouseleave(function (e) {
        paint = false;
    });

    $('#canvas').mousemove(function (e) {

        if (paint) {
            var mouseX = e.pageX - this.offsetLeft;
            var mouseY = e.pageY - this.offsetTop;
            generateRandomParticles(mouseX, mouseY);
        }
    });            
}

 

Step 4

Add the drawBackground function. This function loads a JavaScript Image object. It sets the onload function to a new anonymous function which will in turn draw the image to canvas only when the image is loaded.

This is important because otherwise the image may not be fully loaded by the time we call drawImage this would result in a white canvas.

Lastly we set the src of the image object.

function drawBackground() {
    images = new Image();
    images.onload = function () {
        ctx.drawImage(images, 0, 0);
    };

    images.src = "images/vapour.jpg";
} 

Step 5

Add the generateRandomPartcle function. This function takes the x and y coordinates and randomly draws 50 1x1 rectangles around the mouse point. It also changes the colour of 20% of the rectangles to grey.

This is the function that needs work to make the trail look more realistic… It’s a good starting point, but needs alot of work Smile 

function generateRandomParticles(mouseX, mouseY) {
    for (i = 0; i <= 50; i++) {
        var randomnumber = Math.floor(Math.random() * 11);
        var randomcolor = Math.floor(Math.random() * 11);
        var randomdegree = Math.floor(Math.random() * 361);
        var randomTrans = Math.floor(Math.random() * 256);
        var newX = mouseX + Math.floor(Math.cos(randomdegree * Math.PI / 180) * randomnumber);
        var newY = mouseY + Math.floor(Math.sin(randomdegree * Math.PI / 180) * randomnumber);
        if (randomnumber > 7) {
            ctx.fillStyle = "rgba(255,255,255," + randomTrans + ")";
        } else {
            ctx.fillStyle = "rgba(222,222,222," + randomTrans + ")";
        }
        ctx.fillRect(newX, newY, 1, 1);
    }
}
Comments (4)

  1. Shantanu Kumar says:

    A [Demo] button on the blog post page would have been nice. 🙂

  2. thebeebs says:

    There is a demo button 🙂

  3. Kev Ritchie says:

    How 'bout this?

    function generateRandomParticles(mouseX, mouseY) {

               for (i = 0; i <= 50; i++) {

                   var randomnumber = Math.floor(Math.random() * 11);

                   var randomcolor = Math.floor(Math.random() * 11);

                   var randomdegree = Math.floor(Math.random() * 189);

                   var randomTrans = Math.floor(Math.random() * 256);

                   var newX = mouseX + Math.floor(Math.cos(randomdegree * Math.PI / 180) * randomnumber);

                   var newY = mouseY + Math.floor(Math.sin(randomdegree * Math.PI / 180) * randomnumber);

                   if (randomnumber < 7) {

                       ctx.fillStyle = "rgba(255,255,255," + randomTrans + ")";

                   } else {

                       ctx.fillStyle = "rgba(200,200,200," + randomTrans + ")";

                   }

                   ctx.fillRect(newX, newY, 1, 1);

               }

           }

    I've changed the fillStyle slightly, reversed the colours and modified the degree parameter.

    On a curve and holding down the mouse a little longer, seems to give a nice trail.

    Let me know what you think?

  4. Kev Ritchie says:

    Dragging a little slower helps too 🙂

Skip to main content