@hprint/plugins 0.0.1-alpha.1 → 0.0.1-alpha.3

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.
Files changed (64) hide show
  1. package/dist/index.js +122 -117
  2. package/dist/index.mjs +41257 -21115
  3. package/dist/src/plugins/AlignGuidLinePlugin.d.ts +7 -2
  4. package/dist/src/plugins/AlignGuidLinePlugin.d.ts.map +1 -1
  5. package/dist/src/plugins/BarCodePlugin.d.ts +4 -0
  6. package/dist/src/plugins/BarCodePlugin.d.ts.map +1 -1
  7. package/dist/src/plugins/CreateElementPlugin.d.ts +3 -9
  8. package/dist/src/plugins/CreateElementPlugin.d.ts.map +1 -1
  9. package/dist/src/plugins/GroupAlignPlugin.d.ts.map +1 -1
  10. package/dist/src/plugins/LockPlugin.d.ts.map +1 -1
  11. package/dist/src/plugins/QrCodePlugin.d.ts +19 -97
  12. package/dist/src/plugins/QrCodePlugin.d.ts.map +1 -1
  13. package/dist/src/plugins/ResizePlugin.d.ts.map +1 -1
  14. package/dist/src/plugins/UnitPlugin.d.ts.map +1 -1
  15. package/dist/src/plugins/WorkspacePlugin.d.ts.map +1 -1
  16. package/dist/src/utils/units.d.ts.map +1 -1
  17. package/package.json +5 -4
  18. package/src/assets/style/resizePlugin.css +27 -27
  19. package/src/objects/Arrow.js +47 -47
  20. package/src/objects/ThinTailArrow.js +50 -50
  21. package/src/plugins/AlignGuidLinePlugin.ts +1152 -1141
  22. package/src/plugins/BarCodePlugin.ts +33 -27
  23. package/src/plugins/ControlsPlugin.ts +251 -251
  24. package/src/plugins/ControlsRotatePlugin.ts +111 -111
  25. package/src/plugins/CopyPlugin.ts +255 -255
  26. package/src/plugins/CreateElementPlugin.ts +14 -10
  27. package/src/plugins/DeleteHotKeyPlugin.ts +57 -57
  28. package/src/plugins/DrawLinePlugin.ts +162 -162
  29. package/src/plugins/DrawPolygonPlugin.ts +205 -205
  30. package/src/plugins/DringPlugin.ts +125 -125
  31. package/src/plugins/FlipPlugin.ts +59 -59
  32. package/src/plugins/FontPlugin.ts +165 -165
  33. package/src/plugins/FreeDrawPlugin.ts +49 -49
  34. package/src/plugins/GroupAlignPlugin.ts +365 -365
  35. package/src/plugins/GroupPlugin.ts +82 -82
  36. package/src/plugins/GroupTextEditorPlugin.ts +198 -198
  37. package/src/plugins/HistoryPlugin.ts +181 -181
  38. package/src/plugins/ImageStroke.ts +121 -121
  39. package/src/plugins/LayerPlugin.ts +108 -108
  40. package/src/plugins/LockPlugin.ts +242 -240
  41. package/src/plugins/MaskPlugin.ts +155 -155
  42. package/src/plugins/MaterialPlugin.ts +224 -224
  43. package/src/plugins/MiddleMousePlugin.ts +45 -45
  44. package/src/plugins/MoveHotKeyPlugin.ts +46 -46
  45. package/src/plugins/PathTextPlugin.ts +89 -89
  46. package/src/plugins/PolygonModifyPlugin.ts +224 -224
  47. package/src/plugins/PrintPlugin.ts +81 -81
  48. package/src/plugins/PsdPlugin.ts +52 -52
  49. package/src/plugins/QrCodePlugin.ts +322 -393
  50. package/src/plugins/ResizePlugin.ts +278 -274
  51. package/src/plugins/RulerPlugin.ts +78 -78
  52. package/src/plugins/SimpleClipImagePlugin.ts +244 -244
  53. package/src/plugins/UnitPlugin.ts +326 -327
  54. package/src/plugins/WaterMarkPlugin.ts +257 -257
  55. package/src/plugins/WorkspacePlugin.ts +10 -6
  56. package/src/types/eventType.ts +11 -11
  57. package/src/utils/psd.js +432 -432
  58. package/src/utils/ruler/guideline.ts +145 -145
  59. package/src/utils/ruler/index.ts +91 -91
  60. package/src/utils/ruler/ruler.ts +924 -924
  61. package/src/utils/ruler/utils.ts +162 -162
  62. package/src/utils/units.ts +4 -2
  63. package/tsconfig.json +10 -10
  64. package/vite.config.ts +29 -29
@@ -1,181 +1,181 @@
1
- import Editor, { fabric } from '@hprint/core';
2
- import type { IPluginTempl } from '@hprint/core';
3
-
4
- type IEditor = Editor;
5
- type callback = () => void;
6
-
7
- class HistoryPlugin implements IPluginTempl {
8
- static pluginName = 'HistoryPlugin';
9
- static apis = [
10
- 'undo',
11
- 'redo',
12
- 'historyUpdate',
13
- 'clearAndSaveState',
14
- 'saveState',
15
- ];
16
- static events = [];
17
-
18
- // 历史记录相关属性
19
- private stack: string[] = [];
20
- private currentIndex = 0;
21
- private maxLength = 100;
22
- private isProcessing = false;
23
- private isLoading = false;
24
-
25
- hotkeys: string[] = ['ctrl+z', 'ctrl+shift+z', '⌘+z', '⌘+shift+z'];
26
-
27
- constructor(
28
- public canvas: fabric.Canvas,
29
- public editor: IEditor
30
- ) {
31
- this._init();
32
- }
33
-
34
- private _init() {
35
- // 监听对象变更事件
36
- const events = {
37
- 'object:removed': () => this.saveState(),
38
- 'object:modified': () => this.saveState(),
39
- 'object:skewing': () => this.saveState(),
40
- };
41
-
42
- // 绑定事件
43
- Object.entries(events).forEach(([event, handler]) => {
44
- this.canvas.on(event, handler);
45
- });
46
-
47
- // 初始化状态
48
- this.saveState();
49
-
50
- // 更新历史记录状态
51
- this.canvas.on('history:append', () => {
52
- this.historyUpdate();
53
- });
54
-
55
- // 页面离开提示
56
- // window.addEventListener('beforeunload', (e) => {
57
- // const { undoCount } = this.getState();
58
- // if (undoCount > 0) {
59
- // (e || window.event).returnValue = '确认离开';
60
- // }
61
- // });
62
- }
63
-
64
- // 获取当前状态
65
- private getCurrentState() {
66
- return this.editor.getJson();
67
- }
68
-
69
- // 保存状态
70
- private saveState() {
71
- if (this.isProcessing) return;
72
-
73
- // 清除当前索引后的记录
74
- this.stack.splice(this.currentIndex);
75
- this.stack.push(this.getCurrentState());
76
-
77
- // 维护最大长度
78
- if (this.stack.length > this.maxLength) {
79
- this.stack.shift();
80
- } else {
81
- this.currentIndex++;
82
- }
83
- this.historyUpdate();
84
- }
85
-
86
- // 加载状态
87
- private _loadState(state: string, eventName: string, callback?: callback) {
88
- this.isLoading = true;
89
- this.isProcessing = true;
90
-
91
- // 处理 workspace 的特殊情况
92
- const parsedState = JSON.parse(state);
93
- const workspace = parsedState.objects?.find(
94
- (item: any) => item.id === 'workspace'
95
- );
96
- if (workspace) {
97
- workspace.evented = false;
98
- }
99
-
100
- this.canvas.loadFromJSON(state, () => {
101
- this.canvas.renderAll();
102
- this.canvas.fire(eventName);
103
- this.isProcessing = false;
104
- this.isLoading = false;
105
- callback?.();
106
- });
107
- }
108
-
109
- // 获取历史记录状态
110
- private getState() {
111
- return {
112
- undoCount: this.currentIndex - 1,
113
- redoCount: this.stack.length - this.currentIndex,
114
- };
115
- }
116
-
117
- // 清空历史记录
118
- private clear() {
119
- this.stack = [];
120
- this.currentIndex = 0;
121
- this.saveState();
122
- }
123
-
124
- // 公开方法
125
- historyUpdate() {
126
- const { undoCount, redoCount } = this.getState();
127
- this.editor.emit('historyUpdate', undoCount, redoCount);
128
- }
129
-
130
- hookImportAfter() {
131
- this.clear();
132
- this.historyUpdate();
133
- return Promise.resolve();
134
- }
135
-
136
- undo() {
137
- if (this.isLoading || this.currentIndex <= 1) return;
138
-
139
- this.currentIndex--;
140
- const state = this.stack[this.currentIndex - 1];
141
- if (state) {
142
- this._loadState(JSON.stringify(state), 'history:undo');
143
- this.historyUpdate();
144
- }
145
- }
146
-
147
- redo() {
148
- if (this.isLoading || this.currentIndex >= this.stack.length) return;
149
-
150
- const state = this.stack[this.currentIndex];
151
- if (state) {
152
- this._loadState(JSON.stringify(state), 'history:redo');
153
- this.currentIndex++;
154
- this.historyUpdate();
155
- }
156
- }
157
-
158
- hotkeyEvent(eventName: string, e: KeyboardEvent) {
159
- if (e.type === 'keydown') {
160
- switch (eventName) {
161
- case 'ctrl+z':
162
- case '⌘+z':
163
- this.undo();
164
- break;
165
- case 'ctrl+shift+z':
166
- case '⌘+shift+z':
167
- this.redo();
168
- break;
169
- }
170
- }
171
- }
172
-
173
- clearAndSaveState() {
174
- const currentState = this.getCurrentState();
175
- this.stack = [currentState]; // 只保留当前状态作为第一条记录
176
- this.currentIndex = 1;
177
- this.historyUpdate();
178
- }
179
- }
180
-
181
- export default HistoryPlugin;
1
+ import Editor, { fabric } from '@hprint/core';
2
+ import type { IPluginTempl } from '@hprint/core';
3
+
4
+ type IEditor = Editor;
5
+ type callback = () => void;
6
+
7
+ class HistoryPlugin implements IPluginTempl {
8
+ static pluginName = 'HistoryPlugin';
9
+ static apis = [
10
+ 'undo',
11
+ 'redo',
12
+ 'historyUpdate',
13
+ 'clearAndSaveState',
14
+ 'saveState',
15
+ ];
16
+ static events = [];
17
+
18
+ // 历史记录相关属性
19
+ private stack: string[] = [];
20
+ private currentIndex = 0;
21
+ private maxLength = 100;
22
+ private isProcessing = false;
23
+ private isLoading = false;
24
+
25
+ hotkeys: string[] = ['ctrl+z', 'ctrl+shift+z', '⌘+z', '⌘+shift+z'];
26
+
27
+ constructor(
28
+ public canvas: fabric.Canvas,
29
+ public editor: IEditor
30
+ ) {
31
+ this._init();
32
+ }
33
+
34
+ private _init() {
35
+ // 监听对象变更事件
36
+ const events = {
37
+ 'object:removed': () => this.saveState(),
38
+ 'object:modified': () => this.saveState(),
39
+ 'object:skewing': () => this.saveState(),
40
+ };
41
+
42
+ // 绑定事件
43
+ Object.entries(events).forEach(([event, handler]) => {
44
+ this.canvas.on(event, handler);
45
+ });
46
+
47
+ // 初始化状态
48
+ this.saveState();
49
+
50
+ // 更新历史记录状态
51
+ this.canvas.on('history:append', () => {
52
+ this.historyUpdate();
53
+ });
54
+
55
+ // 页面离开提示
56
+ // window.addEventListener('beforeunload', (e) => {
57
+ // const { undoCount } = this.getState();
58
+ // if (undoCount > 0) {
59
+ // (e || window.event).returnValue = '确认离开';
60
+ // }
61
+ // });
62
+ }
63
+
64
+ // 获取当前状态
65
+ private getCurrentState() {
66
+ return this.editor.getJson();
67
+ }
68
+
69
+ // 保存状态
70
+ private saveState() {
71
+ if (this.isProcessing) return;
72
+
73
+ // 清除当前索引后的记录
74
+ this.stack.splice(this.currentIndex);
75
+ this.stack.push(this.getCurrentState());
76
+
77
+ // 维护最大长度
78
+ if (this.stack.length > this.maxLength) {
79
+ this.stack.shift();
80
+ } else {
81
+ this.currentIndex++;
82
+ }
83
+ this.historyUpdate();
84
+ }
85
+
86
+ // 加载状态
87
+ private _loadState(state: string, eventName: string, callback?: callback) {
88
+ this.isLoading = true;
89
+ this.isProcessing = true;
90
+
91
+ // 处理 workspace 的特殊情况
92
+ const parsedState = JSON.parse(state);
93
+ const workspace = parsedState.objects?.find(
94
+ (item: any) => item.id === 'workspace'
95
+ );
96
+ if (workspace) {
97
+ workspace.evented = false;
98
+ }
99
+
100
+ this.canvas.loadFromJSON(state, () => {
101
+ this.canvas.renderAll();
102
+ this.canvas.fire(eventName);
103
+ this.isProcessing = false;
104
+ this.isLoading = false;
105
+ callback?.();
106
+ });
107
+ }
108
+
109
+ // 获取历史记录状态
110
+ private getState() {
111
+ return {
112
+ undoCount: this.currentIndex - 1,
113
+ redoCount: this.stack.length - this.currentIndex,
114
+ };
115
+ }
116
+
117
+ // 清空历史记录
118
+ private clear() {
119
+ this.stack = [];
120
+ this.currentIndex = 0;
121
+ this.saveState();
122
+ }
123
+
124
+ // 公开方法
125
+ historyUpdate() {
126
+ const { undoCount, redoCount } = this.getState();
127
+ this.editor.emit('historyUpdate', undoCount, redoCount);
128
+ }
129
+
130
+ hookImportAfter() {
131
+ this.clear();
132
+ this.historyUpdate();
133
+ return Promise.resolve();
134
+ }
135
+
136
+ undo() {
137
+ if (this.isLoading || this.currentIndex <= 1) return;
138
+
139
+ this.currentIndex--;
140
+ const state = this.stack[this.currentIndex - 1];
141
+ if (state) {
142
+ this._loadState(JSON.stringify(state), 'history:undo');
143
+ this.historyUpdate();
144
+ }
145
+ }
146
+
147
+ redo() {
148
+ if (this.isLoading || this.currentIndex >= this.stack.length) return;
149
+
150
+ const state = this.stack[this.currentIndex];
151
+ if (state) {
152
+ this._loadState(JSON.stringify(state), 'history:redo');
153
+ this.currentIndex++;
154
+ this.historyUpdate();
155
+ }
156
+ }
157
+
158
+ hotkeyEvent(eventName: string, e: KeyboardEvent) {
159
+ if (e.type === 'keydown') {
160
+ switch (eventName) {
161
+ case 'ctrl+z':
162
+ case '⌘+z':
163
+ this.undo();
164
+ break;
165
+ case 'ctrl+shift+z':
166
+ case '⌘+shift+z':
167
+ this.redo();
168
+ break;
169
+ }
170
+ }
171
+ }
172
+
173
+ clearAndSaveState() {
174
+ const currentState = this.getCurrentState();
175
+ this.stack = [currentState]; // 只保留当前状态作为第一条记录
176
+ this.currentIndex = 1;
177
+ this.historyUpdate();
178
+ }
179
+ }
180
+
181
+ export default HistoryPlugin;
@@ -1,121 +1,121 @@
1
- import { fabric } from '@hprint/core';
2
- import type { IEditor, IPluginTempl } from '@hprint/core';
3
-
4
- type IPlugin = Pick<ImageStrokePlugin, 'imageStrokeDraw'>;
5
-
6
- declare module '@hprint/core' {
7
- // eslint-disable-next-line @typescript-eslint/no-empty-interface
8
- interface IEditor extends IPlugin {}
9
- }
10
-
11
- /*type IStrokeOps = {
12
- enabled: boolean;
13
- width: number;
14
- color: string;
15
- type: 'destination-out' | 'source-over' | 'source-in';
16
- };*/
17
- interface IExtendImage {
18
- [x: string]: any;
19
- originWidth?: number;
20
- originHeight?: number;
21
- originSrc?: string;
22
- }
23
- class ImageStrokePlugin implements IPluginTempl {
24
- static pluginName = 'ImageStroke';
25
- static apis = ['imageStrokeDraw'];
26
- // public options: Required<IStrokeOps>;
27
- constructor(
28
- public canvas: fabric.Canvas,
29
- public editor: IEditor
30
- ) {
31
- // this.options = Object.assign(
32
- // {
33
- // enabled: false,
34
- // width: 5,
35
- // color: '#000',
36
- // type: 'source-over',
37
- // },
38
- // _options
39
- // );
40
- }
41
-
42
- private addImage(src: string): Promise<HTMLImageElement | undefined> {
43
- return new Promise((resolve, reject) => {
44
- const img = new Image();
45
- img.crossOrigin = 'anonymous';
46
- img.onload = () => resolve(img);
47
- img.onerror = () => reject();
48
- img.src = src;
49
- });
50
- }
51
-
52
- // imageStrokeEnable() {
53
- // this.options.enabled = true;
54
- // }
55
-
56
- // imageStrokeDisable() {
57
- // this.options.enabled = false;
58
- // }
59
-
60
- // imageStrokeSet(key: 'enabled' | 'width' | 'color' | 'type', val: any) {
61
- // this.options[key] = val;
62
- // }
63
-
64
- async imageStrokeDraw(
65
- stroke: string,
66
- strokeWidth: number,
67
- type = 'source-over'
68
- ) {
69
- const activeObject = this.canvas.getActiveObject() as
70
- | (fabric.Image & IExtendImage)
71
- | undefined;
72
- if (!activeObject) return;
73
- const w = activeObject.originWidth || 0,
74
- h = activeObject.originHeight || 0,
75
- src = activeObject?.originSrc || activeObject.getSrc();
76
- let canvas: HTMLCanvasElement | null = document.createElement('canvas');
77
- const ctx = canvas!.getContext('2d');
78
- if (!ctx) return;
79
- // 描边等于0 说明关闭了开关或者不需要描边 直接从原图绘制
80
- if (strokeWidth === 0) {
81
- activeObject.setSrc(src, () => {
82
- activeObject.canvas?.renderAll();
83
- });
84
- return;
85
- }
86
- ctx.save();
87
- ctx.clearRect(0, 0, canvas!.width, canvas!.height);
88
- ctx.restore();
89
- canvas!.width = w + strokeWidth * 2;
90
- canvas!.height = h + strokeWidth * 2;
91
- const dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1];
92
- const img = await this.addImage(src);
93
- if (!img) return;
94
- for (let i = 0; i < dArr.length; i += 2) {
95
- ctx.drawImage(
96
- img,
97
- strokeWidth + dArr[i] * strokeWidth,
98
- strokeWidth + dArr[i + 1] * strokeWidth,
99
- w,
100
- h
101
- );
102
- }
103
- ctx.globalCompositeOperation = 'source-in';
104
- ctx.fillStyle = stroke;
105
- ctx.fillRect(0, 0, w + strokeWidth * 2, h + strokeWidth * 2);
106
- ctx.globalCompositeOperation = type as any;
107
- ctx.drawImage(img, strokeWidth, strokeWidth, w, h);
108
- const res = canvas?.toDataURL();
109
- canvas = null;
110
- if (!res) return;
111
- activeObject.setSrc(res, () => {
112
- activeObject.canvas?.renderAll();
113
- });
114
- }
115
-
116
- destroy() {
117
- // this.editor.off('sizeChange', this.drawWaterMark);
118
- }
119
- }
120
-
121
- export default ImageStrokePlugin;
1
+ import { fabric } from '@hprint/core';
2
+ import type { IEditor, IPluginTempl } from '@hprint/core';
3
+
4
+ type IPlugin = Pick<ImageStrokePlugin, 'imageStrokeDraw'>;
5
+
6
+ declare module '@hprint/core' {
7
+ // eslint-disable-next-line @typescript-eslint/no-empty-interface
8
+ interface IEditor extends IPlugin {}
9
+ }
10
+
11
+ /*type IStrokeOps = {
12
+ enabled: boolean;
13
+ width: number;
14
+ color: string;
15
+ type: 'destination-out' | 'source-over' | 'source-in';
16
+ };*/
17
+ interface IExtendImage {
18
+ [x: string]: any;
19
+ originWidth?: number;
20
+ originHeight?: number;
21
+ originSrc?: string;
22
+ }
23
+ class ImageStrokePlugin implements IPluginTempl {
24
+ static pluginName = 'ImageStroke';
25
+ static apis = ['imageStrokeDraw'];
26
+ // public options: Required<IStrokeOps>;
27
+ constructor(
28
+ public canvas: fabric.Canvas,
29
+ public editor: IEditor
30
+ ) {
31
+ // this.options = Object.assign(
32
+ // {
33
+ // enabled: false,
34
+ // width: 5,
35
+ // color: '#000',
36
+ // type: 'source-over',
37
+ // },
38
+ // _options
39
+ // );
40
+ }
41
+
42
+ private addImage(src: string): Promise<HTMLImageElement | undefined> {
43
+ return new Promise((resolve, reject) => {
44
+ const img = new Image();
45
+ img.crossOrigin = 'anonymous';
46
+ img.onload = () => resolve(img);
47
+ img.onerror = () => reject();
48
+ img.src = src;
49
+ });
50
+ }
51
+
52
+ // imageStrokeEnable() {
53
+ // this.options.enabled = true;
54
+ // }
55
+
56
+ // imageStrokeDisable() {
57
+ // this.options.enabled = false;
58
+ // }
59
+
60
+ // imageStrokeSet(key: 'enabled' | 'width' | 'color' | 'type', val: any) {
61
+ // this.options[key] = val;
62
+ // }
63
+
64
+ async imageStrokeDraw(
65
+ stroke: string,
66
+ strokeWidth: number,
67
+ type = 'source-over'
68
+ ) {
69
+ const activeObject = this.canvas.getActiveObject() as
70
+ | (fabric.Image & IExtendImage)
71
+ | undefined;
72
+ if (!activeObject) return;
73
+ const w = activeObject.originWidth || 0,
74
+ h = activeObject.originHeight || 0,
75
+ src = activeObject?.originSrc || activeObject.getSrc();
76
+ let canvas: HTMLCanvasElement | null = document.createElement('canvas');
77
+ const ctx = canvas!.getContext('2d');
78
+ if (!ctx) return;
79
+ // 描边等于0 说明关闭了开关或者不需要描边 直接从原图绘制
80
+ if (strokeWidth === 0) {
81
+ activeObject.setSrc(src, () => {
82
+ activeObject.canvas?.renderAll();
83
+ });
84
+ return;
85
+ }
86
+ ctx.save();
87
+ ctx.clearRect(0, 0, canvas!.width, canvas!.height);
88
+ ctx.restore();
89
+ canvas!.width = w + strokeWidth * 2;
90
+ canvas!.height = h + strokeWidth * 2;
91
+ const dArr = [-1, -1, 0, -1, 1, -1, -1, 0, 1, 0, -1, 1, 0, 1, 1, 1];
92
+ const img = await this.addImage(src);
93
+ if (!img) return;
94
+ for (let i = 0; i < dArr.length; i += 2) {
95
+ ctx.drawImage(
96
+ img,
97
+ strokeWidth + dArr[i] * strokeWidth,
98
+ strokeWidth + dArr[i + 1] * strokeWidth,
99
+ w,
100
+ h
101
+ );
102
+ }
103
+ ctx.globalCompositeOperation = 'source-in';
104
+ ctx.fillStyle = stroke;
105
+ ctx.fillRect(0, 0, w + strokeWidth * 2, h + strokeWidth * 2);
106
+ ctx.globalCompositeOperation = type as any;
107
+ ctx.drawImage(img, strokeWidth, strokeWidth, w, h);
108
+ const res = canvas?.toDataURL();
109
+ canvas = null;
110
+ if (!res) return;
111
+ activeObject.setSrc(res, () => {
112
+ activeObject.canvas?.renderAll();
113
+ });
114
+ }
115
+
116
+ destroy() {
117
+ // this.editor.off('sizeChange', this.drawWaterMark);
118
+ }
119
+ }
120
+
121
+ export default ImageStrokePlugin;