mirror of
https://github.com/shadoll/sLogos.git
synced 2025-12-20 04:27:59 +00:00
feat: add script and workflow step for generating SVG variants from logos
This commit is contained in:
190
scripts/generate-svg-variants.js
Normal file
190
scripts/generate-svg-variants.js
Normal file
@@ -0,0 +1,190 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const LOGOS_DIR = path.join(__dirname, '..', 'public', 'logos');
|
||||
const LOGOS_GEN_DIR = path.join(__dirname, '..', 'public', 'logos_gen');
|
||||
|
||||
// Try multiple possible locations for logos.json
|
||||
const POSSIBLE_LOGOS_JSON_PATHS = [
|
||||
path.join(process.cwd(), 'public', 'data', 'logos.json'), // Correct location after scan-logos
|
||||
path.join(__dirname, '..', 'public', 'data', 'logos.json'),
|
||||
path.join(process.cwd(), 'public', 'logos.json'),
|
||||
path.join(__dirname, '..', 'public', 'logos.json'),
|
||||
path.join(__dirname, '..', 'src', 'data', 'logos.json')
|
||||
];
|
||||
|
||||
function findLogosJsonPath() {
|
||||
for (const possiblePath of POSSIBLE_LOGOS_JSON_PATHS) {
|
||||
if (fs.existsSync(possiblePath)) {
|
||||
console.log(`📁 Found logos.json at: ${possiblePath}`);
|
||||
return possiblePath;
|
||||
}
|
||||
}
|
||||
|
||||
console.error('❌ Could not find logos.json in any of these locations:');
|
||||
POSSIBLE_LOGOS_JSON_PATHS.forEach(p => console.error(` ${p}`));
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load logos data from logos.json
|
||||
*/
|
||||
function loadLogosData() {
|
||||
const LOGOS_JSON_PATH = findLogosJsonPath();
|
||||
|
||||
if (!LOGOS_JSON_PATH) {
|
||||
console.error('❌ logos.json file not found');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(LOGOS_JSON_PATH, 'utf8');
|
||||
return JSON.parse(data);
|
||||
} catch (error) {
|
||||
console.error('Error loading logos.json:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply color set to SVG content
|
||||
*/
|
||||
function applySvgColors(svgContent, colorSet, targets) {
|
||||
let modifiedSvg = svgContent;
|
||||
|
||||
if (!targets || !colorSet) {
|
||||
return modifiedSvg;
|
||||
}
|
||||
|
||||
// Apply colors based on targets mapping
|
||||
Object.entries(targets).forEach(([targetKey, selector]) => {
|
||||
if (colorSet[targetKey]) {
|
||||
const color = colorSet[targetKey];
|
||||
|
||||
// Handle different types of selectors
|
||||
if (selector.startsWith('#')) {
|
||||
// ID selector - replace fill/stroke for specific element
|
||||
const elementId = selector.substring(1);
|
||||
const idRegex = new RegExp(`(id="${elementId}"[^>]*?)fill="[^"]*"`, 'g');
|
||||
modifiedSvg = modifiedSvg.replace(idRegex, `$1fill="${color}"`);
|
||||
|
||||
// If no fill attribute, add it
|
||||
const addFillRegex = new RegExp(`(id="${elementId}"[^>]*?)(?!.*fill=)([^>]*>)`, 'g');
|
||||
modifiedSvg = modifiedSvg.replace(addFillRegex, `$1 fill="${color}"$2`);
|
||||
} else {
|
||||
// Default: replace all fill attributes (fallback)
|
||||
modifiedSvg = modifiedSvg.replace(
|
||||
/fill="[^"]*"/g,
|
||||
`fill="${color}"`
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return modifiedSvg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate SVG variants with color sets
|
||||
*/
|
||||
function generateSvgVariants() {
|
||||
console.log('🎨 Generating SVG variants with color sets...');
|
||||
|
||||
// Ensure the logos_gen directory exists
|
||||
if (!fs.existsSync(LOGOS_GEN_DIR)) {
|
||||
fs.mkdirSync(LOGOS_GEN_DIR, { recursive: true });
|
||||
console.log(`📁 Created directory: ${LOGOS_GEN_DIR}`);
|
||||
}
|
||||
|
||||
const logos = loadLogosData();
|
||||
let generatedCount = 0;
|
||||
let skippedCount = 0;
|
||||
|
||||
if (!Array.isArray(logos)) {
|
||||
console.error('❌ Expected logos.json to contain an array, got:', typeof logos);
|
||||
process.exit(1);
|
||||
} console.log(`📊 Processing ${logos.length} logos...`);
|
||||
|
||||
logos.forEach((logo, index) => {
|
||||
// Check if logo has required properties
|
||||
if (!logo || typeof logo !== 'object') {
|
||||
console.warn(`⚠️ Logo at index ${index} is not a valid object`);
|
||||
skippedCount++;
|
||||
return;
|
||||
}// Handle different possible filename properties
|
||||
const pathOrFilename = logo.path || logo.filename || logo.file || logo.name;
|
||||
|
||||
if (!pathOrFilename) {
|
||||
console.warn(`⚠️ Logo at index ${index} has no path/filename property`);
|
||||
skippedCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Extract just the filename from path if needed
|
||||
const actualFilename = pathOrFilename.includes('/') ? path.basename(pathOrFilename) : pathOrFilename;
|
||||
|
||||
// Skip if no sets or not an SVG
|
||||
if (!logo.sets || !actualFilename.endsWith('.svg')) {
|
||||
skippedCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
const basePath = path.join(LOGOS_DIR, actualFilename);
|
||||
const baseNameWithoutExt = path.basename(actualFilename, '.svg'); // Check if base SVG exists
|
||||
if (!fs.existsSync(basePath)) {
|
||||
console.warn(`⚠️ Base SVG not found: ${actualFilename}`);
|
||||
skippedCount++;
|
||||
return;
|
||||
}
|
||||
|
||||
// Read the base SVG content
|
||||
const baseSvgContent = fs.readFileSync(basePath, 'utf8');
|
||||
|
||||
// Generate variants for each color set
|
||||
// Handle sets as object (not array)
|
||||
Object.entries(logo.sets).forEach(([setName, setConfig]) => {
|
||||
if (!setName || !setConfig) {
|
||||
console.warn(`⚠️ Invalid set in ${actualFilename}: missing name or config`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert set config to colors object
|
||||
const colors = {};
|
||||
if (logo.colors && logo.targets) {
|
||||
Object.entries(setConfig).forEach(([targetKey, colorKey]) => {
|
||||
if (logo.colors[colorKey]) {
|
||||
colors[targetKey] = logo.colors[colorKey];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (Object.keys(colors).length === 0) {
|
||||
console.warn(`⚠️ No valid colors found for set ${setName} in ${actualFilename}`);
|
||||
return;
|
||||
} const variantFilename = `${baseNameWithoutExt}__${setName}.svg`;
|
||||
const variantPath = path.join(LOGOS_GEN_DIR, variantFilename);
|
||||
|
||||
// Apply colors to SVG
|
||||
const modifiedSvg = applySvgColors(baseSvgContent, colors, logo.targets);
|
||||
|
||||
// Write the variant SVG
|
||||
fs.writeFileSync(variantPath, modifiedSvg, 'utf8');
|
||||
|
||||
console.log(`✅ Generated: ${variantFilename}`);
|
||||
generatedCount++;
|
||||
});
|
||||
});
|
||||
|
||||
console.log(`\n🎨 SVG variant generation complete!`);
|
||||
console.log(` Generated: ${generatedCount} variants`);
|
||||
console.log(` Skipped: ${skippedCount} logos (no sets or not SVG)`);
|
||||
}
|
||||
|
||||
// Run the script
|
||||
if (require.main === module) {
|
||||
generateSvgVariants();
|
||||
}
|
||||
|
||||
module.exports = { generateSvgVariants };
|
||||
Reference in New Issue
Block a user