Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | 1x 1x 1x 1x 1x 1x 16x 112x 16x 16x 16x 400x 16x 1x 5x 11x 2x 16x 1x | // Minidenticons MIT Credit to https://github.com/laurentpayot/minidenticons // density of 4 for the lowest probability of collision const SQUARE_DENSITY = 4; // 18 different colors only for easy distinction const COLORS_NB = 18; const DEFAULT_SATURATION = 50; const DEFAULT_LIGHTNESS = 50; // 32 bit FNV-1a hash parameters const FNV_PRIME = 16777619; const OFFSET_BASIS = 2166136261; // based on the FNV-1a hash algorithm, modified for *signed* 32 bit integers http://www.isthe.com/chongo/tech/comp/fnv/index.html /** * @param str */ function simpleHash(str) { return ( str .split('') // >>> 0 for 32 bit unsigned integer conversion https://2ality.com/2012/02/js-integers.html .reduce( (hash, char) => ((hash ^ char.charCodeAt(0)) >>> 0) * FNV_PRIME, OFFSET_BASIS ) ); } /** * @param username * @param saturation * @param lightness */ export function identicon( username, saturation = DEFAULT_SATURATION, lightness = DEFAULT_LIGHTNESS ) { const hash = simpleHash(username); // dividing hash by FNV_PRIME to get last XOR result for better color randomness (will be an integer except for empty string hash) const hue = ((hash / FNV_PRIME) % COLORS_NB) * (360 / COLORS_NB); const rects = [...Array(username ? 25 : 0).keys()] // 2 + ((3 * 5 - 1) - modulo) to concentrate squares at the center .map((i) => hash % (16 - (i % 15)) < SQUARE_DENSITY ? `<rect x="${i > 14 ? 7 - ~~(i / 5) : ~~(i / 5)}" y="${ i % 5 }" width="1" height="1"/>` : '' ) .join(''); // xmlns attribute added in case of SVG file generation https://developer.mozilla.org/en-US/docs/Web/SVG/Element/svg#sect1 return `<svg viewBox="-1.5 -1.5 8 8" xmlns="http://www.w3.org/2000/svg" fill="hsl(${hue} ${saturation}% ${lightness}%)">${rects}</svg>`; } class IdenticonOrImageElement extends HTMLElement { connectedCallback() { this.identiconSvg(); } attributeChangedCallback() { this.identiconSvg(); } static get observedAttributes() { return ['username', 'saturation', 'lightness']; } identiconSvg() { this.innerHTML = identicon( this.getAttribute('username') || '', this.getAttribute('saturation') || DEFAULT_SATURATION, this.getAttribute('lightness') || DEFAULT_LIGHTNESS ); } } customElements.define('identicon-or-image', IdenticonOrImageElement); export { IdenticonOrImageElement }; |