iso-3166-1-flags-sprite-generator
Version:
iso-3166-1 country flags css sprite generator
114 lines (113 loc) • 7.72 kB
JavaScript
;
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}`;
}