Say that I have a spritesheet like this

simple spritesheet

And I want to use the dirt tile at (1, 1). I know that I can repeat an entire image using createPattern but how do I create the pattern from just the tile section of the image? So far I have this

var pattern = ctx.createPattern(img, 'repeat');
ctx.fillStyle = pattern;
ctx.fillRect(x, y, w, h);

I know I could use repeated calls to ctx.drawImage but is it possible to get the same effect using patterns?


Here's what I found out by following this link.

context.drawImage can take an img, canvas, or video element. So you can decide to use the contents of an off-screen canvas as a pattern.

// First we create a canvas to draw our pattern on
// Doesn't actually have to be in the DOM
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = textureWidth;
offscreenCanvas.height = textureHeight;

// Grab it's context and render to it
var offscreenContext = offscreenCanvas.getContext('2d');
    texture,       // the Image
    sourceX,       // X offset on the spritesheet
    sourceY,       // Y offset on the spritesheet
    textureWidth,  // Width of the sprite
    textureHeight, // Height of the sprite
    0,             // Destination X
    0,             // Destination Y
    textureWidth,  // Destination width
    textureHeight  // Destination height

Now here's the fun part: creating a pattern from our "invisible" canvas.

// Can use 'repeat', 'repeat-x', 'repeat-y', or 'no-repeat'
var pattern = context.createPattern(offscreenCanvas, 'repeat');
context.fillStyle = pattern;
context.fillRect(x, y, textureWidth, textureHeight);

As an added bonus, this is much faster than making multiple drawImage calls.

  • 1
    \$\begingroup\$ WARNING: The JSPerf linked above causes repeated crashing of my graphics driver for the drawPattern! \$\endgroup\$ – Vaughan Hilts Apr 8 '14 at 20:31
  • \$\begingroup\$ I shrank down the test area so hopefully it won't crash any more drivers haha. \$\endgroup\$ – Mike Cluck Apr 29 '14 at 17:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.