import { App, Component, Ref } from 'vue'; import { ElementsManagerAPI } from './composables/useElements'; import { HistoryAPI } from './composables/useHistory'; export interface AudioConfig { url: string; volume?: number; [key: string]: unknown; } export interface AnimationConfig { id: string; type?: 'in' | 'emphasis' | 'out'; animate?: string; duration?: number; delay?: number; step?: number; audio?: string | AudioConfig; } export interface CanvasElementModel { value?: any; default?: any; field?: string; checked?: boolean; [key: string]: any; } export interface CanvasElementData { id: string; name?: string; type: string; x: number; y: number; width?: number; height?: number; rotation?: number; groupId?: string; isEditable?: boolean; props?: Record; propValues?: Record; slots?: Record; animations?: AnimationConfig[]; enterStep?: number; exitStep?: number; delay?: number; description?: string; events?: Record; methods?: Record; model?: CanvasElementModel; } export type CanvasRatio = '16:9' | '9:16' | '4:3' | '3:4' | '1:1' | '3:2' | '2:3' | '2:1' | '1:2' | '4:5' | '5:4' | 'auto' | (string & {}); export interface CanvasResolution { name: string; width: number; height: number; ratio: CanvasRatio; } export declare const COMMON_RESOLUTIONS: CanvasResolution[]; export interface SnapLine { axis: 'x' | 'y'; value: number; } export interface CanvasWatermarkConfig { text: string; color?: string; fontSize?: number; fontFamily?: string; opacity?: number; angle?: number; repeat?: boolean; position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'; } export interface CanvasDocumentConfig { ratio: CanvasRatio; width?: number; height?: number; background: string; bgm?: string | AudioConfig | null; enterSound?: string | AudioConfig | null; animationJson?: string; autoPlay?: boolean; autoStep?: boolean; watermark?: CanvasWatermarkConfig | null; } export interface CanvasSlideConfig { background?: string; bgm?: string | AudioConfig | null; enterSound?: string | AudioConfig | null; transition?: string; animationJson?: string; } export interface CanvasSlideData { config?: CanvasSlideConfig; elements: CanvasElementData[]; } export interface CanvasDocumentData { id?: string; meta?: Record; config: CanvasDocumentConfig; slides: CanvasSlideData[]; pluginDatas?: Record; } export type CanvasTheme = 'light' | 'dark'; export type CanvasLanguage = 'en' | 'zh'; export interface CanvasEditorConfig { theme: CanvasTheme; language: CanvasLanguage; showRoughToolbar: boolean; showPreviewControls: boolean; showRulers: boolean; showGuides: boolean; showGrid: boolean; gridSize: number; enableShortcuts: boolean; disablePan: boolean; disableBgm: boolean; muteAll: boolean; fullScreen: boolean; autoStep: boolean; showElementDescription: boolean; defaultRoughProps?: Record; [key: string]: any; } export interface CanvasParams { ratio?: CanvasRatio; width?: number; height?: number; background?: string; theme?: CanvasTheme; language?: CanvasLanguage; showRoughToolbar?: boolean; drawingMode?: string; fullScreen?: boolean; showRulers?: boolean; showGuides?: boolean; showGrid?: boolean; gridSize?: number; enableShortcuts?: boolean; autoStep?: boolean; disablePan?: boolean; bgm?: string | AudioConfig | null; enterSound?: string | AudioConfig | null; disableBgm?: boolean; muteAll?: boolean; showPreviewControls?: boolean; autoPlay?: boolean; mode?: CanvasMode; scale?: number; showElementDescription?: boolean; watermark?: CanvasWatermarkConfig | null; [key: string]: any; } export type CanvasMode = 'edit' | 'preview'; export type PresentationMode = 'default' | 'ppt'; export interface CanvasRuntimeState { activeElements: CanvasElementData[]; currentSlideIndex: number; mode: CanvasMode; presentationMode: PresentationMode; currentStep: number; scale: number; offsetX: number; offsetY: number; width: number; height: number; selectedIds: Set; lockedIds?: Set; drawingMode: string; snapLines: SnapLine[]; isSpacePressed: boolean; isMobile?: boolean; isDragging?: boolean; } export interface CanvasState { document: CanvasDocumentData; runtime: CanvasRuntimeState; editor: CanvasEditorConfig; } export interface CanvasEventContext { elements: CanvasElementData[]; selectedIds: string[]; } export type CanvasEventName = 'after-change' | 'select' | 'deselect' | 'element:add' | 'element:update' | 'element:remove' | 'element:move' | 'element:resize' | 'element:rotate' | 'group' | 'ungroup' | 'change' | 'save' | 'load' | 'undo' | 'redo' | 'init' | 'ratio-change' | 'scale-change' | 'mode-change' | 'theme-change' | 'language-change' | 'params-change' | 'background-change' | 'presentation:start' | 'presentation:stop' | 'presentation:pause' | 'presentation:resume' | 'step:change' | 'step:next' | 'step:prev' | 'step:go' | 'slide:change' | 'slide:next' | 'slide:prev' | 'slide:go' | 'pointer:move' | 'keyboard:down' | 'keyboard:up' | 'history:restore' | 'history:save' | string; /** * Centralized event name constants for use by external plugins. * Plugins can import this object and use the constants directly instead of hardcoding event name strings. * * @example * ```ts * import { CanvasEventNames } from 'vue-canvas'; * ctx.hooks.on(CanvasEventNames.PRESENTATION_START, () => { ... }); * ctx.hooks.on(CanvasEventNames.STEP_CHANGE, (step) => { ... }); * ``` */ export declare const CanvasEventNames: { readonly INIT: "init"; readonly CHANGE: "change"; readonly AFTER_CHANGE: "after-change"; readonly SELECT: "select"; readonly DESELECT: "deselect"; readonly ELEMENT_ADD: "element:add"; readonly ELEMENT_UPDATE: "element:update"; readonly ELEMENT_REMOVE: "element:remove"; readonly ELEMENT_MOVE: "element:move"; readonly ELEMENT_RESIZE: "element:resize"; readonly ELEMENT_ROTATE: "element:rotate"; readonly GROUP: "group"; readonly UNGROUP: "ungroup"; readonly SAVE: "save"; readonly LOAD: "load"; readonly UNDO: "undo"; readonly REDO: "redo"; readonly RATIO_CHANGE: "ratio-change"; readonly SCALE_CHANGE: "scale-change"; readonly MODE_CHANGE: "mode-change"; readonly THEME_CHANGE: "theme-change"; readonly LANGUAGE_CHANGE: "language-change"; readonly PARAMS_CHANGE: "params-change"; readonly BACKGROUND_CHANGE: "background-change"; readonly PRESENTATION_START: "presentation:start"; readonly PRESENTATION_STOP: "presentation:stop"; readonly PRESENTATION_PAUSE: "presentation:pause"; readonly PRESENTATION_RESUME: "presentation:resume"; readonly STEP_CHANGE: "step:change"; readonly STEP_NEXT: "step:next"; readonly STEP_PREV: "step:prev"; readonly STEP_GO: "step:go"; readonly SLIDE_CHANGE: "slide:change"; readonly SLIDE_NEXT: "slide:next"; readonly SLIDE_PREV: "slide:prev"; readonly SLIDE_GO: "slide:go"; readonly POINTER_MOVE: "pointer:move"; }; export interface ToolbarItemConfig { id?: string; icon?: string; label?: string; tooltip?: string; component?: Component | string; onClick?: () => void; position?: 'left' | 'right' | 'center'; } export interface ContextMenuConfig { id: string; type?: 'item' | 'separator'; label?: string; icon?: string; shortcut?: string; onClick?: (context: CanvasEventContext) => void; show?: (context: CanvasEventContext) => boolean; } export interface RemoteLibraryConfig { js?: string | string[]; css?: string | string[]; elements?: Record; } export interface PresentationOptions { autoPlay?: boolean; fullScreen?: boolean; showPreviewControls?: boolean; presentationMode?: 'default' | 'ppt'; autoPlayInterval?: number; disableBgm?: boolean; muteAll?: boolean; startSlide?: number; } export type CanvasProjectData = CanvasDocumentData; export interface CanvasElementsAPI { add: (el: CanvasElementData | CanvasElementData[], skipHistory?: boolean) => void; update: (id: string, props: Partial, skipHistory?: boolean) => void; remove: (id: string | string[], skipHistory?: boolean) => void; group: () => void; ungroup: () => void; align: (direction: 'top' | 'bottom' | 'left' | 'right' | 'center' | 'middle') => void; alignCanvas: (direction: 'top' | 'bottom' | 'left' | 'right' | 'center' | 'middle') => void; get: () => CanvasElementData[]; load: (components: Record) => void; register: (components: Record) => void; customComponents: Record; loadRemoteLibrary?: (config: RemoteLibraryConfig) => Promise; invokeMethod: (elementId: string, methodName: string, ...args: any[]) => any; } export interface CanvasProjectAPI { load: (data: CanvasElementData[] | CanvasDocumentData | any) => boolean | void; get: () => CanvasProjectData; setMeta: (payload: { id?: string; meta?: Record; }) => void; clear: () => void; export: (options?: { format?: 'json' | 'png' | 'svg' | 'blob' | 'jpeg'; download?: boolean; selectionOnly?: boolean; quality?: number; scale?: number; }) => Promise; copyToPng: (options?: { selectIds?: string[]; background?: string; scale?: number; }) => Promise; copyToSvg: (options?: { selectIds?: string[]; background?: string; scale?: number; }) => Promise; save: () => void; saveState: (skipBroadcast?: boolean) => void; } export interface CanvasEditorAPI { setMode: (mode: CanvasMode) => void; setScale: (scale: number) => void; zoomToCenter: (scale: number) => void; setDisablePan: (disable: boolean) => void; setBackground: (bg: string) => void; setAnimation: (animation: string | null) => void; setResolution: (width: number, height: number, ratio?: CanvasRatio) => void; toolbarItems: Ref; contextMenuItems: Ref; overlays: Ref boolean; component: any; } | any>>; setParams: (params: Partial) => void; resetParams: () => void; setLanguage: (lang: CanvasLanguage) => void; setAudio: (type: 'bgm' | 'slide' | 'element', audio: string | AudioConfig | null) => void; registerToolbarItem: (item: ToolbarItemConfig, index?: number) => void; registerContextMenuItem: (item: ContextMenuConfig, index?: number) => void; registerOverlay: (overlay: { show?: () => boolean; component: any; } | any) => void; mode: Ref; drawingMode: Ref; theme: Ref; showGuides: Ref; t: (key: string, ...args: any[]) => any; getDOM?: () => HTMLElement | null; } export interface CanvasPresentationAPI { start: (options?: boolean | PresentationOptions) => void; stop: () => void; nextStep: () => void; prevStep: () => void; goStep: (step: number) => void; pauseStep: () => void; setMode: (mode: 'default' | 'ppt') => void; nextSlide: () => void; prevSlide: () => void; goSlide: (index: number) => void; } export interface CanvasHooksAPI { on: (event: CanvasEventName, callback: (...args: any[]) => void) => void; off: (event: CanvasEventName, callback: (...args: any[]) => void) => void; emit: (event: CanvasEventName, ...args: any[]) => void; } export interface CanvasFormAPI { getFormData: (elementIds?: string[]) => Record; getCheckedFormData: () => Record; getFields: (checked?: boolean) => string[]; setFormData: (data: Record) => void; setFieldData: (field: string, value: any) => void; } export interface CanvasContext { state: CanvasState; selection: ElementsManagerAPI; history: HistoryAPI; api: { elements: CanvasElementsAPI; project: CanvasProjectAPI; editor: CanvasEditorAPI; presentation: CanvasPresentationAPI; form: CanvasFormAPI; }; hooks: CanvasHooksAPI; } export interface CanvasPluginContext extends CanvasContext { app?: App; plugin: { getName: () => string | undefined; getVersion: () => string | undefined; /** Get this plugin's own persisted data by key */ getPluginData: (key: string) => any; /** Set this plugin's own persisted data by key */ setPluginData: (key: string, value: any) => void; /** Get all plugins' persisted data (read-only snapshot) */ getAllPluginData: () => Record; }; registerPlugin: (plugin: CanvasPlugin, options?: Record) => void; unregisterPlugin: (pluginName: string) => void; loadPlugin: (url: string, options?: Record) => Promise; getActivePlugins: () => CanvasPlugin[]; } export interface CanvasPlugin { name: string; version?: string; install: (ctx: CanvasPluginContext, options?: Record) => void; destroy?: () => void; }