diff --git a/src/components/index.ts b/src/components/index.ts index 2fdaa8d..53b2deb 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -82,6 +82,7 @@ import { ExportDocx } from "./menus/toolbar/export/ExportDocx.ts"; import { ExportOdt } from "./menus/toolbar/export/ExportOdt.ts"; import { ExportPdf } from "./menus/toolbar/export/ExportPdf.ts"; import { ExportMarkdown } from "./menus/toolbar/export/ExportMarkdown.ts"; +import { ExportImage } from "./menus/toolbar/export/ExportImage.ts"; // 注册组件 defineCustomElement('uai-editor-header', Header); @@ -165,3 +166,4 @@ defineCustomElement('uai-editor-export-menu-docx', ExportDocx); defineCustomElement('uai-editor-export-menu-odt', ExportOdt); defineCustomElement('uai-editor-export-menu-pdf', ExportPdf); defineCustomElement('uai-editor-export-menu-markdown', ExportMarkdown); +defineCustomElement('uai-editor-export-menu-image', ExportImage); diff --git a/src/components/menus/toolbar/Classic.ts b/src/components/menus/toolbar/Classic.ts index 6f44274..4ddda1e 100644 --- a/src/components/menus/toolbar/Classic.ts +++ b/src/components/menus/toolbar/Classic.ts @@ -75,6 +75,7 @@ import { ExportDocx } from "./export/ExportDocx.ts"; import { ExportOdt } from "./export/ExportOdt.ts"; import { ExportPdf } from "./export/ExportPdf.ts"; import { ExportMarkdown } from "./export/ExportMarkdown.ts"; +import { ExportImage } from "./export/ExportImage.ts"; /** * 传统菜单栏 @@ -181,6 +182,7 @@ export class Classic extends HTMLElement implements UAIEditorEventListener { exportMenuExportOdt!: ExportOdt; exportMenuExportPdf!: ExportPdf; exportMenuExportMarkdown!: ExportMarkdown; + exportMenuExportImage!: ExportImage; constructor(defaultToolbarMenus: Record[]) { super(); @@ -445,6 +447,9 @@ export class Classic extends HTMLElement implements UAIEditorEventListener { this.exportMenuExportMarkdown = new ExportMarkdown({ menuType: "button", enable: true, header: "classic", hideText: false }); this.eventComponents.push(this.exportMenuExportMarkdown); + + this.exportMenuExportImage = new ExportImage({ menuType: "button", enable: true, header: "classic", hideText: false }); + this.eventComponents.push(this.exportMenuExportImage); } /** * 创建基础菜单 @@ -639,5 +644,10 @@ export class Classic extends HTMLElement implements UAIEditorEventListener { group1.appendChild(this.exportMenuExportOdt); group1.appendChild(this.exportMenuExportPdf); group1.appendChild(this.exportMenuExportMarkdown); + + const group2 = document.createElement("div"); + group2.classList.add("uai-classic-virtual-group"); + this.classicMenuExportGroup.appendChild(group2); + group2.appendChild(this.exportMenuExportImage); } } \ No newline at end of file diff --git a/src/components/menus/toolbar/Ribbon.ts b/src/components/menus/toolbar/Ribbon.ts index aa1d32f..8ef3436 100644 --- a/src/components/menus/toolbar/Ribbon.ts +++ b/src/components/menus/toolbar/Ribbon.ts @@ -77,6 +77,7 @@ import { ExportDocx } from "./export/ExportDocx.ts"; import { ExportOdt } from "./export/ExportOdt.ts"; import { ExportPdf } from "./export/ExportPdf.ts"; import { ExportMarkdown } from "./export/ExportMarkdown.ts"; +import { ExportImage } from "./export/ExportImage.ts"; /** * 经典菜单栏 @@ -184,6 +185,7 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener { exportMenuExportOdt!: ExportOdt; exportMenuExportPdf!: ExportPdf; exportMenuExportMarkdown!: ExportMarkdown; + exportMenuExportImage!: ExportImage; constructor(defaultToolbarMenus: Record[]) { super(); @@ -468,6 +470,9 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener { this.exportMenuExportMarkdown = new ExportMarkdown({ menuType: "button", enable: true, huge: true, hideText: false }); this.eventComponents.push(this.exportMenuExportMarkdown); + + this.exportMenuExportImage = new ExportImage({ menuType: "button", enable: true, huge: true, hideText: false }); + this.eventComponents.push(this.exportMenuExportImage); } /** @@ -744,5 +749,10 @@ export class Ribbon extends HTMLElement implements UAIEditorEventListener { group1.appendChild(this.exportMenuExportOdt); group1.appendChild(this.exportMenuExportPdf); group1.appendChild(this.exportMenuExportMarkdown); + + const group2 = document.createElement("div"); + group2.classList.add("uai-ribbon-virtual-group"); + this.ribbonMenuExportGroup.appendChild(group2); + group2.appendChild(this.exportMenuExportImage); } } \ No newline at end of file diff --git a/src/components/menus/toolbar/export/ExportImage.ts b/src/components/menus/toolbar/export/ExportImage.ts new file mode 100644 index 0000000..676c8a3 --- /dev/null +++ b/src/components/menus/toolbar/export/ExportImage.ts @@ -0,0 +1,78 @@ +// Copyright (c) 2024-present AI-Labs + +// @ ts-nocheck +import { MenuButton, MenuButtonOptions } from "../../MenuButton.ts"; +import icon from "../../../../assets/icons/image.svg"; +import { t } from "i18next"; +import { UAIEditorEventListener, UAIEditorOptions } from "../../../../core/UAIEditor.ts"; +import { EditorEvents } from "@tiptap/core"; +import domtoimage from 'dom-to-image-more'; +import { saveAs } from 'file-saver'; + +/** + * 导出菜单:导出图片 + */ +export class ExportImage extends HTMLElement implements UAIEditorEventListener { + // 按钮选项 + menuButtonOptions: MenuButtonOptions = { + menuType: "button", + enable: true, + icon: icon, + hideText: true, + text: t('export.image.text'), + tooltip: t('export.image.title'), + } + + // 功能按钮 + menuButton: MenuButton; + + constructor(options: MenuButtonOptions) { + super(); + + // 初始化功能按钮选项 + this.menuButtonOptions = { ...this.menuButtonOptions, ...options }; + + // 创建功能按钮 + this.menuButton = new MenuButton(this.menuButtonOptions); + } + + /** + * 定义创建方法 + * @param event + * @param options + */ + onCreate(event: EditorEvents["create"], options: UAIEditorOptions) { + this.menuButton.onCreate(event, options); + this.appendChild(this.menuButton); + + // 定义按钮点击事件,导出文件 + this.addEventListener("click", async () => { + if (this.menuButtonOptions.enable) { + const content = document.querySelector(".uai-zoomable-content") as HTMLElement; + const { toBlob } = domtoimage; + const blob = await toBlob(content, { + style: { + transform: 'scale(1)', // 如果需要的话,可以通过transform来缩放元素 + transformOrigin: 'top left', // 设置变换的原点 + } + }); + saveAs(blob, `export-${Date.now()}.jpg`,); + } + }) + } + + /** + * 定义Transaction监听方法 + * @param event + * @param options + */ + onTransaction(event: EditorEvents["transaction"], options: UAIEditorOptions) { + this.menuButton.onTransaction(event, options); + } + + onEditableChange(editable: boolean) { + this.menuButtonOptions.enable = editable; + this.menuButton.onEditableChange(editable); + } +} +