Here is the relevant part of the code:
function render( image, radius, imageScale, imageAngle )
{
var PI2 = 2.0 * Math.PI;
// the radius at the edge
var radiusInner = radius >> 0;
// the radius at the vertex
var radiusOuter = radiusInner * Math.sqrt( 3 ) >> 1;
var numRows = 1 + ( _height * 0.5 / radiusInner ) >> 0;
var numCols = 1 + ( _width * 0.5 / ( radiusInner * 3 ) ) >> 0;
var mirror = -1;
_context.save();
_context.translate( 0.5 * _width, 0.5 * _height );
_context.fillStyle = _context.createPattern( image, "repeat" );
for( var row = -numRows; row <= numRows; ++row )
{
_context.save();
_context.translate( ( row % 2 ) ? 0 : radiusInner * 1.5, radiusOuter * row );
for( var col = -numCols; col <= numCols; ++col )
{
_context.save();
_context.translate( radiusInner * col * 3, 0 );
//render hexagon sides
for( var i = 0; i < 6; ++i )
{
_context.save();
_context.rotate( i * PI2 / 6 );
_context.scale( mirror, 1 );
_context.beginPath();
_context.moveTo( 0, 0 );
_context.lineTo( -radiusInner * .5, radiusOuter );
_context.lineTo( radiusInner * .5, radiusOuter );
_context.closePath();
// render pattern start
_context.save();
_context.scale( imageScale, imageScale );
_context.rotate( imageAngle * PI2 );
_context.translate( -0.5 * image.width, -0.5 * image.height );
_context.fill();
_context.restore();
// render pattern end
mirror *= -1;
_context.restore();
}
_context.restore();
}
_context.restore();
}
_context.restore();
}