51 lines
1.7 KiB
JavaScript
51 lines
1.7 KiB
JavaScript
/**
|
|
* 画个标 · 海报导出:SVG / PNG(按画布规格导出)
|
|
*/
|
|
const HGB_PosterExporter = (function () {
|
|
'use strict';
|
|
|
|
function buildSvg(spec, elements) {
|
|
return HGB_PosterRenderer.render(spec, elements);
|
|
}
|
|
|
|
function download(name, blob) {
|
|
const a = document.createElement('a');
|
|
a.href = URL.createObjectURL(blob);
|
|
a.download = name;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
setTimeout(() => { URL.revokeObjectURL(a.href); a.remove(); }, 0);
|
|
}
|
|
|
|
function exportSvg(spec, elements, base) {
|
|
const svg = buildSvg(spec, elements);
|
|
download((base || '海报') + '.svg', new Blob([svg], { type: 'image/svg+xml' }));
|
|
}
|
|
|
|
/** 渲染 SVG 到位图并下载(scale 控制放大倍数,默认 1) */
|
|
function svgToCanvas(spec, elements, scale) {
|
|
return new Promise((resolve, reject) => {
|
|
const svg = buildSvg(spec, elements);
|
|
const img = new Image();
|
|
img.onload = () => {
|
|
const w = Math.round(spec.w * scale), h = Math.round(spec.h * scale);
|
|
const c = document.createElement('canvas');
|
|
c.width = w; c.height = h;
|
|
const ctx = c.getContext('2d');
|
|
ctx.drawImage(img, 0, 0, w, h);
|
|
resolve(c);
|
|
};
|
|
img.onerror = () => reject(new Error('SVG 渲染失败'));
|
|
img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg);
|
|
});
|
|
}
|
|
|
|
async function exportPng(spec, elements, base, scale) {
|
|
const c = await svgToCanvas(spec, elements, scale || 1);
|
|
const blob = await new Promise(res => c.toBlob(res, 'image/png'));
|
|
download((base || '海报') + '.png', blob);
|
|
}
|
|
|
|
return { buildSvg, exportSvg, exportPng, svgToCanvas };
|
|
})();
|