@nanggo/social-preview
Version:
Generate beautiful social media preview images from any URL
79 lines (76 loc) • 3.51 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateDefaultOverlay = generateDefaultOverlay;
const utils_1 = require("../utils");
const validators_1 = require("../utils/validators");
const sharp_cache_1 = require("../utils/sharp-cache");
const fonts_1 = require("../constants/fonts");
/**
* Default overlay generator for templates that don't provide a custom overlayGenerator.
* Uses conservative typography + wrapping so custom templates still render cleanly.
*/
async function generateDefaultOverlay(metadata, template, width, height, options) {
const padding = template.layout.padding || 60;
const textColor = (0, validators_1.validateColor)(options.colors?.text || '#ffffff');
// Typography settings
const titleFontSize = template.typography.title.fontSize;
const titleLineHeight = template.typography.title.lineHeight || 1.2;
const descFontSize = template.typography.description?.fontSize || 24;
const descLineHeight = template.typography.description?.lineHeight || 1.4;
// Text wrapping similar to specific template generators
const maxTextWidth = width - padding * 2;
const titleLines = (0, utils_1.wrapText)(metadata.title, maxTextWidth, titleFontSize, template.typography.title.maxLines || 2, 'default');
const descLines = metadata.description
? (0, utils_1.wrapText)(metadata.description, maxTextWidth, descFontSize, template.typography.description?.maxLines || 2, 'default')
: [];
// Calculate positions for proper vertical centering
const titleHeight = titleLines.length * titleFontSize * titleLineHeight;
const descHeight = descLines.length > 0 ? descLines.length * descFontSize * descLineHeight : 0;
const gap = descLines.length > 0 ? 20 : 0;
const totalContentHeight = titleHeight + gap + descHeight;
const contentStartY = (height - totalContentHeight) / 2;
const titleStartY = contentStartY + titleFontSize;
const descStartY = titleStartY + titleHeight + gap;
const overlaySvg = `
<svg width="${width}" height="${height}" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
.title {
font-family: ${fonts_1.SYSTEM_FONT_STACK};
font-size: ${titleFontSize}px;
font-weight: ${template.typography.title.fontWeight || '700'};
fill: ${textColor};
}
.description {
font-family: ${fonts_1.SYSTEM_FONT_STACK};
font-size: ${descFontSize}px;
font-weight: ${template.typography.description?.fontWeight || '400'};
fill: ${textColor};
opacity: 0.9;
}
</style>
</defs>
<!-- Title with proper wrapping -->
${titleLines
.map((line, index) => `
<text x="${padding}" y="${titleStartY + index * titleFontSize * titleLineHeight}" class="title">
${(0, utils_1.escapeXml)(line)}
</text>
`)
.join('')}
<!-- Description with proper wrapping -->
${descLines.length > 0
? descLines
.map((line, index) => `
<text x="${padding}" y="${descStartY + index * descFontSize * descLineHeight}" class="description">
${(0, utils_1.escapeXml)(line)}
</text>
`)
.join('')
: ''}
</svg>
`;
// Use cached SVG creation for better performance
const cachedSVG = await (0, sharp_cache_1.createCachedSVG)(overlaySvg);
return cachedSVG.toBuffer();
}