173 lines
6.9 KiB
JavaScript
Executable file
173 lines
6.9 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
/**
|
|
* AeThex Logo Generator - Animated SVG
|
|
* Generates logos with animation effects
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const COLORS = {
|
|
purpleLight: '#A855F7',
|
|
purple: '#8B5CF6',
|
|
purpleDark: '#7C3AED',
|
|
cyan: '#06B6D4',
|
|
cyanLight: '#22D3EE',
|
|
white: '#FFFFFF',
|
|
};
|
|
|
|
function createAnimatedLogo() {
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
|
|
<defs>
|
|
<linearGradient id="animGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" style="stop-color:${COLORS.purpleLight}">
|
|
<animate attributeName="stop-color"
|
|
values="${COLORS.purpleLight};${COLORS.cyan};${COLORS.purpleLight}"
|
|
dur="3s" repeatCount="indefinite"/>
|
|
</stop>
|
|
<stop offset="100%" style="stop-color:${COLORS.purpleDark}">
|
|
<animate attributeName="stop-color"
|
|
values="${COLORS.purpleDark};${COLORS.purple};${COLORS.purpleDark}"
|
|
dur="3s" repeatCount="indefinite"/>
|
|
</stop>
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<!-- Animated Letter A -->
|
|
<g transform="translate(100, 100)">
|
|
<path d="M -2 -40 L -35 35 L -25 35 L -8 -10 Z" fill="url(#animGrad)">
|
|
<animate attributeName="opacity" values="1;0.8;1" dur="2s" repeatCount="indefinite"/>
|
|
</path>
|
|
<path d="M 2 -40 L 35 35 L 25 35 L 8 -10 Z" fill="url(#animGrad)">
|
|
<animate attributeName="opacity" values="1;0.8;1" dur="2s" repeatCount="indefinite" begin="0.1s"/>
|
|
</path>
|
|
|
|
<!-- Animated connection nodes -->
|
|
<circle cx="-20" cy="0" r="3" fill="${COLORS.cyan}">
|
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite"/>
|
|
<animate attributeName="opacity" values="0.6;1;0.6" dur="1.5s" repeatCount="indefinite"/>
|
|
</circle>
|
|
<circle cx="20" cy="0" r="3" fill="${COLORS.cyan}">
|
|
<animate attributeName="r" values="3;5;3" dur="1.5s" repeatCount="indefinite" begin="0.3s"/>
|
|
<animate attributeName="opacity" values="0.6;1;0.6" dur="1.5s" repeatCount="indefinite" begin="0.3s"/>
|
|
</circle>
|
|
<circle cx="0" cy="-5" r="2" fill="${COLORS.cyanLight}">
|
|
<animate attributeName="r" values="2;4;2" dur="1.5s" repeatCount="indefinite" begin="0.6s"/>
|
|
<animate attributeName="opacity" values="0.8;1;0.8" dur="1.5s" repeatCount="indefinite" begin="0.6s"/>
|
|
</circle>
|
|
|
|
<!-- Connection lines -->
|
|
<line x1="-20" y1="0" x2="20" y2="0" stroke="${COLORS.cyan}" stroke-width="2">
|
|
<animate attributeName="stroke-opacity" values="0.3;0.8;0.3" dur="2s" repeatCount="indefinite"/>
|
|
</line>
|
|
</g>
|
|
|
|
<!-- Orbit animation -->
|
|
<circle r="70" cx="100" cy="100" fill="none" stroke="${COLORS.purple}" stroke-width="1" opacity="0.3">
|
|
<animate attributeName="r" values="70;75;70" dur="3s" repeatCount="indefinite"/>
|
|
<animate attributeName="stroke-opacity" values="0.3;0.6;0.3" dur="3s" repeatCount="indefinite"/>
|
|
</circle>
|
|
</svg>`;
|
|
}
|
|
|
|
function createLoadingAnimation() {
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
|
|
<defs>
|
|
<linearGradient id="loadGrad" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
<stop offset="0%" style="stop-color:${COLORS.purple}"/>
|
|
<stop offset="100%" style="stop-color:${COLORS.cyan}"/>
|
|
</linearGradient>
|
|
</defs>
|
|
|
|
<!-- Rotating circles (loading indicator) -->
|
|
<g transform="translate(50, 50)">
|
|
<circle cx="0" cy="-25" r="4" fill="${COLORS.purple}">
|
|
<animateTransform attributeName="transform" type="rotate"
|
|
from="0 0 0" to="360 0 0" dur="1s" repeatCount="indefinite"/>
|
|
</circle>
|
|
<circle cx="0" cy="-25" r="4" fill="${COLORS.cyan}">
|
|
<animateTransform attributeName="transform" type="rotate"
|
|
from="120 0 0" to="480 0 0" dur="1s" repeatCount="indefinite"/>
|
|
</circle>
|
|
<circle cx="0" cy="-25" r="4" fill="${COLORS.purpleLight}">
|
|
<animateTransform attributeName="transform" type="rotate"
|
|
from="240 0 0" to="600 0 0" dur="1s" repeatCount="indefinite"/>
|
|
</circle>
|
|
</g>
|
|
</svg>`;
|
|
}
|
|
|
|
function createPulsingWifi() {
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
|
|
<g transform="translate(100, 120)">
|
|
<!-- WiFi/signal waves (representing cloud connectivity) -->
|
|
<path d="M -60 -40 Q 0 -80, 60 -40" fill="none" stroke="${COLORS.purple}" stroke-width="4" opacity="0.4">
|
|
<animate attributeName="opacity" values="0;0.8;0" dur="2s" repeatCount="indefinite"/>
|
|
</path>
|
|
<path d="M -40 -20 Q 0 -50, 40 -20" fill="none" stroke="${COLORS.purple}" stroke-width="4" opacity="0.4">
|
|
<animate attributeName="opacity" values="0;0.8;0" dur="2s" repeatCount="indefinite" begin="0.3s"/>
|
|
</path>
|
|
<path d="M -20 0 Q 0 -20, 20 0" fill="none" stroke="${COLORS.cyan}" stroke-width="4" opacity="0.4">
|
|
<animate attributeName="opacity" values="0;1;0" dur="2s" repeatCount="indefinite" begin="0.6s"/>
|
|
</path>
|
|
|
|
<!-- Center dot -->
|
|
<circle cx="0" cy="10" r="6" fill="${COLORS.cyan}">
|
|
<animate attributeName="r" values="4;8;4" dur="2s" repeatCount="indefinite"/>
|
|
</circle>
|
|
</g>
|
|
</svg>`;
|
|
}
|
|
|
|
function createDataFlow() {
|
|
const dots = [];
|
|
for (let i = 0; i < 5; i++) {
|
|
const delay = i * 0.5;
|
|
dots.push(`
|
|
<circle cx="20" cy="100" r="3" fill="${COLORS.cyan}">
|
|
<animate attributeName="cx" from="20" to="180" dur="2s" repeatCount="indefinite" begin="${delay}s"/>
|
|
<animate attributeName="opacity" values="0;1;1;0" dur="2s" repeatCount="indefinite" begin="${delay}s"/>
|
|
</circle>`);
|
|
}
|
|
|
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 200" width="200" height="200">
|
|
<!-- Flow lines -->
|
|
<path d="M 20 80 Q 100 60, 180 80" fill="none" stroke="${COLORS.purple}" stroke-width="2" opacity="0.3"/>
|
|
<path d="M 20 100 L 180 100" fill="none" stroke="${COLORS.purple}" stroke-width="2" opacity="0.5"/>
|
|
<path d="M 20 120 Q 100 140, 180 120" fill="none" stroke="${COLORS.purple}" stroke-width="2" opacity="0.3"/>
|
|
|
|
<!-- Animated data packets -->
|
|
${dots.join('\n ')}
|
|
|
|
<!-- Nodes -->
|
|
<circle cx="20" cy="100" r="8" fill="${COLORS.purple}"/>
|
|
<circle cx="180" cy="100" r="8" fill="${COLORS.cyan}"/>
|
|
</svg>`;
|
|
}
|
|
|
|
// Generate all animations
|
|
function main() {
|
|
const outputDir = path.join(__dirname, '..', 'assets', 'animated-logos');
|
|
|
|
if (!fs.existsSync(outputDir)) {
|
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
}
|
|
|
|
const animations = {
|
|
'logo-animated.svg': createAnimatedLogo(),
|
|
'loading-spinner.svg': createLoadingAnimation(),
|
|
'wifi-pulse.svg': createPulsingWifi(),
|
|
'data-flow.svg': createDataFlow(),
|
|
};
|
|
|
|
for (const [filename, content] of Object.entries(animations)) {
|
|
const filepath = path.join(outputDir, filename);
|
|
fs.writeFileSync(filepath, content);
|
|
console.log(`✓ Generated: ${filepath}`);
|
|
}
|
|
|
|
console.log(`\n✅ Generated ${Object.keys(animations).length} animated logos in ${outputDir}/`);
|
|
console.log('\nOpen them in a browser to see the animations!');
|
|
}
|
|
|
|
main();
|