Skip to content

Commit d5dea1f

Browse files
authored
Merge pull request #53 from HashLips/dev
v1.0.6 Update
2 parents df892d6 + f8b189f commit d5dea1f

10 files changed

Lines changed: 138 additions & 52 deletions

File tree

README.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,11 @@ const layerConfigurations = [
101101
];
102102
```
103103

104-
Then optionally, update your `format` size, ie the outputted image size, and the `growEditionSizeTo` on each `layerConfigurations` object, which is the amount of variation outputted.
104+
Update your `format` size, ie the outputted image size, and the `growEditionSizeTo` on each `layerConfigurations` object, which is the amount of variation outputted.
105+
106+
You can mix up the `layerConfigurations` order on how the images are saved by setting the variable `shuffleLayerConfigurations` in the `config.js` file to true. It is false by default and will save all images in numerical order.
107+
108+
If you want to have logs to debug and see what is happening when you generate images you can set the variable `debugLogs` in the `config.js` file to true. It is false by default, so you will only see general logs.
105109

106110
If you want to play around with different blending modes, you can add a `blend: MODE.colorBurn` field to the layersOrder object. If you need a layers to have a different opacity then you can add the `opacity: 0.7` field to the layersOrder object as well. Both the `blend: MODE.colorBurn` and `opacity: 0.7` can be addes on the same layer if you want to.
107111

@@ -157,7 +161,7 @@ const MODE = {
157161
};
158162
```
159163

160-
When you are all ready, run the following command and your outputted art will be in the `build/images` directory and the json in the `build/json` directory:
164+
When you are ready, run the following command and your outputted art will be in the `build/images` directory and the json in the `build/json` directory:
161165

162166
```sh
163167
npm run build
@@ -192,6 +196,20 @@ The program will output all the images in the `build/images` directory along wit
192196
}
193197
```
194198

199+
You can also add extra metadata to each metadata file by adding your extra items, (key: value) pairs to the `extraMetadata` object variable in the `config.js` file.
200+
201+
```js
202+
const extraMetadata = {
203+
creator: "Daniel Eugene Botha",
204+
};
205+
```
206+
207+
If you don't need extra metadata, simply leave the object empty. It is empty by default.
208+
209+
```js
210+
const extraMetadata = {};
211+
```
212+
195213
That's it, you're done.
196214

197215
## Utils
@@ -232,14 +250,14 @@ The output will look something like this:
232250

233251
```sh
234252
Trait type: Bottom lid
235-
{ trait: 'High', chance: '20', occurrence: '40' }
236-
{ trait: 'Low', chance: '40', occurrence: '60' }
237-
{ trait: 'Middle', chance: '40', occurrence: '0' }
238-
239-
Trait type: Top lid
240-
{ trait: 'High', chance: '30', occurrence: '20' }
241-
{ trait: 'Low', chance: '20', occurrence: '40' }
242-
{ trait: 'Middle', chance: '50', occurrence: '40' }
253+
{ trait: 'High', chance: '20', occurrence: '15% out of 100%' }
254+
{ trait: 'Low', chance: '40', occurrence: '40% out of 100%' }
255+
{ trait: 'Middle', chance: '40', occurrence: '45% out of 100%' }
256+
257+
Trait type: Iris
258+
{ trait: 'Large', chance: '20', occurrence: '15% out of 100%' }
259+
{ trait: 'Medium', chance: '20', occurrence: '15% out of 100%' }
260+
{ trait: 'Small', chance: '60', occurrence: '70% out of 100%' }
243261
```
244262
245263
Hope you create some awesome artworks with this code 👄

index.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
const { startCreating, buildSetup } = require("./src/main.js");
1+
"use strict";
2+
3+
const path = require("path");
4+
const isLocal = typeof process.pkg === "undefined";
5+
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
6+
const { startCreating, buildSetup } = require(path.join(
7+
basePath,
8+
"/src/main.js"
9+
));
210

311
(() => {
412
buildSetup();

package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,10 @@
66
"bin": "index.js",
77
"pkg": {
88
"assets": [
9-
"layers/**/*"
10-
],
11-
"scripts": [
12-
"src/main.js",
13-
"src/config.js"
14-
],
15-
"outputPath": "dist"
9+
"layers/**/*",
10+
"node_modules/**/*",
11+
"src/**/*"
12+
]
1613
},
1714
"scripts": {
1815
"build": "node index.js",

src/blendMode.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
"use strict";
2+
13
const MODE = {
24
sourceOver: "source-over",
35
sourceIn: "source-in",

src/config.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
1-
const { MODE } = require("./blendMode.js");
1+
"use strict";
2+
3+
const path = require("path");
4+
const isLocal = typeof process.pkg === "undefined";
5+
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
6+
const { MODE } = require(path.join(basePath, "src/blendMode.js"));
27
const description =
38
"This is the description of your NFT project, remember to replace this";
4-
const baseUri = "ipfs://QmNfPMWLPTEbFpBtPFy4wkYEHRVWcz8dzjziTcPbebzF53";
9+
const baseUri = "ipfs://NewUriToReplace";
510

611
const layerConfigurations = [
712
{
8-
growEditionSizeTo: 20,
13+
growEditionSizeTo: 10,
914
layersOrder: [
1015
{ name: "Background" },
1116
{ name: "Eyeball" },
@@ -18,6 +23,10 @@ const layerConfigurations = [
1823
},
1924
];
2025

26+
const shuffleLayerConfigurations = false;
27+
28+
const debugLogs = false;
29+
2130
const format = {
2231
width: 512,
2332
height: 512,
@@ -28,17 +37,19 @@ const background = {
2837
brightness: "80%",
2938
};
3039

40+
const extraMetadata = {};
41+
42+
const rarityDelimiter = "#";
43+
44+
const uniqueDnaTorrance = 10000;
45+
3146
const preview = {
3247
thumbPerRow: 5,
3348
thumbWidth: 50,
3449
imageRatio: format.width / format.height,
3550
imageName: "preview.png",
3651
};
3752

38-
const rarityDelimiter = "#";
39-
40-
const uniqueDnaTorrance = 10000;
41-
4253
module.exports = {
4354
format,
4455
baseUri,
@@ -48,4 +59,7 @@ module.exports = {
4859
layerConfigurations,
4960
rarityDelimiter,
5061
preview,
62+
shuffleLayerConfigurations,
63+
debugLogs,
64+
extraMetadata,
5165
};

src/main.js

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
1-
const fs = require("fs");
1+
"use strict";
2+
23
const path = require("path");
3-
const sha1 = require("sha1");
4-
const { createCanvas, loadImage } = require("canvas");
54
const isLocal = typeof process.pkg === "undefined";
65
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
7-
const buildDir = `${basePath}/build`;
8-
const layersDir = `${basePath}/layers`;
6+
const fs = require("fs");
7+
const sha1 = require(path.join(basePath, "/node_modules/sha1"));
8+
const { createCanvas, loadImage } = require(path.join(
9+
basePath,
10+
"/node_modules/canvas"
11+
));
12+
const buildDir = path.join(basePath, "/build");
13+
const layersDir = path.join(basePath, "/layers");
14+
console.log(path.join(basePath, "/src/config.js"));
915
const {
1016
format,
1117
baseUri,
@@ -14,8 +20,10 @@ const {
1420
uniqueDnaTorrance,
1521
layerConfigurations,
1622
rarityDelimiter,
23+
shuffleLayerConfigurations,
24+
debugLogs,
25+
extraMetadata,
1726
} = require(path.join(basePath, "/src/config.js"));
18-
const console = require("console");
1927
const canvas = createCanvas(format.width, format.height);
2028
const ctx = canvas.getContext("2d");
2129
var metadataList = [];
@@ -27,8 +35,8 @@ const buildSetup = () => {
2735
fs.rmdirSync(buildDir, { recursive: true });
2836
}
2937
fs.mkdirSync(buildDir);
30-
fs.mkdirSync(`${buildDir}/json`);
31-
fs.mkdirSync(`${buildDir}/images`);
38+
fs.mkdirSync(path.join(buildDir, "/json"));
39+
fs.mkdirSync(path.join(buildDir, "/images"));
3240
};
3341

3442
const getRarityWeight = (_str) => {
@@ -107,6 +115,7 @@ const addMetadata = (_dna, _edition) => {
107115
image: `${baseUri}/${_edition}.png`,
108116
edition: _edition,
109117
date: dateTime,
118+
...extraMetadata,
110119
attributes: attributesList,
111120
compiler: "HashLips Art Engine",
112121
};
@@ -183,20 +192,50 @@ const writeMetaData = (_data) => {
183192
};
184193

185194
const saveMetaDataSingleFile = (_editionCount) => {
195+
let metadata = metadataList.find((meta) => meta.edition == _editionCount);
196+
debugLogs
197+
? console.log(
198+
`Writing metadata for ${_editionCount}: ${JSON.stringify(metadata)}`
199+
)
200+
: null;
186201
fs.writeFileSync(
187202
`${buildDir}/json/${_editionCount}.json`,
188-
JSON.stringify(
189-
metadataList.find((meta) => meta.edition == _editionCount),
190-
null,
191-
2
192-
)
203+
JSON.stringify(metadata, null, 2)
193204
);
194205
};
195206

207+
function shuffle(array) {
208+
let currentIndex = array.length,
209+
randomIndex;
210+
while (currentIndex != 0) {
211+
randomIndex = Math.floor(Math.random() * currentIndex);
212+
currentIndex--;
213+
[array[currentIndex], array[randomIndex]] = [
214+
array[randomIndex],
215+
array[currentIndex],
216+
];
217+
}
218+
return array;
219+
}
220+
196221
const startCreating = async () => {
197222
let layerConfigIndex = 0;
198223
let editionCount = 1;
199224
let failedCount = 0;
225+
let abstractedIndexes = [];
226+
for (
227+
let i = 1;
228+
i <= layerConfigurations[layerConfigurations.length - 1].growEditionSizeTo;
229+
i++
230+
) {
231+
abstractedIndexes.push(i);
232+
}
233+
if (shuffleLayerConfigurations) {
234+
abstractedIndexes = shuffle(abstractedIndexes);
235+
}
236+
debugLogs
237+
? console.log("Editions left to create: ", abstractedIndexes)
238+
: null;
200239
while (layerConfigIndex < layerConfigurations.length) {
201240
const layers = layersSetup(
202241
layerConfigurations[layerConfigIndex].layersOrder
@@ -214,24 +253,29 @@ const startCreating = async () => {
214253
});
215254

216255
await Promise.all(loadedElements).then((renderObjectArray) => {
256+
debugLogs ? console.log("Clearing casvas") : null;
217257
ctx.clearRect(0, 0, format.width, format.height);
218258
if (background.generate) {
219259
drawBackground();
220260
}
221261
renderObjectArray.forEach((renderObject) => {
222262
drawElement(renderObject);
223263
});
224-
saveImage(editionCount);
225-
addMetadata(newDna, editionCount);
226-
saveMetaDataSingleFile(editionCount);
264+
debugLogs
265+
? console.log("Editions left to create: ", abstractedIndexes)
266+
: null;
267+
saveImage(abstractedIndexes[0]);
268+
addMetadata(newDna, abstractedIndexes[0]);
269+
saveMetaDataSingleFile(abstractedIndexes[0]);
227270
console.log(
228-
`Created edition: ${editionCount}, with DNA: ${sha1(
271+
`Created edition: ${abstractedIndexes[0]}, with DNA: ${sha1(
229272
newDna.join("")
230273
)}`
231274
);
232275
});
233276
dnaList.push(newDna);
234277
editionCount++;
278+
abstractedIndexes.shift();
235279
} else {
236280
console.log("DNA exists!");
237281
failedCount++;

utils/createPreviewCollage.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
"use strict";
22

3+
const isLocal = typeof process.pkg === "undefined";
4+
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
35
const fs = require("fs");
46
const path = require("path");
57
const { createCanvas, loadImage } = require("canvas");
6-
const isLocal = typeof process.pkg === "undefined";
7-
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
88
const buildDir = `${basePath}/build`;
99

10-
const { preview } = require("../src/config.js");
10+
console.log(path.join(basePath, "/src/config.js"));
11+
const { preview } = require(path.join(basePath, "/src/config.js"));
1112

1213
// read json data
1314
const rawdata = fs.readFileSync(`${basePath}/build/json/_metadata.json`);

utils/rarityData.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"use strict";
22

3-
const fs = require("fs");
43
const path = require("path");
54
const isLocal = typeof process.pkg === "undefined";
65
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
6+
const fs = require("fs");
77
const layersDir = `${basePath}/layers`;
88

9-
const { layerConfigurations } = require("../src/config.js");
9+
console.log(path.join(basePath, "/src/config.js"));
10+
const { layerConfigurations } = require(path.join(basePath, "/src/config.js"));
1011

1112
const { getElements } = require("../src/main.js");
1213

@@ -70,7 +71,7 @@ for (var layer in rarityData) {
7071

7172
// show two decimal places in percent
7273
rarityData[layer][attribute].occurrence =
73-
rarityData[layer][attribute].occurrence.toFixed(0);
74+
rarityData[layer][attribute].occurrence.toFixed(0) + "% out of 100%";
7475
}
7576
}
7677

utils/regenerateMetadata.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"use strict";
22

3-
const fs = require("fs");
4-
const path = require("path");
53
const isLocal = typeof process.pkg === "undefined";
64
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
5+
const fs = require("fs");
6+
const path = require("path");
77
const jsonDir = `${basePath}/build/json`;
88
const metadataFilePath = `${basePath}/build/json/_metadata.json`;
99

utils/updateBaseUri.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
"use strict";
22

3-
const fs = require("fs");
43
const path = require("path");
54
const isLocal = typeof process.pkg === "undefined";
65
const basePath = isLocal ? process.cwd() : path.dirname(process.execPath);
6+
const fs = require("fs");
77

8-
const { baseUri } = require("../src/config.js");
8+
console.log(path.join(basePath, "/src/config.js"));
9+
const { baseUri } = require(path.join(basePath, "/src/config.js"));
910

1011
// read json data
1112
let rawdata = fs.readFileSync(`${basePath}/build/json/_metadata.json`);

0 commit comments

Comments
 (0)