UNPKG

iso-3166-1-flags-sprite-generator

Version:
114 lines (113 loc) 7.72 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const glob = require("glob"); const path = require("path"); const fs = require("fs"); const chalk = require("chalk"); const utils_1 = require("@qntm-code/utils"); const sharp = require("sharp"); const Spritesmith = require("spritesmith"); const css_properties_to_string_1 = require("./css-properties-to-string"); const TEMP_DIRECTORY = path.join(__dirname, '..', `tmp`).replace(path.join(__dirname, '..', '..'), ''); function createFlagSprite(spriteDestination, cssDestination, options) { return __awaiter(this, void 0, void 0, function* () { const mergedOptions = Object.assign({ center: true, classPrefix: 'flag', cssFileName: 'flags', demo: true, demoDestination: 'flags-demo', dimensionsSuffix: 'dims', width: 60, spriteFileName: 'flag-sprite' }, options); if (!mergedOptions.silent) { console.log(chalk.blue('Generating flag sprite')); } fs.mkdirSync(TEMP_DIRECTORY.substring(1), { recursive: true }); const originalPNGPaths = glob.sync(`${path.join(__dirname, '..')}/png/*.png`); const pngPaths = []; const originalWidths = (yield Promise.all(originalPNGPaths.map((originalPath) => __awaiter(this, void 0, void 0, function* () { return (yield sharp(originalPath).metadata()).width; })))).filter(item => !(0, utils_1.isNullOrUndefined)(item)); const widestOriginal = Math.max(...originalWidths); const maxIconWidth = Math.min(...originalWidths); mergedOptions.width = Math.max(Math.min(mergedOptions.width, maxIconWidth), 1); const flagHeight = Math.round((mergedOptions.width / widestOriginal) * 240); const results = yield Promise.all(originalPNGPaths.map((originalPath) => __awaiter(this, void 0, void 0, function* () { const pngPath = `${TEMP_DIRECTORY.substring(1)}/${path.basename(originalPath, '.png')}.png`; pngPaths.push(pngPath); const png = sharp(originalPath).resize(undefined, flagHeight); yield png.toFile(pngPath); return sharp(pngPath).metadata(); }))); const widths = results.map(({ width }) => width || 0); const maxWidth = Math.max(...widths); const padding = Math.ceil((maxWidth - Math.min(...widths)) / 2); // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call Spritesmith.run({ src: pngPaths, padding }, (_, { coordinates, properties, image, }) => { const spriteFilename = `${mergedOptions.spriteFileName}.png`; const spriteFilePath = `${spriteDestination}/${spriteFilename}`; const spriteUrl = mergedOptions.spriteUrl ? `${mergedOptions.spriteUrl}/${spriteFilename}` : spriteFilePath; const demoSpriteName = 'sprite.png'; const cssFilename = `${mergedOptions.cssFileName}.css`; const cssFilePath = `${cssDestination}/${cssFilename}`; const demoCssName = `flags.css`; let css = createCssStart(properties, spriteUrl, maxWidth, flagHeight, mergedOptions); let demoCSS = createCssStart(properties, demoSpriteName, maxWidth, flagHeight, mergedOptions); let html = `<!DOCTYPE html><html><head><title>Flags Sprite</title><link rel="stylesheet" type="text/css" href="${demoCssName}"><style>body { font-family: sans-serif; text-align: center; margin 5px; } body > div { display: inline-block; margin: 5px; } .${mergedOptions.classPrefix}{ width: ${maxWidth}px; height: ${flagHeight}px; }</style></head><body><h1>Created by iso-3166-1-flags-sprite-generator</h1>`; Object.entries(coordinates).forEach(([pngPath, { x, y, width, height }]) => { const code = path.basename(pngPath, '.png'); const className = `${mergedOptions.classPrefix}-${mergedOptions.lowecaseAlpha2 ? code.toLowerCase() : code}`; const cssProperties = { ['background-position']: `${((x - (mergedOptions.center ? (maxWidth - width) / 2 : 0)) / (properties.width - maxWidth)) * 100}% ${(y / (properties.height - flagHeight)) * 100}%`, }; const flagClass = `\n\n.${className} {${(0, css_properties_to_string_1.cssPropertiesToString)(cssProperties)}\n}`; css += flagClass; demoCSS += flagClass; if (mergedOptions.dimensionsClasses) { const flagDimensionsClass = `\n\n.${className}-${mergedOptions.dimensionsSuffix} {${(0, css_properties_to_string_1.cssPropertiesToString)({ width: `${width}px`, height: `${height}px`, })}\n}`; css += flagDimensionsClass; demoCSS += flagDimensionsClass; } html += `<div><div class="${mergedOptions.classPrefix} ${className}"></div><p>${className}</p></div>`; }); html += `</body></html>`; fs.mkdirSync(spriteDestination, { recursive: true }); fs.mkdirSync(cssDestination, { recursive: true }); fs.createWriteStream(spriteFilePath).write(image); fs.writeFileSync(cssFilePath, css, 'utf-8'); const demoFilePath = `${mergedOptions.demoDestination}/index.html`; if (mergedOptions.demo) { fs.mkdirSync(mergedOptions.demoDestination, { recursive: true }); fs.writeFileSync(demoFilePath, html, 'utf-8'); fs.createWriteStream(`${mergedOptions.demoDestination}/${demoSpriteName}`).write(image); fs.writeFileSync(`${mergedOptions.demoDestination}/${demoCssName}`, demoCSS, 'utf-8'); } if (!mergedOptions.silent) { console.log(chalk.greenBright('Successfully generated flags sprite')); console.log(chalk.green(`Sprite: ${spriteFilePath}`)); console.log(chalk.green(`CSS: ${cssFilePath}`)); if (mergedOptions.demo) { console.log(chalk.green(`Demo: ${demoFilePath}`)); } } }); }); } exports.default = createFlagSprite; function createCssStart(properties, spriteUrl, maxWidth, flagHeight, mergedOptions) { const baseCss = { display: `inline-block`, background: ` url('${spriteUrl}') no-repeat`, ['background-size']: `${(properties.width / maxWidth) * 100}% ${(properties.height / flagHeight) * 100}%`, ['vertical-align']: `middle`, overflow: `hidden`, }; const dimensionsCss = { width: `${mergedOptions.width}px`, height: `${flagHeight}px`, }; return `/**\n * GENERATED BY iso-3166-1-flags-sprite-generator\n */\n\n.${mergedOptions.classPrefix} {${(0, css_properties_to_string_1.cssPropertiesToString)(baseCss)}\n}\n\n.${mergedOptions.classPrefix}-${mergedOptions.dimensionsSuffix} {${(0, css_properties_to_string_1.cssPropertiesToString)(dimensionsCss)}\n}`; }