Files
new.rybstock.ru/scripts/generate-brand-assets.js
T
2026-06-06 00:46:10 +03:00

108 lines
6.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const fs = require('fs');
const path = require('path');
const { chromium } = require('playwright');
const outDir = path.join('public', 'assets', 'images', 'brand');
fs.mkdirSync(outDir, { recursive: true });
const fullLogoSvg = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 650 220">
<defs>
<style>
.green{fill:#173d2c}.green2{fill:#27634a}.red{fill:#c43d31}.paper{fill:#fffefa}.shadow-green{fill:#173d2c;opacity:.13}
.word{font-family:Arial Black, Arial, Helvetica, sans-serif;font-size:104px;font-weight:950;letter-spacing:-7px}
.tag{font-family:Arial, Helvetica, sans-serif;font-size:25px;font-weight:900;letter-spacing:-.25px;fill:#173d2c}
.rule-red{fill:none;stroke:#c43d31;stroke-width:7;stroke-linecap:round}.rule-green{fill:none;stroke:#173d2c;stroke-width:5;stroke-linecap:round}.rule-shadow{fill:none;stroke:#173d2c;stroke-width:7;stroke-linecap:round;opacity:.12}.stroke{fill:none;stroke-linecap:round;stroke-linejoin:round}
</style>
</defs>
<g transform="translate(8 26)">
<text class="word shadow-green" x="9" y="91">Рыб</text><text class="word shadow-green" x="199" y="91">сток</text>
<text class="word green" x="0" y="80">Рыб</text><text class="word red" x="190" y="80">сток</text>
<path class="shadow-green" d="M157 28 C183 30 203 49 203 74 C203 99 183 118 157 120 L157 100 C172 98 183 88 183 74 C183 60 172 50 157 48Z"/>
<path class="red" d="M164 22 C190 24 210 43 210 68 C210 93 190 112 164 114 L164 94 C179 92 190 82 190 68 C190 54 179 44 164 42Z"/>
<path class="paper" d="M164 39 C179 41 190 53 190 68 C190 83 179 95 164 97 L164 82 C171 80 176 75 176 68 C176 61 171 56 164 54Z"/>
<path class="stroke green2" stroke-width="6" d="M141 56 H168"/><path class="stroke red" stroke-width="5" d="M151 64 H174"/>
<path class="stroke green2" stroke-width="6" d="M141 84 H168"/><path class="stroke red" stroke-width="5" d="M151 92 H174"/>
<path class="rule-shadow" d="M8 119 H432"/><path class="rule-red" d="M4 112 H176"/><path class="rule-green" d="M178 112 H432"/>
<text class="tag" x="4" y="162">Качество со склада. <tspan class="red">Стоковые цены.</tspan></text>
</g>
</svg>`;
const iconMonogramSvg = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#fffefa"/>
<path d="M76 362 H250" fill="none" stroke="#c43d31" stroke-width="26" stroke-linecap="round"/>
<path d="M252 362 H436" fill="none" stroke="#173d2c" stroke-width="20" stroke-linecap="round"/>
<text x="38" y="284" font-family="Arial Black, Arial, Helvetica, sans-serif" font-size="214" font-weight="950" letter-spacing="-18" fill="#173d2c">Ры</text>
<text x="214" y="284" font-family="Arial Black, Arial, Helvetica, sans-serif" font-size="214" font-weight="950" letter-spacing="-18" fill="#c43d31">с</text>
<path d="M247 105 C318 111 374 166 374 256 C374 346 318 401 247 407 L247 352 C290 346 320 307 320 256 C320 205 290 166 247 160Z" fill="#c43d31"/>
<path d="M248 165 C284 174 306 210 306 256 C306 302 284 338 248 347 L248 300 C266 293 278 277 278 256 C278 235 266 219 248 212Z" fill="#fffefa"/>
<path d="M202 225 H267" fill="none" stroke="#27634a" stroke-width="18" stroke-linecap="round"/>
<path d="M225 246 H282" fill="none" stroke="#c43d31" stroke-width="14" stroke-linecap="round"/>
<path d="M202 287 H267" fill="none" stroke="#27634a" stroke-width="18" stroke-linecap="round"/>
<path d="M225 308 H282" fill="none" stroke="#c43d31" stroke-width="14" stroke-linecap="round"/>
</svg>`;
const iconFishSvg = `
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<rect width="512" height="512" rx="112" fill="#173d2c"/>
<path d="M120 176 C222 181 292 248 292 256 C292 264 222 331 120 336 C96 315 76 286 68 256 C76 226 96 197 120 176Z" fill="#fffefa"/>
<circle cx="145" cy="256" r="17" fill="#173d2c"/>
<path d="M292 256 L390 190 L390 322Z" fill="#fffefa"/>
<path d="M90 118 H344" fill="none" stroke="#c43d31" stroke-width="26" stroke-linecap="round"/>
<path d="M90 394 H344" fill="none" stroke="#c43d31" stroke-width="26" stroke-linecap="round"/>
<path d="M146 440 H295" fill="none" stroke="#27634a" stroke-width="20" stroke-linecap="round"/>
</svg>`;
async function pngFromSvg(page, svg, file, width, height = null) {
const targetHeight = height ?? Math.round((width / 650) * 220);
await page.setViewportSize({ width, height: targetHeight });
await page.setContent(`
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<style>
html, body { margin: 0; width: ${width}px; height: ${targetHeight}px; background: transparent; overflow: hidden; }
svg { display: block; width: ${width}px; height: ${targetHeight}px; }
</style>
</head>
<body>${svg}</body>
</html>
`);
await page.locator('svg').screenshot({ path: file, omitBackground: true });
}
async function main() {
fs.writeFileSync(path.join(outDir, 'logo-rybstock-source.svg'), fullLogoSvg.trim(), 'utf8');
fs.writeFileSync(path.join(outDir, 'favicon-rybstock-monogram-source.svg'), iconMonogramSvg.trim(), 'utf8');
fs.writeFileSync(path.join(outDir, 'favicon-rybstock-fish-source.svg'), iconFishSvg.trim(), 'utf8');
const edgePath = 'C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe';
const browser = await chromium.launch(fs.existsSync(edgePath) ? { executablePath: edgePath } : {});
const page = await browser.newPage({ deviceScaleFactor: 1 });
try {
for (const width of [320, 640, 1280, 1920]) {
await pngFromSvg(page, fullLogoSvg, path.join(outDir, `logo-rybstock-${width}.png`), width);
}
for (const width of [16, 32, 48, 64, 180, 192, 512]) {
await pngFromSvg(page, iconMonogramSvg, path.join(outDir, `favicon-rybstock-monogram-${width}.png`), width, width);
await pngFromSvg(page, iconFishSvg, path.join(outDir, `favicon-rybstock-fish-${width}.png`), width, width);
}
await pngFromSvg(page, iconMonogramSvg, path.join('public', 'favicon-16x16.png'), 16, 16);
await pngFromSvg(page, iconMonogramSvg, path.join('public', 'favicon-32x32.png'), 32, 32);
await pngFromSvg(page, iconMonogramSvg, path.join('public', 'apple-touch-icon.png'), 180, 180);
} finally {
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exit(1);
});