Files
gollum/lib/gollum/frontend/public/gollum/javascript/identicon_canvas.js
T
2012-11-13 21:17:23 -05:00

112 lines
4.2 KiB
JavaScript

/*
Client-side Canvas tag based Identicon rendering code
@author Don Park
@version 0.2
@date January 21th, 2007
*/
var patch0 = new Array( 0, 4, 24, 20 );
var patch1 = new Array( 0, 4, 20 );
var patch2 = new Array( 2, 24, 20 );
var patch3 = new Array( 0, 2, 20, 22 );
var patch4 = new Array( 2, 14, 22, 10 );
var patch5 = new Array( 0, 14, 24, 22 );
var patch6 = new Array( 2, 24, 22, 13, 11, 22, 20 );
var patch7 = new Array( 0, 14, 22 );
var patch8 = new Array( 6, 8, 18, 16 );
var patch9 = new Array( 4, 20, 10, 12, 2 );
var patch10 = new Array( 0, 2, 12, 10 );
var patch11 = new Array( 10, 14, 22 );
var patch12 = new Array( 20, 12, 24 );
var patch13 = new Array( 10, 2, 12 );
var patch14 = new Array( 0, 2, 10 );
var patchTypes = new Array( patch0, patch1, patch2, patch3, patch4,
patch5, patch6, patch7, patch8, patch9, patch10, patch11,
patch12, patch13, patch14, patch0 );
var centerPatchTypes = new Array(0, 4, 8, 15);
function render_identicon_patch(ctx, x, y, size, patch, turn, invert, foreColor, backColor) {
patch %= patchTypes.length;
turn %= 4;
if (patch == 15)
invert = !invert;
var vertices = patchTypes[patch];
var offset = size / 2;
var scale = size / 4;
ctx.save();
// paint background
ctx.fillStyle = invert ? foreColor : backColor;
ctx.fillRect(x, y, size, size);
// build patch path
ctx.translate(x + offset, y + offset);
ctx.rotate(turn * Math.PI / 2);
ctx.beginPath();
ctx.moveTo((vertices[0] % 5 * scale - offset), (Math.floor(vertices[0] / 5) * scale - offset));
for (var i = 1; i < vertices.length; i++)
ctx.lineTo((vertices[i] % 5 * scale - offset), (Math.floor(vertices[i] / 5) * scale - offset));
ctx.closePath();
// offset and rotate coordinate space by patch position (x, y) and
// 'turn' before rendering patch shape
// render rotated patch using fore color (back color if inverted)
ctx.fillStyle = invert ? backColor : foreColor;
ctx.fill();
// restore rotation
ctx.restore();
}
function render_identicon(node, code, size) {
if (!node || !code || !size) return;
var patchSize = size / 3;
var middleType = centerPatchTypes[code & 3];
var middleInvert = ((code >> 2) & 1) != 0;
var cornerType = (code >> 3) & 15;
var cornerInvert = ((code >> 7) & 1) != 0;
var cornerTurn = (code >> 8) & 3;
var sideType = (code >> 10) & 15;
var sideInvert = ((code >> 14) & 1) != 0;
var sideTurn = (code >> 15) & 3;
var blue = (code >> 16) & 31;
var green = (code >> 21) & 31;
var red = (code >> 27) & 31;
var foreColor = "rgb(" + (red << 3) + "," + (green << 3) + "," + (blue << 3) + ")";
var backColor = "rgb(255,255,255)";
var ctx = node.getContext("2d");
// middle patch
render_identicon_patch(ctx, patchSize, patchSize, patchSize, middleType, 0, middleInvert, foreColor, backColor);
// side patchs, starting from top and moving clock-wise
render_identicon_patch(ctx, patchSize, 0, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
render_identicon_patch(ctx, patchSize * 2, patchSize, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
render_identicon_patch(ctx, patchSize, patchSize * 2, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
render_identicon_patch(ctx, 0, patchSize, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
// corner patchs, starting from top left and moving clock-wise
render_identicon_patch(ctx, 0, 0, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
render_identicon_patch(ctx, patchSize * 2, 0, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
render_identicon_patch(ctx, patchSize * 2, patchSize * 2, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
render_identicon_patch(ctx, 0, patchSize * 2, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
}
function render_identicon_canvases(prefix) {
var canvases = document.getElementsByTagName("canvas");
var n = canvases.length;
for (var i = 0; i < n; i++) {
var node = canvases[i];
if (node.title && node.title.indexOf(prefix) == 0) {
if (node.style.display == 'none') node.style.display = "inline";
var code = node.title.substring(prefix.length) * 1;
var size = node.width;
render_identicon(node, code, size);
}
}
}