summaryrefslogtreecommitdiff
path: root/src/misc/gen-avatar.ts
blob: 14c01a9bd992d2c23938307b54a7eaa9ecb67593 (plain)
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
80
81
82
83
84
85
86
87
88
89
90
/**
 * Random avatar generator
 */

const p = require('pureimage');
import * as gen from 'random-seed';
import { WriteStream } from 'fs';

const size = 256; // px
const n = 5; // resolution
const margin = (size / n) / 1.5;
const colors = [
	'#e57373',
	'#F06292',
	'#BA68C8',
	'#9575CD',
	'#7986CB',
	'#64B5F6',
	'#4FC3F7',
	'#4DD0E1',
	'#4DB6AC',
	'#81C784',
	'#8BC34A',
	'#AFB42B',
	'#F57F17',
	'#FF5722',
	'#795548',
	'#455A64',
];
const bg = '#e9e9e9';

const actualSize = size - (margin * 2);
const cellSize = actualSize / n;
const sideN = Math.floor(n / 2);

/**
 * Generate buffer of random avatar by seed
 */
export function genAvatar(seed: string, stream: WriteStream): Promise<void> {
	const rand = gen.create(seed);
	const canvas = p.make(size, size);
	const ctx = canvas.getContext('2d');

	ctx.fillStyle = bg;
	ctx.beginPath();
	ctx.fillRect(0, 0, size, size);

	ctx.fillStyle = colors[rand(colors.length)];

	// side bitmap (filled by false)
	const side: boolean[][] = new Array(sideN);
	for (let i = 0; i < side.length; i++) {
		side[i] = new Array(n).fill(false);
	}

	// 1*n (filled by false)
	const center: boolean[] = new Array(n).fill(false);

	// tslint:disable-next-line:prefer-for-of
	for (let x = 0; x < side.length; x++) {
		for (let y = 0; y < side[x].length; y++) {
			side[x][y] = rand(3) === 0;
		}
	}

	for (let i = 0; i < center.length; i++) {
		center[i] = rand(3) === 0;
	}

	// Draw
	for (let x = 0; x < n; x++) {
		for (let y = 0; y < n; y++) {
			const isXCenter = x === ((n - 1) / 2);
			if (isXCenter && !center[y]) continue;

			const isLeftSide = x < ((n - 1) / 2);
			if (isLeftSide && !side[x][y]) continue;

			const isRightSide = x > ((n - 1) / 2);
			if (isRightSide && !side[sideN - (x - sideN)][y]) continue;

			const actualX = margin + (cellSize * x);
			const actualY = margin + (cellSize * y);
			ctx.beginPath();
			ctx.fillRect(actualX, actualY, cellSize, cellSize);
		}
	}

	return p.encodePNGToStream(canvas, stream);
}