Last active
August 29, 2015 14:06
-
-
Save a-c-t-i-n-i-u-m/6582581b71faabe3ae7a to your computer and use it in GitHub Desktop.
3x3 Grid icon generator template for JavaScript, Demo: http://devel.actinium.org/myidenticon.js/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* myidenticon.js; 3x3 Grid icon generator template for JavaScript + Canvas | |
* (C) Lianol <actinium.org> | |
*/ | |
(function (w, d, undefined) { | |
/** | |
* Constructor | |
* @param {object} option Override Defaults | |
*/ | |
var myidenticon = function (option) { | |
// generate hash table | |
this.hashtable = []; | |
for (var c, n = 0; n < 256; n++) { | |
c = n; | |
for (var k = 0; k < 8; k++) { | |
c = ((c&1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1)); | |
} | |
this.hashtable[n] = c; | |
} | |
// override | |
option = option || {}; | |
if (typeof option.color !== 'undefined') { | |
this.backgroundColor = option.color; | |
} | |
if (typeof option.pattern !== 'undefined') { | |
this.pattern = option.pattern; | |
} | |
}; | |
/** | |
* @var default background color | |
*/ | |
myidenticon.prototype.backgroundColor = 'rgb(255, 255, 255)'; | |
/** | |
* @var Pattern Points | |
*/ | |
myidenticon.prototype.pattern = [ | |
// pattern.1: square | |
[ | |
[0, 0], | |
[0, 1], | |
[1, 1], | |
[1, 0], | |
], | |
// pattern.2: triangle 1:1:sqrt(2) | |
[ | |
[0, 0], | |
[1, 0], | |
[0, 1], | |
], | |
// pattern.3: triangle 1:1:1 | |
[ | |
[0.5, 0], | |
[0, 1], | |
[1, 1], | |
], | |
// pattern.4: half square | |
[ | |
[0, 0], | |
[0, 1], | |
[0.5, 1], | |
[0.5, 0], | |
], | |
// pattern.5: diamond | |
[ | |
[0.5, 0], | |
[1, 0.5], | |
[0.5, 1], | |
[0, 0.5], | |
], | |
// pattern.6: horns | |
[ | |
[0, 0], | |
[1, 0.5], | |
[1, 1], | |
[0.5, 1], | |
], | |
// pattern.7: pyramid | |
[ | |
[0.5, 0], | |
[0, 1], | |
[0.5, 1], | |
[0.25, 0.5], | |
[0.75, 0.5], | |
[0.5, 1], | |
[1, 1], | |
], | |
// pattern.8: triangle, 45deg | |
[ | |
[0, 0], | |
[0.5, 1], | |
[1, 0.5], | |
], | |
// pattern.9: square, small | |
[ | |
[0.25, 0.25], | |
[0.75, 0.25], | |
[0.75, 0.75], | |
[0.25, 0.75], | |
], | |
// pattrn.10: small triangle x2 | |
[ | |
[0.5, 0], | |
[0.5, 0.5], | |
[0, 0.5], | |
[0, 1], | |
[1, 0], | |
], | |
// pattern.11: small square, left, top | |
[ | |
[0, 0], | |
[0.5, 0], | |
[0.5, 0.5], | |
[0, 0.5], | |
], | |
// pattern.12: half triangle, to bottom | |
[ | |
[0, 0.5], | |
[1, 0.5], | |
[0.5, 1], | |
], | |
// pattern.13: half triangle, to top | |
[ | |
[0, 1], | |
[0.5, 0.5], | |
[1, 1], | |
], | |
// pattern.14: quoter triangle, left top, to center | |
[ | |
[0.5, 0], | |
[0.5, 0.5], | |
[0, 0.5], | |
], | |
// pattern.15: quoter triangle, left top, to outer | |
[ | |
[0, 0], | |
[0.5, 0], | |
[0, 0.5], | |
], | |
// pattern.16: blank | |
[ | |
], | |
]; | |
/** | |
* hash; CRC32 | |
* @param {string} string Input | |
* @return {integer} Hash | |
*/ | |
myidenticon.prototype.hash = function (string) { | |
var crc = 0 ^ (-1); | |
for (var i = 0; i < string.length; i++) { | |
crc = (crc >>> 8) ^ this.hashtable[(crc ^ string.charCodeAt(i)) & 0xFF]; | |
} | |
return (crc ^ (-1)) >>> 0; | |
}; | |
/** | |
* Generate Identicon on HTML5 Canvas | |
* @param {string} string Input | |
* @param {integer} size Image Size(*Choose number multiple of 3, or program adjust this value automatically.) | |
* @return {DOM} Canvas Object | |
*/ | |
myidenticon.prototype.make = function (string, size) { | |
// string to config | |
var hash = this.hash(string), | |
config = { | |
size: Math.round(size / 3) * 3, | |
pattern: { | |
// center pattern, 0-15, 4bit | |
center: hash & 0xf, | |
// corner pattern, 0-15, 4bit | |
corner: (hash >> 4) & 0xf, | |
// middle pattern, 0-15, 4bit | |
middle: (hash >> 8) & 0xf, | |
}, | |
invert: { | |
// center invert, 1bit | |
center: (hash >> 12) & 0x1, | |
// corner invert, 1bit | |
corner: (hash >> 13) & 0x1, | |
// middle invert, 1bit | |
middle: (hash >> 14) & 0x1, | |
}, | |
reverse: (hash >> 15) & 0x1, | |
color: { | |
// red color, 4bit | |
red: (hash >> 16) & 0xff, | |
// green color, 4bit | |
green: (hash >> 20) & 0xff, | |
// blue color, 4bit | |
blue: (hash >> 24) & 0xff, | |
}, | |
}; | |
// check fill color | |
var dist = Math.sqrt( | |
Math.pow(255 - config.color.red, 2) + | |
Math.pow(255 - config.color.green, 2) + | |
Math.pow(255 - config.color.blue, 2) | |
); | |
if (dist < 80) { | |
for (var k in config.color) { | |
config.color[k] = 255 - config.color[k]; | |
} | |
} | |
// initialize canvas | |
var canvas = document.createElement('canvas'); | |
if (!canvas || !canvas.getContext) { | |
return false; | |
} | |
canvas.width = config.size; | |
canvas.height = config.size; | |
var ctx = canvas.getContext('2d'); | |
// fill background | |
ctx.fillStyle = this.backgroundColor; | |
ctx.fillRect(0, 0, config.size, config.size); | |
// draw center | |
this.drawPattern(ctx, config.pattern.center, config.invert.center, config.size, config.color, 1, 1, 1); | |
// draw corner | |
this.drawPattern(ctx, config.pattern.corner, config.invert.corner, config.size, config.color, 4, 0, 0); | |
// draw middle | |
this.drawPattern(ctx, config.pattern.middle, config.invert.middle, config.size, config.color, 4, 0, 1); | |
// reverse | |
if (config.reverse) { | |
var newCanvas = document.createElement('canvas'), newCtx = newCanvas.getContext('2d') | |
newCanvas.width = config.size; | |
newCanvas.height = config.size; | |
newCtx.transform(-1, 0, 0, 1, config.size, 0); | |
newCtx.drawImage(canvas, 0, 0); | |
return newCanvas; | |
} | |
// fin | |
return canvas; | |
}; | |
/** | |
* render | |
* @param {context} c Target 2D Context | |
* @param {integer} id Index of this.pattern | |
* @param {boolean} invert Is invert pattern | |
* @param {integer} size Image Size | |
* @param {object} color Color Info {red, green, blue} | |
* @param {integer} repeat Rotate Repeating | |
* @param {integer} offsetX Offset number of grid horizontal | |
* @oaram {integer} offsetY Offset number of grid vertical | |
*/ | |
myidenticon.prototype.drawPattern = function (c, id, invert, size, color, repeat, offsetX, offsetY) { | |
var fill = 'rgb(' + color.red + ',' + color.green + ',' + color.blue + ')', | |
offset = size / 3, | |
move = size / 2, | |
pattern = this.pattern[id].map(function (p) { | |
return [(p[0] + offsetX) * offset, (p[1] + offsetY) * offset]; | |
}); | |
for (var r = 0; r < repeat; r++) { | |
var tempFill = fill; | |
if (invert) { | |
c.fillStyle = tempFill; | |
c.fillRect(offset * offsetX, offset * offsetY, offset, offset); | |
tempFill = this.backgroundColor; | |
} | |
if (pattern.length > 0) { | |
c.fillStyle = tempFill; | |
c.beginPath(); | |
c.moveTo(pattern[0][0], pattern[0][1]); | |
for (var i = 1; i < pattern.length; i++) { | |
c.lineTo(pattern[i][0], pattern[i][1]); | |
} | |
c.closePath(); | |
c.fill(); | |
} | |
if (repeat > 1) { | |
c.translate(move, move); | |
c.rotate(Math.PI / 2); | |
c.translate(-move, -move); | |
} | |
} | |
}; | |
w.myidenticon = myidenticon; | |
})(window, document); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment