forked from fireship-io/nft-art-generator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
123 lines (97 loc) · 3.7 KB
/
index.js
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
const { readFileSync, writeFileSync, readdirSync, rmSync, existsSync, mkdirSync } = require('fs');
const sharp = require('sharp');
const template = `
<svg width="256" height="256" viewBox="0 0 256 256" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- bg -->
<!-- head -->
<!-- hair -->
<!-- eyes -->
<!-- nose -->
<!-- mouth -->
<!-- beard -->
</svg>
`
const takenNames = {};
const takenFaces = {};
let idx = 999;
function randInt(max) {
return Math.floor(Math.random() * (max + 1));
}
function randElement(arr) {
return arr[Math.floor(Math.random() * arr.length)];
}
function getRandomName() {
const adjectives = 'fired trashy tubular nasty jacked swol buff ferocious firey flamin agnostic artificial bloody crazy cringey crusty dirty eccentric glutinous harry juicy simple stylish awesome creepy corny freaky shady sketchy lame sloppy hot intrepid juxtaposed killer ludicrous mangy pastey ragin rusty rockin sinful shameful stupid sterile ugly vascular wild young old zealous flamboyant super sly shifty trippy fried injured depressed anxious clinical'.split(' ');
const names = 'aaron bart chad dale earl fred grady harry ivan jeff joe kyle lester steve tanner lucifer todd mitch hunter mike arnold norbert olaf plop quinten randy saul balzac tevin jack ulysses vince will xavier yusuf zack roger raheem rex dustin seth bronson dennis'.split(' ');
const randAdj = randElement(adjectives);
const randName = randElement(names);
const name = `${randAdj}-${randName}`;
if (takenNames[name] || !name) {
return getRandomName();
} else {
takenNames[name] = name;
return name;
}
}
function getLayer(name, skip=0.0) {
const svg = readFileSync(`./layers/${name}.svg`, 'utf-8');
const re = /(?<=\<svg\s*[^>]*>)([\s\S]*?)(?=\<\/svg\>)/g
const layer = svg.match(re)[0];
return Math.random() > skip ? layer : '';
}
async function svgToPng(name) {
const src = `./out/${name}.svg`;
const dest = `./out/${name}.png`;
const img = await sharp(src);
const resized = await img.resize(1024);
await resized.toFile(dest);
}
function createImage(idx) {
const bg = randInt(5);
const hair = randInt(7);
const eyes = randInt(9);
const nose = randInt(4);
const mouth = randInt(5);
const beard = randInt(3);
// 18,900 combinations
const face = [hair, eyes, mouth, nose, beard].join('');
if (face[takenFaces]) {
createImage();
} else {
const name = getRandomName()
console.log(name)
face[takenFaces] = face;
const final = template
.replace('<!-- bg -->', getLayer(`bg${bg}`))
.replace('<!-- head -->', getLayer('head0'))
.replace('<!-- hair -->', getLayer(`hair${hair}`))
.replace('<!-- eyes -->', getLayer(`eyes${eyes}`))
.replace('<!-- nose -->', getLayer(`nose${nose}`))
.replace('<!-- mouth -->', getLayer(`mouth${mouth}`))
.replace('<!-- beard -->', getLayer(`beard${beard}`, 0.5))
const meta = {
name,
description: `A drawing of ${name.split('-').join(' ')}`,
image: `${idx}.png`,
attributes: [
{
beard: '',
rarity: 0.5
}
]
}
writeFileSync(`./out/${idx}.json`, JSON.stringify(meta))
writeFileSync(`./out/${idx}.svg`, final)
svgToPng(idx)
}
}
// Create dir if not exists
if (!existsSync('./out')){
mkdirSync('./out');
}
// Cleanup dir before each run
readdirSync('./out').forEach(f => rmSync(`./out/${f}`));
do {
createImage(idx);
idx--;
} while (idx >= 0);