react-native-svg-app-icon
Version:
App icon generator for React Native projects
145 lines (118 loc) • 4.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.ensureFileContents = ensureFileContents;
exports.genaratePngs = genaratePngs;
var fse = _interopRequireWildcard(require("fs-extra"));
var path = _interopRequireWildcard(require("path"));
var input = _interopRequireWildcard(require("./input"));
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
async function* genaratePngs(fileInput, outputs) {
for (const output of outputs) {
yield* genaratePng(fileInput, output);
}
}
async function* genaratePng(fileInput, output) {
if (!(output.force || (await hasChanged(fileInput, output)))) {
return;
}
const {
sharp,
baseImage,
operations = []
} = await fileInput.read();
const metadata = baseImage.metadata;
await fse.ensureDir(path.dirname(output.filePath));
const scale = fileInput.cropSize === undefined ? 1 : input.inputImageSize / fileInput.cropSize;
const targetDensity = output.outputSize / metadata.width * metadata.density * scale;
let image = sharp(baseImage.data, {
density: targetDensity
});
for (const operation of operations) {
switch (operation.type) {
case "composite":
{
let blend;
switch (operation.blend) {
case "overlay":
blend = "over";
break;
case "mask":
blend = "dest-in";
break;
default:
blend = "over";
}
image = sharp(await image.composite([{
input: await sharp(operation.file, {
density: targetDensity
}).toBuffer(),
blend: blend
}]).toBuffer());
break;
}
case "remove-alpha":
image = image.removeAlpha();
break;
}
}
const extractRegion = getExtractRegion(targetDensity, metadata, output.outputSize);
image = image.extract(extractRegion);
await image.png({
adaptiveFiltering: false,
compressionLevel: 9
}).toFile(output.filePath);
yield output.filePath;
}
function getExtractRegion(targetDensity, metadata, outputSize) {
const imageMargin = Math.floor((targetDensity / metadata.density * metadata.width - outputSize) / 2);
return {
top: imageMargin,
left: imageMargin,
width: outputSize,
height: outputSize
};
}
async function hasChanged(input, output) {
let outputStat;
try {
outputStat = await fse.stat(output.filePath);
} catch {
return true;
}
if (input.lastModified > outputStat.mtimeMs) {
return true;
} else {
return false;
}
}
async function* ensureFileContents(path, content, config) {
let stringContent;
switch (typeof content) {
case "object":
stringContent = JSON.stringify(content, undefined, 2);
break;
case "string":
stringContent = content;
break;
default:
throw Error("Invalid content");
}
const contentBuffer = Buffer.from(stringContent, "utf-8");
if (!config.force && (await hasFileContent(path, contentBuffer))) {
return;
} else {
await fse.outputFile(path, contentBuffer);
yield path;
}
}
async function hasFileContent(path, contentBuffer) {
try {
const diskFileBuffer = await fse.readFile(path);
return diskFileBuffer.equals(contentBuffer);
} catch {
return false;
}
}