102 lines
No EOL
3.9 KiB
JavaScript
102 lines
No EOL
3.9 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Simple PWA icon generator for Great Lakes Ice Report
|
|
* Creates basic icons using Canvas API for different sizes
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Icon sizes needed for PWA
|
|
const SIZES = [72, 96, 128, 144, 152, 192, 384, 512];
|
|
const MASKABLE_SIZES = [192, 512];
|
|
|
|
// Create icons directory if it doesn't exist
|
|
const iconsDir = path.join(__dirname, '../public/icons');
|
|
if (!fs.existsSync(iconsDir)) {
|
|
fs.mkdirSync(iconsDir, { recursive: true });
|
|
}
|
|
|
|
/**
|
|
* Generate SVG icon content
|
|
*/
|
|
function generateSVG(size, isMaskable = false) {
|
|
const padding = isMaskable ? size * 0.1 : 0; // 10% padding for maskable icons
|
|
const iconSize = size - (padding * 2);
|
|
const iconOffset = padding;
|
|
|
|
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
<svg width="${size}" height="${size}" viewBox="0 0 ${size} ${size}" xmlns="http://www.w3.org/2000/svg">
|
|
<defs>
|
|
<linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" style="stop-color:#2196F3;stop-opacity:1" />
|
|
<stop offset="100%" style="stop-color:#1976D2;stop-opacity:1" />
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<!-- Background circle -->
|
|
<circle cx="${size/2}" cy="${size/2}" r="${size/2}" fill="url(#bg)"/>
|
|
|
|
<!-- Ice crystal/snowflake icon -->
|
|
<g transform="translate(${iconOffset + iconSize/2}, ${iconOffset + iconSize/2})">
|
|
<!-- Main cross -->
|
|
<line x1="${-iconSize*0.3}" y1="0" x2="${iconSize*0.3}" y2="0" stroke="white" stroke-width="${iconSize*0.08}" stroke-linecap="round"/>
|
|
<line x1="0" y1="${-iconSize*0.3}" x2="0" y2="${iconSize*0.3}" stroke="white" stroke-width="${iconSize*0.08}" stroke-linecap="round"/>
|
|
|
|
<!-- Diagonal lines -->
|
|
<line x1="${-iconSize*0.21}" y1="${-iconSize*0.21}" x2="${iconSize*0.21}" y2="${iconSize*0.21}" stroke="white" stroke-width="${iconSize*0.06}" stroke-linecap="round"/>
|
|
<line x1="${iconSize*0.21}" y1="${-iconSize*0.21}" x2="${-iconSize*0.21}" y2="${iconSize*0.21}" stroke="white" stroke-width="${iconSize*0.06}" stroke-linecap="round"/>
|
|
|
|
<!-- Small decorative elements -->
|
|
<circle cx="0" cy="0" r="${iconSize*0.04}" fill="white"/>
|
|
<circle cx="${iconSize*0.15}" cy="0" r="${iconSize*0.02}" fill="white"/>
|
|
<circle cx="${-iconSize*0.15}" cy="0" r="${iconSize*0.02}" fill="white"/>
|
|
<circle cx="0" cy="${iconSize*0.15}" r="${iconSize*0.02}" fill="white"/>
|
|
<circle cx="0" cy="${-iconSize*0.15}" r="${iconSize*0.02}" fill="white"/>
|
|
</g>
|
|
|
|
${isMaskable ? `<!-- Safe zone indicator (invisible) -->
|
|
<circle cx="${size/2}" cy="${size/2}" r="${size*0.4}" fill="none" stroke="none"/>` : ''}
|
|
</svg>`;
|
|
}
|
|
|
|
// Generate all required icon sizes
|
|
console.log('🎨 Generating PWA icons...');
|
|
|
|
// Generate regular icons
|
|
for (const size of SIZES) {
|
|
const svgContent = generateSVG(size, false);
|
|
|
|
// Save as SVG
|
|
const svgFilename = `icon-${size}.svg`;
|
|
const svgFilepath = path.join(iconsDir, svgFilename);
|
|
fs.writeFileSync(svgFilepath, svgContent);
|
|
|
|
console.log(`✅ Generated ${svgFilename}`);
|
|
}
|
|
|
|
// Generate maskable icons
|
|
for (const size of MASKABLE_SIZES) {
|
|
const svgContent = generateSVG(size, true);
|
|
const svgFilename = `icon-${size}-maskable.svg`;
|
|
const svgFilepath = path.join(iconsDir, svgFilename);
|
|
fs.writeFileSync(svgFilepath, svgContent);
|
|
|
|
console.log(`✅ Generated ${svgFilename} (maskable)`);
|
|
}
|
|
|
|
// Create a simple favicon.ico reference
|
|
const faviconSVG = generateSVG(32, false);
|
|
fs.writeFileSync(path.join(iconsDir, 'favicon.svg'), faviconSVG);
|
|
|
|
console.log('🎉 Icon generation complete!');
|
|
console.log('📁 Icons saved to:', iconsDir);
|
|
console.log('');
|
|
console.log('📝 Note: SVG icons are generated for development.');
|
|
console.log(' For production, convert these to PNG using a tool like:');
|
|
console.log(' - sharp (Node.js)');
|
|
console.log(' - ImageMagick');
|
|
console.log(' - Online converters');
|
|
console.log('');
|
|
console.log('💡 To use PNG icons, update the file extensions in manifest.json'); |