← back to Watches

utils/generate-icons.js

203 lines

/**
 * Icon Generator for PWA
 * Creates app icons from SVG using canvas
 *
 * NOTE: This is a simple placeholder generator.
 * For production, use real Omega watch imagery or professional icon design.
 */

import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const ICON_SIZES = [72, 96, 128, 144, 152, 192, 384, 512];

// SVG icon template (Omega-inspired design)
const iconSVG = (size) => `
<svg width="${size}" height="${size}" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
  <!-- Background -->
  <rect width="512" height="512" fill="#0C1E3C"/>

  <!-- Omega Symbol Approximation (Circle with gap) -->
  <g transform="translate(256, 256)">
    <!-- Outer circle -->
    <circle cx="0" cy="0" r="180" fill="none" stroke="#C41E3A" stroke-width="24"/>

    <!-- Inner circle -->
    <circle cx="0" cy="0" r="120" fill="none" stroke="#C41E3A" stroke-width="16"/>

    <!-- Bottom gap -->
    <rect x="-20" y="140" width="40" height="80" fill="#0C1E3C"/>

    <!-- Bottom extensions -->
    <rect x="-140" y="180" width="100" height="24" rx="12" fill="#C41E3A"/>
    <rect x="40" y="180" width="100" height="24" rx="12" fill="#C41E3A"/>

    <!-- Watch hands -->
    <line x1="0" y1="0" x2="0" y2="-80" stroke="#fff" stroke-width="12" stroke-linecap="round"/>
    <line x1="0" y1="0" x2="60" y2="40" stroke="#fff" stroke-width="10" stroke-linecap="round"/>

    <!-- Center dot -->
    <circle cx="0" cy="0" r="16" fill="#C41E3A"/>
    <circle cx="0" cy="0" r="8" fill="#fff"/>
  </g>

  <!-- Text (for larger icons) -->
  ${size >= 192 ? `<text x="256" y="470" font-family="Arial, sans-serif" font-size="48" font-weight="bold" fill="#C41E3A" text-anchor="middle">OMEGA</text>` : ''}
</svg>
`;

// Generate PNG from SVG (requires sharp or similar, we'll use placeholder approach)
async function generateIcons() {
  console.log('Generating PWA icons...');

  const iconsDir = path.join(__dirname, '..', 'public', 'icons');

  // Ensure icons directory exists
  if (!fs.existsSync(iconsDir)) {
    fs.mkdirSync(iconsDir, { recursive: true });
  }

  // Generate SVG icons (as fallback)
  for (const size of ICON_SIZES) {
    const svg = iconSVG(size);
    const filename = `icon-${size}x${size}.svg`;
    const filepath = path.join(iconsDir, filename);

    fs.writeFileSync(filepath, svg);
    console.log(`Created ${filename}`);
  }

  // Create a simple HTML file that can be used to convert SVG to PNG
  const converterHTML = `
<!DOCTYPE html>
<html>
<head>
    <title>Icon Converter</title>
    <style>
        body { font-family: Arial; padding: 20px; }
        canvas { border: 1px solid #ccc; margin: 10px; }
        .icon-group { margin-bottom: 20px; }
    </style>
</head>
<body>
    <h1>PWA Icon Converter</h1>
    <p>Right-click each canvas and "Save image as..." to create PNG icons.</p>

    <div id="icons"></div>

    <script>
        const sizes = ${JSON.stringify(ICON_SIZES)};
        const iconsContainer = document.getElementById('icons');

        sizes.forEach(size => {
            const div = document.createElement('div');
            div.className = 'icon-group';

            const title = document.createElement('h3');
            title.textContent = \`icon-\${size}x\${size}.png\`;
            div.appendChild(title);

            const canvas = document.createElement('canvas');
            canvas.width = size;
            canvas.height = size;
            div.appendChild(canvas);

            const ctx = canvas.getContext('2d');

            // Background
            ctx.fillStyle = '#0C1E3C';
            ctx.fillRect(0, 0, size, size);

            // Scale factor
            const scale = size / 512;

            ctx.translate(size / 2, size / 2);
            ctx.scale(scale, scale);

            // Outer circle
            ctx.strokeStyle = '#C41E3A';
            ctx.lineWidth = 24;
            ctx.beginPath();
            ctx.arc(0, 0, 180, 0, Math.PI * 2);
            ctx.stroke();

            // Inner circle
            ctx.lineWidth = 16;
            ctx.beginPath();
            ctx.arc(0, 0, 120, 0, Math.PI * 2);
            ctx.stroke();

            // Bottom gap
            ctx.fillStyle = '#0C1E3C';
            ctx.fillRect(-20, 140, 40, 80);

            // Bottom extensions
            ctx.fillStyle = '#C41E3A';
            ctx.beginPath();
            ctx.roundRect(-140, 180, 100, 24, 12);
            ctx.fill();
            ctx.beginPath();
            ctx.roundRect(40, 180, 100, 24, 12);
            ctx.fill();

            // Watch hands
            ctx.strokeStyle = '#fff';
            ctx.lineWidth = 12;
            ctx.lineCap = 'round';
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(0, -80);
            ctx.stroke();

            ctx.lineWidth = 10;
            ctx.beginPath();
            ctx.moveTo(0, 0);
            ctx.lineTo(60, 40);
            ctx.stroke();

            // Center dot
            ctx.fillStyle = '#C41E3A';
            ctx.beginPath();
            ctx.arc(0, 0, 16, 0, Math.PI * 2);
            ctx.fill();

            ctx.fillStyle = '#fff';
            ctx.beginPath();
            ctx.arc(0, 0, 8, 0, Math.PI * 2);
            ctx.fill();

            // Reset transform for text
            ctx.setTransform(1, 0, 0, 1, 0, 0);

            // Text (for larger icons)
            if (size >= 192) {
                ctx.fillStyle = '#C41E3A';
                ctx.font = \`bold \${48 * scale}px Arial\`;
                ctx.textAlign = 'center';
                ctx.fillText('OMEGA', size / 2, size - 42 * scale);
            }

            iconsContainer.appendChild(div);
        });
    </script>
</body>
</html>
  `;

  const converterPath = path.join(iconsDir, 'icon-converter.html');
  fs.writeFileSync(converterPath, converterHTML);
  console.log('Created icon-converter.html');

  console.log('\n✅ Icon generation complete!');
  console.log(`\nTo create PNG icons:`);
  console.log(`1. Open http://45.61.58.125:7600/icons/icon-converter.html in a browser`);
  console.log(`2. Right-click each canvas and save as PNG`);
  console.log(`3. Save files as icon-72x72.png, icon-96x96.png, etc. in /public/icons/\n`);
}

generateIcons().catch(console.error);