@lemonppt/renderer 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser-export-driver.d.ts +28 -0
- package/dist/browser-export-driver.d.ts.map +1 -0
- package/dist/browser-export-driver.js +115 -0
- package/dist/browser-export-driver.js.map +1 -0
- package/dist/browser-export.d.ts +66 -0
- package/dist/browser-export.d.ts.map +1 -0
- package/dist/browser-export.js +176 -0
- package/dist/browser-export.js.map +1 -0
- package/dist/client/browser-export.js +1 -0
- package/dist/client/client-render.js +21 -21
- package/dist/client/theme-echarts.js +27 -27
- package/dist/export-pdf.d.ts +2 -2
- package/dist/export-pdf.d.ts.map +1 -1
- package/dist/export-pdf.js +8 -5
- package/dist/export-pdf.js.map +1 -1
- package/dist/export-pptx-screenshot.d.ts +40 -0
- package/dist/export-pptx-screenshot.d.ts.map +1 -0
- package/dist/export-pptx-screenshot.js +76 -0
- package/dist/export-pptx-screenshot.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/normalize-goal.d.ts +6 -0
- package/dist/normalize-goal.d.ts.map +1 -0
- package/dist/normalize-goal.js +12 -0
- package/dist/normalize-goal.js.map +1 -0
- package/dist/preview-server.d.ts +9 -0
- package/dist/preview-server.d.ts.map +1 -0
- package/dist/preview-server.js +81 -0
- package/dist/preview-server.js.map +1 -0
- package/dist/render-editor-data.js +2 -2
- package/dist/render-editor-data.js.map +1 -1
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +20 -4
- package/dist/render.js.map +1 -1
- package/package.json +8 -5
- package/dist/export-pptx.d.ts +0 -1167
- package/dist/export-pptx.d.ts.map +0 -1
- package/dist/export-pptx.js +0 -3007
- package/dist/export-pptx.js.map +0 -1
- package/dist/theme01-pptx.d.ts +0 -12
- package/dist/theme01-pptx.d.ts.map +0 -1
- package/dist/theme01-pptx.js +0 -2957
- package/dist/theme01-pptx.js.map +0 -1
- package/dist/theme02-pptx.d.ts +0 -5
- package/dist/theme02-pptx.d.ts.map +0 -1
- package/dist/theme02-pptx.js +0 -1063
- package/dist/theme02-pptx.js.map +0 -1
- package/dist/theme03-pptx.d.ts +0 -5
- package/dist/theme03-pptx.d.ts.map +0 -1
- package/dist/theme03-pptx.js +0 -3279
- package/dist/theme03-pptx.js.map +0 -1
- package/dist/theme04-pptx.d.ts +0 -6
- package/dist/theme04-pptx.d.ts.map +0 -1
- package/dist/theme04-pptx.js +0 -5496
- package/dist/theme04-pptx.js.map +0 -1
- package/dist/theme05-pptx.d.ts +0 -5
- package/dist/theme05-pptx.d.ts.map +0 -1
- package/dist/theme05-pptx.js +0 -3152
- package/dist/theme05-pptx.js.map +0 -1
- package/dist/theme06-pptx.d.ts +0 -124
- package/dist/theme06-pptx.d.ts.map +0 -1
- package/dist/theme06-pptx.js +0 -8154
- package/dist/theme06-pptx.js.map +0 -1
- package/dist/theme07-pptx.d.ts +0 -49
- package/dist/theme07-pptx.d.ts.map +0 -1
- package/dist/theme07-pptx.js +0 -2579
- package/dist/theme07-pptx.js.map +0 -1
- package/dist/theme08-pptx.d.ts +0 -19
- package/dist/theme08-pptx.d.ts.map +0 -1
- package/dist/theme08-pptx.js +0 -1411
- package/dist/theme08-pptx.js.map +0 -1
- package/dist/theme09-pptx.d.ts +0 -18
- package/dist/theme09-pptx.d.ts.map +0 -1
- package/dist/theme09-pptx.js +0 -1513
- package/dist/theme09-pptx.js.map +0 -1
- package/dist/theme10-pptx.d.ts +0 -18
- package/dist/theme10-pptx.d.ts.map +0 -1
- package/dist/theme10-pptx.js +0 -2889
- package/dist/theme10-pptx.js.map +0 -1
- package/dist/theme11-pptx.d.ts +0 -17
- package/dist/theme11-pptx.d.ts.map +0 -1
- package/dist/theme11-pptx.js +0 -908
- package/dist/theme11-pptx.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 浏览器端导出驱动页生成器。
|
|
3
|
+
*
|
|
4
|
+
* 当服务端无法启动 Chromium 时,渲染一个包含 deck 静态 markup 的 HTML 页面,
|
|
5
|
+
* 由用户浏览器完成截图 / PPTX 组装 / PDF 图片上传,服务端只做文件 I/O。
|
|
6
|
+
*/
|
|
7
|
+
import type { DeckGoal } from '@lemonppt/core';
|
|
8
|
+
export interface BrowserExportDriverOptions {
|
|
9
|
+
/** deck 数据 */
|
|
10
|
+
goal: DeckGoal;
|
|
11
|
+
/** 导出模式:pptx 在浏览器内组装后 POST base64;pdf 截图后 POST base64 数组 */
|
|
12
|
+
mode: 'pdf' | 'pptx';
|
|
13
|
+
/** 接收导出结果的回调 URL */
|
|
14
|
+
callbackUrl: string;
|
|
15
|
+
/** 页面宽度,默认 1280 */
|
|
16
|
+
width?: number;
|
|
17
|
+
/** 页面高度,默认 720 */
|
|
18
|
+
height?: number;
|
|
19
|
+
/** 像素比,默认 2 */
|
|
20
|
+
pixelRatio?: number;
|
|
21
|
+
/** 静态资源基础路径,默认 ./assets */
|
|
22
|
+
assetBaseUrl?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 生成浏览器端导出驱动页 HTML。
|
|
26
|
+
*/
|
|
27
|
+
export declare function renderBrowserExportDriver(options: BrowserExportDriverOptions): string;
|
|
28
|
+
//# sourceMappingURL=browser-export-driver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-export-driver.d.ts","sourceRoot":"","sources":["../src/browser-export-driver.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,MAAM,WAAW,0BAA0B;IACzC,cAAc;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,4DAA4D;IAC5D,IAAI,EAAE,KAAK,GAAG,MAAM,CAAC;IACrB,oBAAoB;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA2FD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CAwBrF"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// lemonPPT - AI-powered presentation generation
|
|
2
|
+
// Copyright (c) 2026 lemonforme
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
import { renderDeck } from './render.js';
|
|
5
|
+
function buildDriverScript(options) {
|
|
6
|
+
const { mode, callbackUrl, width = 1280, height = 720, pixelRatio = 2 } = options;
|
|
7
|
+
const title = options.goal.title || 'Presentation';
|
|
8
|
+
const hasCallback = Boolean(callbackUrl);
|
|
9
|
+
return `<script>
|
|
10
|
+
(function() {
|
|
11
|
+
async function postJSON(url, payload) {
|
|
12
|
+
const res = await fetch(url, {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: { 'Content-Type': 'application/json' },
|
|
15
|
+
body: JSON.stringify(payload),
|
|
16
|
+
});
|
|
17
|
+
if (!res.ok) {
|
|
18
|
+
const text = await res.text();
|
|
19
|
+
throw new Error('Callback failed: ' + text);
|
|
20
|
+
}
|
|
21
|
+
return res.json();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function downloadBase64(filename, mimeType, base64) {
|
|
25
|
+
const binary = atob(base64);
|
|
26
|
+
const bytes = new Uint8Array(binary.length);
|
|
27
|
+
for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
|
|
28
|
+
const blob = new Blob([bytes], { type: mimeType });
|
|
29
|
+
const url = URL.createObjectURL(blob);
|
|
30
|
+
const a = document.createElement('a');
|
|
31
|
+
a.href = url;
|
|
32
|
+
a.download = filename;
|
|
33
|
+
document.body.appendChild(a);
|
|
34
|
+
a.click();
|
|
35
|
+
document.body.removeChild(a);
|
|
36
|
+
URL.revokeObjectURL(url);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function run() {
|
|
40
|
+
const api = window.__lemonPPT_browserExport;
|
|
41
|
+
if (!api) {
|
|
42
|
+
document.body.innerHTML = '<div style="padding:40px;color:red">浏览器端导出脚本未加载</div>';
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
document.body.innerHTML += '<div id="lp-export-status" style="position:fixed;top:16px;left:16px;z-index:99999;background:#111;color:#fff;padding:12px 16px;border-radius:8px;font-family:system-ui,sans-serif">正在导出 ${mode.toUpperCase()},请稍候...</div>';
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const exportOptions = { width: ${width}, height: ${height}, pixelRatio: ${pixelRatio}, title: ${JSON.stringify(title)}, author: 'lemonPPT' };
|
|
50
|
+
let result;
|
|
51
|
+
if (${mode === 'pptx' ? 'true' : 'false'}) {
|
|
52
|
+
result = await api.exportDeckToPptxInBrowser(exportOptions);
|
|
53
|
+
} else {
|
|
54
|
+
result = await api.exportDeckToPdfInBrowser(exportOptions);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const status = document.getElementById('lp-export-status');
|
|
58
|
+
|
|
59
|
+
if (${hasCallback ? 'true' : 'false'}) {
|
|
60
|
+
if (status) status.textContent = '正在上传结果到服务端...';
|
|
61
|
+
const callbackResult = await postJSON(${JSON.stringify(callbackUrl)}, {
|
|
62
|
+
mode: ${JSON.stringify(mode)},
|
|
63
|
+
filename: result.filename,
|
|
64
|
+
mimeType: result.mimeType,
|
|
65
|
+
base64: result.base64,
|
|
66
|
+
});
|
|
67
|
+
if (callbackResult && callbackResult.downloadUrl) {
|
|
68
|
+
window.location.href = callbackResult.downloadUrl;
|
|
69
|
+
} else {
|
|
70
|
+
document.body.innerHTML = '<div style="padding:40px;color:green">导出完成,但服务端未返回下载地址</div>';
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
if (status) status.textContent = '正在保存到本地...';
|
|
74
|
+
downloadBase64(result.filename, result.mimeType, result.base64);
|
|
75
|
+
document.body.innerHTML = '<div style="padding:40px;color:green">导出完成,文件已开始下载</div>';
|
|
76
|
+
}
|
|
77
|
+
} catch (err) {
|
|
78
|
+
const message = err && err.message ? err.message : String(err);
|
|
79
|
+
document.body.innerHTML = '<div style="padding:40px;color:red">导出失败:' + escapeHtml(message) + '</div>';
|
|
80
|
+
console.error(err);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (document.readyState === 'complete' || document.readyState === 'interactive') {
|
|
85
|
+
setTimeout(run, 100);
|
|
86
|
+
} else {
|
|
87
|
+
document.addEventListener('DOMContentLoaded', run);
|
|
88
|
+
}
|
|
89
|
+
})();
|
|
90
|
+
</script>`;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* 生成浏览器端导出驱动页 HTML。
|
|
94
|
+
*/
|
|
95
|
+
export function renderBrowserExportDriver(options) {
|
|
96
|
+
const { goal, width, height } = options;
|
|
97
|
+
const { html } = renderDeck(goal, { width, height });
|
|
98
|
+
const assetBase = (options.assetBaseUrl || './assets').replace(/\/$/, '');
|
|
99
|
+
// 将 deck 内部相对资源路径替换为指定的静态资源基础路径,确保在独立路由下资源可加载
|
|
100
|
+
const htmlWithBase = html.replace(/\.\/assets\//g, `${assetBase}/`);
|
|
101
|
+
const vendorScripts = [
|
|
102
|
+
`<script src="${assetBase}/vendor/html-to-image.js"></script>`,
|
|
103
|
+
`<script src="${assetBase}/vendor/pdf-lib.js"></script>`,
|
|
104
|
+
`<script src="${assetBase}/vendor/pptxgenjs.js"></script>`,
|
|
105
|
+
`<script src="${assetBase}/browser-export.js"></script>`,
|
|
106
|
+
].join('\n');
|
|
107
|
+
const driverScript = buildDriverScript(options);
|
|
108
|
+
// 在 </body> 前注入 vendor 脚本和驱动脚本
|
|
109
|
+
if (htmlWithBase.includes('</body>')) {
|
|
110
|
+
return htmlWithBase.replace('</body>', `${vendorScripts}\n${driverScript}\n</body>`);
|
|
111
|
+
}
|
|
112
|
+
// 兜底:追加到末尾
|
|
113
|
+
return `${htmlWithBase}\n${vendorScripts}\n${driverScript}`;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=browser-export-driver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-export-driver.js","sourceRoot":"","sources":["../src/browser-export-driver.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,gCAAgC;AAChC,6CAA6C;AAU7C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAmBzC,SAAS,iBAAiB,CAAC,OAAmC;IAC5D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,GAAG,GAAG,EAAE,UAAU,GAAG,CAAC,EAAE,GAAG,OAAO,CAAC;IAClF,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,cAAc,CAAC;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAEzC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0NAqCiN,IAAI,CAAC,WAAW,EAAE;;;uCAGrM,KAAK,aAAa,MAAM,iBAAiB,UAAU,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;;YAE/G,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;;;;;;;YAQlC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO;;gDAEM,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;kBACzD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4B5B,CAAC;AACX,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAmC;IAC3E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IACxC,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,UAAU,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAE1E,8CAA8C;IAC9C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,SAAS,GAAG,CAAC,CAAC;IAEpE,MAAM,aAAa,GAAG;QACpB,gBAAgB,SAAS,qCAAqC;QAC9D,gBAAgB,SAAS,+BAA+B;QACxD,gBAAgB,SAAS,iCAAiC;QAC1D,gBAAgB,SAAS,+BAA+B;KACzD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAEhD,+BAA+B;IAC/B,IAAI,YAAY,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QACrC,OAAO,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,aAAa,KAAK,YAAY,WAAW,CAAC,CAAC;IACvF,CAAC;IAED,WAAW;IACX,OAAO,GAAG,YAAY,KAAK,aAAa,KAAK,YAAY,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 浏览器端导出兜底脚本。
|
|
3
|
+
*
|
|
4
|
+
* 运行环境:用户浏览器。
|
|
5
|
+
* 依赖全局变量:
|
|
6
|
+
* - htmlToImage (html-to-image)
|
|
7
|
+
* - PDFLib (pdf-lib)
|
|
8
|
+
* - PptxGenJS (pptxgenjs)
|
|
9
|
+
*
|
|
10
|
+
* 提供能力:
|
|
11
|
+
* - 将 .lp-slide-wrapper 逐页截图为 PNG dataURL
|
|
12
|
+
* - 用 pdf-lib 将图片合成为 PDF
|
|
13
|
+
* - 用 pptxgenjs 将图片合成为 PPTX(每页一张全屏图)
|
|
14
|
+
*/
|
|
15
|
+
export interface BrowserExportOptions {
|
|
16
|
+
width?: number;
|
|
17
|
+
height?: number;
|
|
18
|
+
pixelRatio?: number;
|
|
19
|
+
title?: string;
|
|
20
|
+
subject?: string;
|
|
21
|
+
author?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface BrowserExportResult {
|
|
24
|
+
/** MIME 类型 */
|
|
25
|
+
mimeType: string;
|
|
26
|
+
/** Base64 编码的文件内容 */
|
|
27
|
+
base64: string;
|
|
28
|
+
/** 文件名 */
|
|
29
|
+
filename: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* 将单页幻灯片截图为 PNG dataURL。
|
|
33
|
+
*/
|
|
34
|
+
export declare function captureSlideAsImage(slide: HTMLElement, options?: BrowserExportOptions): Promise<string>;
|
|
35
|
+
/**
|
|
36
|
+
* 将所有幻灯片逐页截图为 PNG dataURL 数组。
|
|
37
|
+
*/
|
|
38
|
+
export declare function captureSlidesAsImages(options?: BrowserExportOptions): Promise<string[]>;
|
|
39
|
+
/**
|
|
40
|
+
* 将截图数组组装为 PDF。
|
|
41
|
+
*/
|
|
42
|
+
export declare function assemblePdfFromImages(images: string[], options?: BrowserExportOptions): Promise<BrowserExportResult>;
|
|
43
|
+
/**
|
|
44
|
+
* 将截图数组组装为 PPTX(每页一张全屏图)。
|
|
45
|
+
*/
|
|
46
|
+
export declare function assemblePptxFromImages(images: string[], options?: BrowserExportOptions): Promise<BrowserExportResult>;
|
|
47
|
+
/**
|
|
48
|
+
* 一键导出:截图并组装为 PDF。
|
|
49
|
+
*/
|
|
50
|
+
export declare function exportDeckToPdfInBrowser(options?: BrowserExportOptions): Promise<BrowserExportResult>;
|
|
51
|
+
/**
|
|
52
|
+
* 一键导出:截图并组装为 PPTX。
|
|
53
|
+
*/
|
|
54
|
+
export declare function exportDeckToPptxInBrowser(options?: BrowserExportOptions): Promise<BrowserExportResult>;
|
|
55
|
+
declare global {
|
|
56
|
+
interface Window {
|
|
57
|
+
__lemonPPT_browserExport?: {
|
|
58
|
+
captureSlidesAsImages: typeof captureSlidesAsImages;
|
|
59
|
+
assemblePdfFromImages: typeof assemblePdfFromImages;
|
|
60
|
+
assemblePptxFromImages: typeof assemblePptxFromImages;
|
|
61
|
+
exportDeckToPdfInBrowser: typeof exportDeckToPdfInBrowser;
|
|
62
|
+
exportDeckToPptxInBrowser: typeof exportDeckToPptxInBrowser;
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=browser-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-export.d.ts","sourceRoot":"","sources":["../src/browser-export.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,cAAc;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU;IACV,QAAQ,EAAE,MAAM,CAAC;CAClB;AAqCD;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB;AAeD;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA0C9B;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA6B9B;AAED;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAG9B;AAED;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CAG9B;AAGD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,wBAAwB,CAAC,EAAE;YACzB,qBAAqB,EAAE,OAAO,qBAAqB,CAAC;YACpD,qBAAqB,EAAE,OAAO,qBAAqB,CAAC;YACpD,sBAAsB,EAAE,OAAO,sBAAsB,CAAC;YACtD,wBAAwB,EAAE,OAAO,wBAAwB,CAAC;YAC1D,yBAAyB,EAAE,OAAO,yBAAyB,CAAC;SAC7D,CAAC;KACH;CACF"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// lemonPPT - AI-powered presentation generation
|
|
2
|
+
// Copyright (c) 2026 lemonforme
|
|
3
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
|
+
function getVendors() {
|
|
5
|
+
const htmlToImage = window.htmlToImage;
|
|
6
|
+
const PDFLib = window.PDFLib;
|
|
7
|
+
const PptxGenJS = window.PptxGenJS;
|
|
8
|
+
if (!htmlToImage) {
|
|
9
|
+
throw new Error('缺少 html-to-image 全局变量,请先加载 assets/vendor/html-to-image.js');
|
|
10
|
+
}
|
|
11
|
+
if (!PDFLib) {
|
|
12
|
+
throw new Error('缺少 pdf-lib 全局变量,请先加载 assets/vendor/pdf-lib.js');
|
|
13
|
+
}
|
|
14
|
+
if (!PptxGenJS) {
|
|
15
|
+
throw new Error('缺少 pptxgenjs 全局变量,请先加载 assets/vendor/pptxgenjs.js');
|
|
16
|
+
}
|
|
17
|
+
return { htmlToImage, PDFLib, PptxGenJS };
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 获取所有幻灯片 DOM 节点。
|
|
21
|
+
*/
|
|
22
|
+
function getSlideElements() {
|
|
23
|
+
const nodes = document.querySelectorAll('.lp-slide-wrapper');
|
|
24
|
+
if (nodes.length === 0) {
|
|
25
|
+
throw new Error('未找到 .lp-slide-wrapper 幻灯片节点');
|
|
26
|
+
}
|
|
27
|
+
return Array.from(nodes);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* 将单页幻灯片截图为 PNG dataURL。
|
|
31
|
+
*/
|
|
32
|
+
export async function captureSlideAsImage(slide, options = {}) {
|
|
33
|
+
const { pixelRatio = 2 } = options;
|
|
34
|
+
const { htmlToImage } = getVendors();
|
|
35
|
+
// 确保当前 slide 可见,其余隐藏,避免叠加。
|
|
36
|
+
const allSlides = getSlideElements();
|
|
37
|
+
allSlides.forEach((el) => {
|
|
38
|
+
el.style.opacity = el === slide ? '1' : '0';
|
|
39
|
+
el.style.visibility = el === slide ? 'visible' : 'hidden';
|
|
40
|
+
el.style.position = el === slide ? 'relative' : 'absolute';
|
|
41
|
+
el.style.zIndex = el === slide ? 'auto' : '-1';
|
|
42
|
+
});
|
|
43
|
+
try {
|
|
44
|
+
const dataUrl = await htmlToImage.toPng(slide, {
|
|
45
|
+
pixelRatio,
|
|
46
|
+
cacheBust: true,
|
|
47
|
+
});
|
|
48
|
+
return dataUrl;
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
allSlides.forEach((el) => {
|
|
52
|
+
el.style.opacity = '';
|
|
53
|
+
el.style.visibility = '';
|
|
54
|
+
el.style.position = '';
|
|
55
|
+
el.style.zIndex = '';
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* 将所有幻灯片逐页截图为 PNG dataURL 数组。
|
|
61
|
+
*/
|
|
62
|
+
export async function captureSlidesAsImages(options = {}) {
|
|
63
|
+
const slides = getSlideElements();
|
|
64
|
+
const images = [];
|
|
65
|
+
for (let i = 0; i < slides.length; i++) {
|
|
66
|
+
const dataUrl = await captureSlideAsImage(slides[i], options);
|
|
67
|
+
images.push(dataUrl);
|
|
68
|
+
}
|
|
69
|
+
return images;
|
|
70
|
+
}
|
|
71
|
+
function dataUrlToUint8Array(dataUrl) {
|
|
72
|
+
const base64 = dataUrl.split(',')[1];
|
|
73
|
+
if (!base64) {
|
|
74
|
+
throw new Error('非法 dataURL 格式');
|
|
75
|
+
}
|
|
76
|
+
const binary = atob(base64);
|
|
77
|
+
const bytes = new Uint8Array(binary.length);
|
|
78
|
+
for (let i = 0; i < binary.length; i++) {
|
|
79
|
+
bytes[i] = binary.charCodeAt(i);
|
|
80
|
+
}
|
|
81
|
+
return bytes;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 将截图数组组装为 PDF。
|
|
85
|
+
*/
|
|
86
|
+
export async function assemblePdfFromImages(images, options = {}) {
|
|
87
|
+
const { width = 1280, height = 720, title = 'Presentation', author = 'lemonPPT' } = options;
|
|
88
|
+
const { PDFLib } = getVendors();
|
|
89
|
+
const pdfDoc = await PDFLib.PDFDocument.create();
|
|
90
|
+
pdfDoc.setTitle(title);
|
|
91
|
+
pdfDoc.setAuthor(author);
|
|
92
|
+
const pageWidth = PDFLib.PageSizes.A4[0];
|
|
93
|
+
const pageHeight = PDFLib.PageSizes.A4[1];
|
|
94
|
+
for (const dataUrl of images) {
|
|
95
|
+
const imageBytes = dataUrlToUint8Array(dataUrl);
|
|
96
|
+
const image = await pdfDoc.embedPng(imageBytes);
|
|
97
|
+
const page = pdfDoc.addPage([pageWidth, pageHeight]);
|
|
98
|
+
const scale = Math.min(pageWidth / width, pageHeight / height);
|
|
99
|
+
const drawWidth = width * scale;
|
|
100
|
+
const drawHeight = height * scale;
|
|
101
|
+
const x = (pageWidth - drawWidth) / 2;
|
|
102
|
+
const y = (pageHeight - drawHeight) / 2;
|
|
103
|
+
page.drawImage(image, {
|
|
104
|
+
x,
|
|
105
|
+
y,
|
|
106
|
+
width: drawWidth,
|
|
107
|
+
height: drawHeight,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
const pdfBytes = await pdfDoc.save();
|
|
111
|
+
const base64 = btoa(Array.from(pdfBytes)
|
|
112
|
+
.map((byte) => String.fromCharCode(byte))
|
|
113
|
+
.join(''));
|
|
114
|
+
return {
|
|
115
|
+
mimeType: 'application/pdf',
|
|
116
|
+
base64,
|
|
117
|
+
filename: 'presentation.pdf',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 将截图数组组装为 PPTX(每页一张全屏图)。
|
|
122
|
+
*/
|
|
123
|
+
export async function assemblePptxFromImages(images, options = {}) {
|
|
124
|
+
const { width = 1280, height = 720, title = 'Presentation', subject, author } = options;
|
|
125
|
+
const { PptxGenJS } = getVendors();
|
|
126
|
+
const pptx = new PptxGenJS();
|
|
127
|
+
pptx.defineLayout({ name: 'CUSTOM', width: (width * 10) / 1280, height: (height * 10) / 1280 });
|
|
128
|
+
pptx.layout = 'CUSTOM';
|
|
129
|
+
if (title)
|
|
130
|
+
pptx.title = title;
|
|
131
|
+
if (subject)
|
|
132
|
+
pptx.subject = subject;
|
|
133
|
+
if (author)
|
|
134
|
+
pptx.author = author;
|
|
135
|
+
for (const dataUrl of images) {
|
|
136
|
+
const slide = pptx.addSlide();
|
|
137
|
+
slide.addImage({
|
|
138
|
+
data: dataUrl,
|
|
139
|
+
x: 0,
|
|
140
|
+
y: 0,
|
|
141
|
+
w: (width * 10) / 1280,
|
|
142
|
+
h: (height * 10) / 1280,
|
|
143
|
+
sizing: { type: 'crop', w: (width * 10) / 1280, h: (height * 10) / 1280 },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
const base64 = await pptx.write({ outputType: 'base64' });
|
|
147
|
+
return {
|
|
148
|
+
mimeType: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
149
|
+
base64,
|
|
150
|
+
filename: 'presentation.pptx',
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* 一键导出:截图并组装为 PDF。
|
|
155
|
+
*/
|
|
156
|
+
export async function exportDeckToPdfInBrowser(options = {}) {
|
|
157
|
+
const images = await captureSlidesAsImages(options);
|
|
158
|
+
return assemblePdfFromImages(images, options);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 一键导出:截图并组装为 PPTX。
|
|
162
|
+
*/
|
|
163
|
+
export async function exportDeckToPptxInBrowser(options = {}) {
|
|
164
|
+
const images = await captureSlidesAsImages(options);
|
|
165
|
+
return assemblePptxFromImages(images, options);
|
|
166
|
+
}
|
|
167
|
+
if (typeof window !== 'undefined') {
|
|
168
|
+
window.__lemonPPT_browserExport = {
|
|
169
|
+
captureSlidesAsImages,
|
|
170
|
+
assemblePdfFromImages,
|
|
171
|
+
assemblePptxFromImages,
|
|
172
|
+
exportDeckToPdfInBrowser,
|
|
173
|
+
exportDeckToPptxInBrowser,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=browser-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser-export.js","sourceRoot":"","sources":["../src/browser-export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var __lemonPPT_browserExport=(()=>{var f=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var L=(t,e)=>{for(var o in e)f(t,o,{get:e[o],enumerable:!0})},O=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of j(e))!v.call(t,r)&&r!==o&&f(t,r,{get:()=>e[r],enumerable:!(n=F(e,r))||n.enumerable});return t};var R=t=>O(f({},"__esModule",{value:!0}),t);var G={};L(G,{assemblePdfFromImages:()=>g,assemblePptxFromImages:()=>y,captureSlideAsImage:()=>P,captureSlidesAsImages:()=>l,exportDeckToPdfInBrowser:()=>E,exportDeckToPptxInBrowser:()=>I});function w(){let t=window.htmlToImage,e=window.PDFLib,o=window.PptxGenJS;if(!t)throw new Error("\u7F3A\u5C11 html-to-image \u5168\u5C40\u53D8\u91CF\uFF0C\u8BF7\u5148\u52A0\u8F7D assets/vendor/html-to-image.js");if(!e)throw new Error("\u7F3A\u5C11 pdf-lib \u5168\u5C40\u53D8\u91CF\uFF0C\u8BF7\u5148\u52A0\u8F7D assets/vendor/pdf-lib.js");if(!o)throw new Error("\u7F3A\u5C11 pptxgenjs \u5168\u5C40\u53D8\u91CF\uFF0C\u8BF7\u5148\u52A0\u8F7D assets/vendor/pptxgenjs.js");return{htmlToImage:t,PDFLib:e,PptxGenJS:o}}function b(){let t=document.querySelectorAll(".lp-slide-wrapper");if(t.length===0)throw new Error("\u672A\u627E\u5230 .lp-slide-wrapper \u5E7B\u706F\u7247\u8282\u70B9");return Array.from(t)}async function P(t,e={}){let{pixelRatio:o=2}=e,{htmlToImage:n}=w(),r=b();r.forEach(s=>{s.style.opacity=s===t?"1":"0",s.style.visibility=s===t?"visible":"hidden",s.style.position=s===t?"relative":"absolute",s.style.zIndex=s===t?"auto":"-1"});try{return await n.toPng(t,{pixelRatio:o,cacheBust:!0})}finally{r.forEach(s=>{s.style.opacity="",s.style.visibility="",s.style.position="",s.style.zIndex=""})}}async function l(t={}){let e=b(),o=[];for(let n=0;n<e.length;n++){let r=await P(e[n],t);o.push(r)}return o}function k(t){let e=t.split(",")[1];if(!e)throw new Error("\u975E\u6CD5 dataURL \u683C\u5F0F");let o=atob(e),n=new Uint8Array(o.length);for(let r=0;r<o.length;r++)n[r]=o.charCodeAt(r);return n}async function g(t,e={}){let{width:o=1280,height:n=720,title:r="Presentation",author:s="lemonPPT"}=e,{PDFLib:p}=w(),i=await p.PDFDocument.create();i.setTitle(r),i.setAuthor(s);let a=p.PageSizes.A4[0],c=p.PageSizes.A4[1];for(let d of t){let B=k(d),S=await i.embedPng(B),A=i.addPage([a,c]),u=Math.min(a/o,c/n),h=o*u,x=n*u,D=(a-h)/2,U=(c-x)/2;A.drawImage(S,{x:D,y:U,width:h,height:x})}let m=await i.save();return{mimeType:"application/pdf",base64:btoa(Array.from(m).map(d=>String.fromCharCode(d)).join("")),filename:"presentation.pdf"}}async function y(t,e={}){let{width:o=1280,height:n=720,title:r="Presentation",subject:s,author:p}=e,{PptxGenJS:i}=w(),a=new i;a.defineLayout({name:"CUSTOM",width:o*10/1280,height:n*10/1280}),a.layout="CUSTOM",r&&(a.title=r),s&&(a.subject=s),p&&(a.author=p);for(let m of t)a.addSlide().addImage({data:m,x:0,y:0,w:o*10/1280,h:n*10/1280,sizing:{type:"crop",w:o*10/1280,h:n*10/1280}});return{mimeType:"application/vnd.openxmlformats-officedocument.presentationml.presentation",base64:await a.write({outputType:"base64"}),filename:"presentation.pptx"}}async function E(t={}){let e=await l(t);return g(e,t)}async function I(t={}){let e=await l(t);return y(e,t)}typeof window!="undefined"&&(window.__lemonPPT_browserExport={captureSlidesAsImages:l,assemblePdfFromImages:g,assemblePptxFromImages:y,exportDeckToPdfInBrowser:E,exportDeckToPptxInBrowser:I});return R(G);})();
|