There's a recurring theme in some of the favourite pens I've made - animating objects in to the shape of text.

I make these by using my favourite CanvasRenderingContext2D method - getImageData.

Calling getImageData on a canvas context returns an Array with the RGBA data of the pixels in the context. Because the array is 1-dimensional, where each red, green, blue and alpha value (between 0 and 255) is an item in the array, it isn't immediately obvious where the data for a pixel at a particular x,y position is. I remember when I first tried to use getImageData it took me a while to grok how to match up the data with the pixels in the image so I'm going to attempt to break this down for you now.

Say you have a canvas element and you've selected the context. Then you can call getImageData on the context, which returns the ImageData interface.

  <canvas id="canvas" width="200" height="200"></canvas>

  // select the canvas element
var canvas = document.getElementById("canvas");

// get the context
var ctx = canvas.getContext('2d');
// fill the canvas with black
ctx.fillRect(0, 0, 200, 200);
// get the ImageData for the top/left 10 pixels
var imageData = ctx.getImageData(0, 0, 10, 10);

// logs an array of 10 x 10 x 4 (400 items)
console.log(imageData.data);


See the Pen d8ea943a5776a0109c38207e16ab9e2f by Rachel Smith (@rachsmith) on CodePen.

As I've tried to illustrate above, the getImageData data array returns an array of pixels, listed from left to right, top to bottom.

This means we can sample a canvas with text (or any other graphic) on it to get the position of pixels with a color in them - and then use the pixel positions to create all sorts of visualisations, such as the hairy text pen I created above.

  // the following code gets the pixels to create the hairy text
var pix = ctx.getImageData(0,0,700,200).data;
textPixels = [];
for (var i = pix.length; i >= 0; i -= 4) {
    /** we're checking every alpha pixel in the array, if it isn't zero 
  that means it is one of the text pixels **/
  if (pix[i] != 0) {
    // get the x position
    var x = (i / 4) % 700;
    // get the y position
    var y = Math.floor(Math.floor(i/700)/4);

    /** we don't want every pixel for this visualisation, we'll just 
    get every 4th pixel in the x and y direction **/
    if((x && x%4 == 0) && (y && y%4 == 0)) textPixels.push({x: x, y: y});
  }
}




Another pen I've used getImageData in is my recent Christmas themed pen. I created a mask of shia and put it on the canvas. I then used getImageData to get the position of the mask pixels and checked the snowflakes' position against the pixel position. If a snowflake "touched" Shia, it would stop falling!

I hope this was helpful in some way to better understanding how you can use getImageData. Once I figured it out, it became my favourite 'trick' to use with canvas. Have fun with getImageData and make sure you comment with links to the pens you made using this method!