mce 0.29.7 → 0.30.0

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.
@@ -37,7 +37,7 @@ declare const _default: {
37
37
  file: string;
38
38
  newDoc: string;
39
39
  openDoc: string;
40
- import: string;
40
+ importFile: string;
41
41
  export: string;
42
42
  'saveAs:png': string;
43
43
  'saveAs:jpeg': string;
@@ -147,8 +147,8 @@ declare const _default: {
147
147
  flip: string;
148
148
  flipHorizontal: string;
149
149
  flipVertical: string;
150
- showOrHideSelection: string;
151
- lockOrUnlockSelection: string;
150
+ toggleSelectionVisible: string;
151
+ toggleSelectionLock: string;
152
152
  layerOrder: string;
153
153
  bringToFront: string;
154
154
  bringForward: string;
@@ -37,7 +37,7 @@ declare const _default: {
37
37
  file: string;
38
38
  newDoc: string;
39
39
  openDoc: string;
40
- import: string;
40
+ importFile: string;
41
41
  export: string;
42
42
  'saveAs:png': string;
43
43
  'saveAs:jpeg': string;
@@ -147,8 +147,8 @@ declare const _default: {
147
147
  flip: string;
148
148
  flipHorizontal: string;
149
149
  flipVertical: string;
150
- showOrHideSelection: string;
151
- lockOrUnlockSelection: string;
150
+ toggleSelectionVisible: string;
151
+ toggleSelectionLock: string;
152
152
  layerOrder: string;
153
153
  bringToFront: string;
154
154
  bringForward: string;
@@ -3,9 +3,12 @@ declare global {
3
3
  type Upload = (file: File | Blob) => Promise<string>;
4
4
  interface Editor {
5
5
  upload: Upload;
6
+ /** 运行时设置/替换上传实现(返回上传后的可访问 URL)。 */
7
+ setUploader: (uploader: Upload) => void;
6
8
  }
7
9
  interface Options {
8
- customUpload?: Upload;
10
+ /** 上传实现:传入 blob,返回上传后的可访问 URL。也可运行时用 {@link Editor.setUploader} 设置。 */
11
+ uploader?: Upload;
9
12
  }
10
13
  }
11
14
  }
@@ -1,6 +1,7 @@
1
1
  import type { Element2D } from 'modern-canvas';
2
+ import type { ImagePipeline as ImagePipelineRef, PipelineImage } from 'modern-idoc';
2
3
  import type { Component, Ref } from 'vue';
3
- import type { AnimationPreset } from '../utils';
4
+ import type { AnimationPreset, ImagePipeline } from '../utils';
4
5
  declare global {
5
6
  namespace Mce {
6
7
  /**
@@ -102,6 +103,16 @@ declare global {
102
103
  animationPresets: Ref<AnimationPreset[]>;
103
104
  registerAnimationPreset: (preset: AnimationPreset) => void;
104
105
  getAnimationPreset: (id: string) => AnimationPreset | undefined;
106
+ /**
107
+ * 插件 / 宿主注册的图片处理管线(`image → image`,如描边/调色/抠图)。
108
+ * 数据只记录管线名与参数(`ImageFill.imagePipelines`),处理函数为运行时黑盒。
109
+ * 注册同 name 则覆盖。渲染端经引擎解析器烘焙,非渲染导出端经 `materializeImagePipelines` 物化。
110
+ */
111
+ imagePipelines: Ref<ImagePipeline[]>;
112
+ registerImagePipeline: (pipeline: ImagePipeline) => void;
113
+ getImagePipeline: (name: string) => ImagePipeline | undefined;
114
+ /** 把一串管线步骤依次作用到图片像素上(引擎解析器与导出物化共用)。 */
115
+ resolveImagePipelines: (steps: ImagePipelineRef[], image: PipelineImage) => Promise<PipelineImage>;
105
116
  }
106
117
  }
107
118
  }
@@ -17,7 +17,7 @@ declare global {
17
17
  /** 解除实例与组件的关联,变回普通元素。 */
18
18
  detachInstance: (node?: Element2D) => void;
19
19
  /** 用某节点的当前内容更新组件 master,并传播到所有实例。 */
20
- updateComponent: (componentId: string, node?: Element2D) => void;
20
+ setComponent: (componentId: string, node?: Element2D) => void;
21
21
  /** 把某组件的所有实例按 master + 各自 override 重建。 */
22
22
  syncInstancesOf: (componentId: string) => void;
23
23
  getComponents: () => ComponentDef[];
@@ -4,10 +4,10 @@ declare global {
4
4
  interface ImportOptions extends AddElementOptions {
5
5
  }
6
6
  interface Commands {
7
- import: (options?: ImportOptions) => Promise<Element2D[]>;
7
+ importFile: (options?: ImportOptions) => Promise<Element2D[]>;
8
8
  }
9
9
  interface Hotkeys {
10
- import: [event: KeyboardEvent];
10
+ importFile: [event: KeyboardEvent];
11
11
  }
12
12
  }
13
13
  }
@@ -0,0 +1,36 @@
1
+ declare global {
2
+ namespace Mce {
3
+ type SaveReason = 'auto' | 'hotkey' | 'manual';
4
+ interface SaveEvent {
5
+ /** 触发来源:自动保存 / 快捷键 / 外部主动调用 */
6
+ reason: SaveReason;
7
+ /** 惰性取当前文档数据(仅在外部需要时序列化) */
8
+ getData: () => JsonData;
9
+ }
10
+ interface AutoSaveConfig {
11
+ /** 是否在文档变更后自动触发 save 事件 */
12
+ enabled: boolean;
13
+ /** 变更后空闲多久(ms)才触发,debounce 合并连续编辑 */
14
+ debounceMs: number;
15
+ }
16
+ interface Config {
17
+ autoSave: AutoSaveConfig;
18
+ }
19
+ interface Editor {
20
+ /** 请求保存:仅对外抛出 'save' 事件,实际持久化由外部消费者处理 */
21
+ save: (reason?: SaveReason) => void;
22
+ }
23
+ interface Commands {
24
+ save: (reason?: SaveReason) => void;
25
+ }
26
+ interface Hotkeys {
27
+ save: [event: KeyboardEvent];
28
+ }
29
+ interface Events {
30
+ /** 保存请求;外部通过 editor.on('save', ({ reason, getData }) => ...) 处理持久化 */
31
+ save: [event: SaveEvent];
32
+ }
33
+ }
34
+ }
35
+ declare const _default: import("..").Plugin;
36
+ export default _default;
@@ -16,8 +16,8 @@ declare global {
16
16
  groupSelection: () => void;
17
17
  ungroupSelection: () => void;
18
18
  frameSelection: () => void;
19
- showOrHideSelection: (target?: 'show' | 'hide') => void;
20
- lockOrUnlockSelection: (target?: 'lock' | 'unlock') => void;
19
+ toggleSelectionVisible: (target?: 'show' | 'hide') => void;
20
+ toggleSelectionLock: (target?: 'lock' | 'unlock') => void;
21
21
  }
22
22
  interface Hotkeys {
23
23
  selectAll: [event: KeyboardEvent];
@@ -30,8 +30,8 @@ declare global {
30
30
  groupSelection: [event: KeyboardEvent];
31
31
  ungroupSelection: [event: KeyboardEvent];
32
32
  frameSelection: [event: KeyboardEvent];
33
- showOrHideSelection: [event: KeyboardEvent];
34
- lockOrUnlockSelection: [event: KeyboardEvent];
33
+ toggleSelectionVisible: [event: KeyboardEvent];
34
+ toggleSelectionLock: [event: KeyboardEvent];
35
35
  }
36
36
  interface Slots {
37
37
  'selection'?: () => void;
@@ -36,7 +36,7 @@ declare global {
36
36
  direction?: string;
37
37
  }
38
38
  interface Commands {
39
- enter: () => void;
39
+ editElement: () => void;
40
40
  getTransform: () => TransformValue;
41
41
  setTransform: (type: TransformType, value: Partial<TransformValue>, options?: TransformOptions) => void;
42
42
  move: (direction: MoveDirection, distance?: number) => void;
@@ -51,7 +51,7 @@ declare global {
51
51
  flipVertical: () => void;
52
52
  }
53
53
  interface Hotkeys {
54
- enter: [event: KeyboardEvent];
54
+ editElement: [event: KeyboardEvent];
55
55
  moveLeft: [event: KeyboardEvent];
56
56
  moveTop: [event: KeyboardEvent];
57
57
  moveRight: [event: KeyboardEvent];
@@ -23,7 +23,7 @@ declare global {
23
23
  interface Commands {
24
24
  startTyping: (event?: MouseEvent) => Promise<boolean>;
25
25
  addTextElement: (options?: addTextElementOptions) => Element2D;
26
- handleTextSelection: (textSelection: IndexCharacter[], cb: (arg: Record<string, any>) => boolean) => void;
26
+ eachTextSelection: (textSelection: IndexCharacter[], cb: (arg: Record<string, any>) => boolean) => void;
27
27
  textFontSizeToFit: (element: Element2D, scale?: number) => void;
28
28
  textToFit: (element: Element2D, typography?: TypographyStrategy) => void;
29
29
  getTextStyle: (key: string) => any;
@@ -6,8 +6,8 @@ declare global {
6
6
  type VariableBindings = Record<string, string>;
7
7
  interface Commands {
8
8
  createVariableCollection: (name: string, modeName?: string) => string;
9
- addVariableMode: (collectionId: string, name: string) => string;
10
- addVariable: (collectionId: string, variable: {
9
+ createVariableMode: (collectionId: string, name: string) => string;
10
+ createVariable: (collectionId: string, variable: {
11
11
  name: string;
12
12
  type: VariableType;
13
13
  value: VariableValue;
@@ -49,6 +49,7 @@ import './plugins/menu'
49
49
  import './plugins/node'
50
50
  import './plugins/pen'
51
51
  import './plugins/ruler'
52
+ import './plugins/save'
52
53
  import './plugins/saveAs'
53
54
  import './plugins/scroll'
54
55
  import './plugins/selection'
@@ -1,6 +1,11 @@
1
1
  import type { ComponentInternalInstance, ComponentPublicInstance, InjectionKey, VNodeChild } from 'vue';
2
2
  import type { DeepMaybe } from '../types';
3
3
  export declare function noop(..._args: any): void;
4
+ /**
5
+ * 节点是否为 flex/自动布局容器(其子节点由布局引擎定位,而非绝对 left/top)。
6
+ * 统一各插件(transform/selection/smartGuides/flexLayout)对 `display === 'flex'` 的判断。
7
+ */
8
+ export declare function isFlexContainer(node?: any): boolean;
4
9
  export declare function isClickInsideElement(event: MouseEvent, targetDiv: HTMLElement): boolean;
5
10
  export interface TemplateRef {
6
11
  (target: Element | ComponentPublicInstance | null): void;
@@ -0,0 +1,26 @@
1
+ import type { ImagePipeline as ImagePipelineRef, PipelineImage } from 'modern-idoc';
2
+ /**
3
+ * 图片处理管线(外部可注册):把图片像素处理成新的图片像素(`image → image`)。
4
+ *
5
+ * 数据只记录管线名与参数(`ImageFill.imagePipelines`,元素类型 `ImagePipelineRef`),
6
+ * 处理函数为运行时注册的黑盒,不入持久化数据。渲染端经引擎注入的解析器烘焙到运行时纹理;
7
+ * 非渲染的导出端(pdf/svg/pptx)经 `materializeImagePipelines` 物化成成品图。
8
+ */
9
+ export interface ImagePipeline {
10
+ /** 唯一名,对应数据 `imagePipelines[].name`。 */
11
+ name: string;
12
+ /** 显示名 i18n key(可选),供 UI 列表使用。 */
13
+ label?: string;
14
+ /** 处理函数:接收图片像素 + 参数,返回处理后的像素,可异步。 */
15
+ process: (image: PipelineImage, params?: Record<string, any>) => PipelineImage | Promise<PipelineImage>;
16
+ }
17
+ type ImagePipelineResolver = (steps: ImagePipelineRef[], image: PipelineImage) => Promise<PipelineImage>;
18
+ /**
19
+ * 导出前物化:深度遍历文档,把所有带 `imagePipelines` 的图片填充跑一遍管线,
20
+ * 结果写回 `image`(PNG dataURI)并删除 `imagePipelines` 字段。这样数据解析类导出器
21
+ * (pdf/svg/pptx)只看到普通图片填充,无需各自实现管线逻辑,跨端一致。
22
+ *
23
+ * 注意:原地修改传入的 `doc`(导出链路里 `doc` 已是 `toJSON` 出的独立快照)。
24
+ */
25
+ export declare function materializeImagePipelines(doc: any, resolve: ImagePipelineResolver): Promise<void>;
26
+ export {};
@@ -11,6 +11,7 @@ export * from './dnd';
11
11
  export * from './easing';
12
12
  export * from './helper';
13
13
  export * from './image';
14
+ export * from './imagePipeline';
14
15
  export * from './keyframes';
15
16
  export * from './line';
16
17
  export * from './lottie';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mce",
3
3
  "type": "module",
4
- "version": "0.29.7",
4
+ "version": "0.30.0",
5
5
  "description": "A headless infinite canvas editor framework built on WebGL rendering, supports exporting to image, video, and PPT. Only the ESM.",
6
6
  "author": "wxm",
7
7
  "license": "MIT",
@@ -60,9 +60,9 @@
60
60
  "@vueuse/core": "^14.3.0",
61
61
  "diff": "^9.0.0",
62
62
  "lodash-es": "^4.18.1",
63
- "modern-canvas": "^0.24.11",
63
+ "modern-canvas": "^0.25.0",
64
64
  "modern-font": "^0.6.1",
65
- "modern-idoc": "^0.12.1",
65
+ "modern-idoc": "^0.12.3",
66
66
  "modern-text": "^2.0.9",
67
67
  "y-protocols": "^1.0.7",
68
68
  "yjs": "^13.6.31"