Tend your corner of the atmosphere. spores.garden turns your AT Protocol records into a personal site with unique themes. Your data never leaves your PDS. Grow something that's truly yours. spores.garden
at main 135 lines 4.1 kB view raw
1/** 2 * Flower Grid Visualization Script 3 * 4 * Generates flower visualizations as PNG images. 5 * 6 * Usage: 7 * npx tsx scripts/visualize-flowers.ts <count> # Generate <count> grids of 256 flowers 8 * npx tsx scripts/visualize-flowers.ts <did> # Generate single flower from specific DID 9 */ 10 11import sharp from 'sharp'; 12import { generateFlowerSVGString } from '../src/utils/flower-svg'; 13 14const GRID_SIZE = 16; 15const TOTAL_FLOWERS = GRID_SIZE * GRID_SIZE; // 256 16const OUTPUT_SIZE = 2000; 17const CELL_SIZE = OUTPUT_SIZE / GRID_SIZE; // 125 18const FLOWER_SIZE = 100; // viewBox size of each flower 19 20/** 21 * Generate unique seed DIDs for diverse flowers 22 */ 23function generateSeeds(count: number, gridIndex: number): string[] { 24 const seeds: string[] = []; 25 const timestamp = Date.now(); 26 for (let i = 0; i < count; i++) { 27 // Use varied seed patterns for maximum diversity 28 seeds.push(`did:plc:flower-grid-${gridIndex}-${i}-${timestamp}`); 29 } 30 return seeds; 31} 32 33/** 34 * Extract inner SVG content (without wrapper) from a flower SVG string 35 */ 36function extractSVGContent(svgString: string): string { 37 // Match content between <svg ...> and </svg> 38 const match = svgString.match(/<svg[^>]*>([\s\S]*?)<\/svg>/i); 39 return match ? match[1].trim() : ''; 40} 41 42/** 43 * Build a combined SVG with all flowers arranged in a grid 44 */ 45function buildGridSVG(seeds: string[]): string { 46 const flowerGroups: string[] = []; 47 48 for (let i = 0; i < seeds.length; i++) { 49 const row = Math.floor(i / GRID_SIZE); 50 const col = i % GRID_SIZE; 51 52 // Calculate position in output coordinates 53 const x = col * CELL_SIZE + (CELL_SIZE - FLOWER_SIZE) / 2; 54 const y = row * CELL_SIZE + (CELL_SIZE - FLOWER_SIZE) / 2; 55 56 // Generate flower SVG and extract its content 57 const flowerSVG = generateFlowerSVGString(seeds[i], FLOWER_SIZE); 58 const innerContent = extractSVGContent(flowerSVG); 59 60 // Wrap in a group with translation 61 flowerGroups.push(` 62 <g transform="translate(${x}, ${y})"> 63 ${innerContent} 64 </g>`); 65 } 66 67 // Build the final SVG 68 return `<?xml version="1.0" encoding="UTF-8"?> 69<svg width="${OUTPUT_SIZE}" height="${OUTPUT_SIZE}" viewBox="0 0 ${OUTPUT_SIZE} ${OUTPUT_SIZE}" xmlns="http://www.w3.org/2000/svg"> 70 <rect width="100%" height="100%" fill="#f8f8f8"/> 71 ${flowerGroups.join('\n')} 72</svg>`; 73} 74 75async function generateGrid(gridIndex: number): Promise<string> { 76 // Generate unique seeds for this grid 77 const seeds = generateSeeds(TOTAL_FLOWERS, gridIndex); 78 79 // Build combined SVG 80 const gridSVG = buildGridSVG(seeds); 81 82 // Convert to PNG using sharp 83 const outputPath = `flower-grid-${gridIndex + 1}.png`; 84 85 await sharp(Buffer.from(gridSVG)) 86 .resize(OUTPUT_SIZE, OUTPUT_SIZE) 87 .png() 88 .toFile(outputPath); 89 90 return outputPath; 91} 92 93async function generateSingleFlower(did: string): Promise<string> { 94 const flowerSize = 500; 95 const flowerSVG = generateFlowerSVGString(did, flowerSize); 96 97 // Create output filename from DID (sanitize for filesystem) 98 const sanitizedDid = did.replace(/:/g, '-'); 99 const outputPath = `flower-${sanitizedDid}.png`; 100 101 await sharp(Buffer.from(flowerSVG)) 102 .resize(flowerSize, flowerSize) 103 .png() 104 .toFile(outputPath); 105 106 return outputPath; 107} 108 109async function main() { 110 const firstArg = process.argv[2]; 111 112 // Check if first argument is a DID 113 if (firstArg && firstArg.startsWith('did:')) { 114 console.log(`Generating single flower for DID: ${firstArg}...`); 115 const outputPath = await generateSingleFlower(firstArg); 116 console.log(`Saved to ${outputPath}`); 117 console.log('\nDone!'); 118 return; 119 } 120 121 // Otherwise, generate grids 122 const count = parseInt(firstArg || '1', 10); 123 124 console.log(`Generating ${count} grid(s), each with ${TOTAL_FLOWERS} flowers (${GRID_SIZE}x${GRID_SIZE})...`); 125 126 for (let i = 0; i < count; i++) { 127 console.log(`\nGenerating grid ${i + 1}/${count}...`); 128 const outputPath = await generateGrid(i); 129 console.log(`Saved to ${outputPath}`); 130 } 131 132 console.log('\nDone!'); 133} 134 135main().catch(console.error);