91 lines
3.0 KiB
JavaScript
91 lines
3.0 KiB
JavaScript
const { createCanvas, loadImage } = require('canvas');
|
|
const fs = require('fs');
|
|
|
|
const width = 1000;
|
|
const height = 1000;
|
|
const canvas = createCanvas(width, height);
|
|
const ctx = canvas.getContext('2d');
|
|
|
|
// Configuration des calques et de la rareté (poids)
|
|
const layers = [
|
|
{
|
|
name: "Background",
|
|
elements: [
|
|
{ name: "Island", file: "Island.png", weight: 20 },
|
|
{ name: "Jungle", file: "Jungle.png", weight: 35 },
|
|
{ name: "Mountain", file: "Mountain.png", weight: 15 },
|
|
{ name: "Plain", file: "Plain.png", weight: 25 },
|
|
{ name: "Jurrasic", file: "Jurrasic.png", weight: 5 }
|
|
]
|
|
},
|
|
{
|
|
name: "beasts",
|
|
elements: [
|
|
{ name: "Flicko", file: "Flicko.png", weight: 20 },
|
|
{ name: "Darm", file: "Darm.png", weight: 15 },
|
|
{ name: "Shiny Darm", file: "Shiny Darm.png", weight: 5 },
|
|
{ name: "Marven", file: "Marven.png", weight: 20 },
|
|
{ name: "Jii", file: "Jii.png", weight: 20 },
|
|
{ name: "Tiro", file: "Tiro.png", weight: 15 },
|
|
{ name: "Shiny Tiro", file: "Shiny Tiro.png", weight: 5 },
|
|
]
|
|
},
|
|
{
|
|
name: "hat",
|
|
elements: [
|
|
{ name: "No hat", file: "No hat.png", weight: 35 },
|
|
{ name: "Cap", file: "Cap.png", weight: 25 },
|
|
{ name: "Fish", file: "Fish.png", weight: 10 },
|
|
{ name: "Magic", file: "Magic.png", weight: 30 },
|
|
{ name: "Pirate", file: "Pirate.png", weight: 20 }
|
|
]
|
|
}
|
|
];
|
|
|
|
// Fonction pour choisir un élément selon son poids (Rareté)
|
|
function pickElement(layer) {
|
|
let totalWeight = layer.elements.reduce((acc, el) => acc + el.weight, 0);
|
|
let random = Math.random() * totalWeight;
|
|
for (let el of layer.elements) {
|
|
if (random < el.weight) return el;
|
|
random -= el.weight;
|
|
}
|
|
}
|
|
|
|
async function createNFT(editionId) {
|
|
let attributes = [];
|
|
ctx.clearRect(0, 0, width, height);
|
|
|
|
// 1. Sélectionner et dessiner chaque calque
|
|
for (const layer of layers) {
|
|
const element = pickElement(layer);
|
|
const image = await loadImage(`./layers/${layer.name}/${element.file}`);
|
|
ctx.drawImage(image, 0, 0, width, height);
|
|
|
|
attributes.push({ trait_type: layer.name, value: element.name });
|
|
}
|
|
|
|
// 2. Sauvegarder l'image finale
|
|
const buffer = canvas.toBuffer('image/png');
|
|
fs.writeFileSync(`./output/${editionId}.png`, buffer);
|
|
|
|
// 3. Créer le fichier JSON Metadata (Standard Solana/Metaplex)
|
|
const metadata = {
|
|
name: `Beast #${editionId}`,
|
|
symbol: "BSTS",
|
|
image: `${editionId}.png`, // Sera remplacé par l'URL IPFS plus tard
|
|
attributes: attributes,
|
|
properties: {
|
|
files: [{ uri: `${editionId}.png`, type: "image/png" }]
|
|
}
|
|
};
|
|
fs.writeFileSync(`./output/${editionId}.json`, JSON.stringify(metadata, null, 2));
|
|
}
|
|
|
|
// Générer 10 NFTs
|
|
(async () => {
|
|
for (let i = 1; i <= 20; i++) {
|
|
await createNFT(i);
|
|
console.log(`NFT ${i} généré !`);
|
|
}
|
|
})(); |