Generate Identity Icon

任意の文字列からIdentity Iconを生成する

by bc_rikko

HTML

<script src="https://rawgit.com/emn178/js-sha1/master/build/sha1.min.js"></script>
<script src="https://rawgit.com/eligrey/FileSaver.js/master/FileSaver.min.js"></script>
<input type="text" id="source">
<button id="generate">generate</button>
<button id="download">download</button>

<div class="identity-icon">
</div>

JavaScript

const identityIcon = document.querySelector('.identity-icon');
const source = document.getElementById('source');
const generate = document.getElementById('generate');
const download =  document.getElementById('download');

/**
 * 文字列からRGBを取得する
 * @param {string} val RGBに変換する文字列
 * @return {Array} [r, g, b]で返す
 */
function generateRGBCode(val) {
  if (!val) { return [0,0,0]; }
  const len = Math.floor(val.length / 3);
  // /[\s\S]{1,n}/g
  const regexp = new RegExp(`[\\s\\S]{1,${len}}`, 'g');
  const codes = val.match(regexp);

  const rgb = [];
  codes.forEach(a => {
    let n = 0;
    for (let x of a) {
      n += x.charCodeAt();
    }
    rgb.push(n % 256);
  });

  return rgb;
}

/**
 * IdentityIconを生成し、SVGのパスを返す
 * @param {string} hash sha1などでハッシュ化した値(40桁)
 * @param {number} size アイコンの横幅
 * @return {string} SVGのパス
 */
function generateIcon(hash, size) {
  const forDraw = hash.substr(0, 25);
  const forColor = hash.substr(25);

  // rgb(x, y, z)
  const hue = `rgb(${generateRGBCode(forColor).join(',')}`;

  const interval = size / 5;
  let x = 0;
  let y = 0;
  let path = '';

  for (let c of forDraw) {
    const isDraw = c.charCodeAt() % 2 === 0;

    path += `<rect x="${x}" y="${y}" width="${interval}" height="${interval}" fill="${isDraw ? hue : 'white'}" />`;

    if (x < size - interval) {
      x += interval;
    } else {
      x = 0;
      y += interval;
    }
  }

  return [
    `<svg width="${size}" height="${size}">`,
    '<g>',
    path,
    '</g>',
  ].join('');
}

/**
 * generateボタン
 */
generate.addEventListener('click', () => {
  const hash = sha1(source.value);
  const size = 300;

  identityIcon.innerHTML = generateIcon(hash, size);
});

/**
 * downloadボタン
 */
download.addEventListener('click', () => {
  const hash = sha1(source.value);
  const size = 300;

  identityIcon.innerHTML = generateIcon(hash, size);
  const svg = identityIcon.querySelector('svg');
  const svgData = new XMLSerializer().serializeToString(svg);
  const canvas =...