UNPKG

penframe

Version:

A lightweight DSL-based wireframe and UI structure visualization tool.

171 lines (149 loc) 4.33 kB
const puppeteer = require('puppeteer'); const astToSvg = require('./astToSvg'); /** * Convert SVG text to PNG using Puppeteer * @param {string} svgText - SVG content as string * @param {string} outputPath - Output PNG file path * @param {Object} options - Screenshot options * @param {number} options.width - Viewport width (optional) * @param {number} options.height - Viewport height (optional) * @param {number} options.deviceScaleFactor - Device scale factor for high DPI (default: 2) * @param {string} options.background - Background color (default: 'white') */ async function renderPNGFromSVG(svgText, outputPath, options = {}) { const { width, height, deviceScaleFactor = 2, // Higher DPI for better quality background = 'white' } = options; const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] }); try { const page = await browser.newPage(); // Set viewport if dimensions specified if (width && height) { await page.setViewport({ width, height, deviceScaleFactor }); } // Create HTML content with SVG const htmlContent = ` <!DOCTYPE html> <html> <head> <style> body { margin: 0; padding: 20px; background-color: ${background}; display: flex; justify-content: center; align-items: flex-start; } svg { max-width: 100%; height: auto; } </style> </head> <body>${svgText}</body> </html> `; await page.setContent(htmlContent, { waitUntil: 'networkidle0' }); // Find SVG element and take screenshot const svgElement = await page.$('svg'); if (!svgElement) { throw new Error('SVG element not found in the rendered content'); } await svgElement.screenshot({ path: outputPath, omitBackground: background === 'transparent' }); } finally { await browser.close(); } } /** * Convert AST to PNG using Puppeteer * @param {Object} ast - The AST object * @param {string} outputPath - Output PNG file path * @param {Object} options - Conversion options */ async function astToPngFile(ast, outputPath, options = {}) { // Convert AST to SVG const svgContent = astToSvg(ast); // Convert SVG to PNG using Puppeteer await renderPNGFromSVG(svgContent, outputPath, options); } /** * Convert AST to PNG buffer using Puppeteer * @param {Object} ast - The AST object * @param {Object} options - Conversion options * @returns {Promise<Buffer>} PNG buffer */ async function astToPng(ast, options = {}) { const { width, height, deviceScaleFactor = 2, background = 'white' } = options; const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] }); try { const page = await browser.newPage(); if (width && height) { await page.setViewport({ width, height, deviceScaleFactor }); } const svgContent = astToSvg(ast); const htmlContent = ` <!DOCTYPE html> <html> <head> <style> body { margin: 0; padding: 20px; background-color: ${background}; display: flex; justify-content: center; align-items: flex-start; } svg { max-width: 100%; height: auto; } </style> </head> <body>${svgContent}</body> </html> `; await page.setContent(htmlContent, { waitUntil: 'networkidle0' }); const svgElement = await page.$('svg'); if (!svgElement) { throw new Error('SVG element not found in the rendered content'); } const buffer = await svgElement.screenshot({ omitBackground: background === 'transparent' }); return buffer; } finally { await browser.close(); } } module.exports = { renderPNGFromSVG, astToPng, astToPngFile };