From 2d705a7108e180df229541a566f5be13d0a1ce34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=B1=E6=B8=8A=E5=8F=A3=E9=A6=99=E7=B3=96?= <5183454+yuanjianming666@user.noreply.gitee.com> Date: Tue, 5 Nov 2024 14:52:07 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=E6=93=A6=E9=99=A4?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/plugin/EarsePlugin.ts | 62 +++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 packages/core/plugin/EarsePlugin.ts diff --git a/packages/core/plugin/EarsePlugin.ts b/packages/core/plugin/EarsePlugin.ts new file mode 100644 index 00000000..bb2630e8 --- /dev/null +++ b/packages/core/plugin/EarsePlugin.ts @@ -0,0 +1,62 @@ +import { fabric } from 'fabric'; +import type { IEditor, IPluginTempl } from '@kuaitu/core'; +import 'fabric-eraser-brush'; +type IPlugin = Pick; + +declare module '@kuaitu/core' { + type IEditor = IPlugin; +} + +class EarsePlugin implements IPluginTempl { + static pluginName = 'EarsePlugin'; + static apis = ['erase', 'undoErasing', 'select']; + public hotkeys: string[] = ['e', 'q', 's']; + static events = ['modeEvent']; + constructor( + public canvas: fabric.Canvas, + public editor: IEditor & { emit: (eventName: string, data: any) => void } + ) { + this._init(); + } + + _init() { + const workspace = this.editor.getWorkspase(); + workspace.set({ erasable: false } as any); + this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas); + this.canvas.freeDrawingBrush.width = 20; // 画笔宽度 + this.canvas.requestRenderAll(); + } + select() { + this.canvas.isDrawingMode = false; + this.editor.emit('modeEvent', 'select'); + } + erase() { + this.canvas.isDrawingMode = true; + this.canvas.freeDrawingBrush.inverted = false; // 复原擦除 + this.editor.emit('modeEvent', 'earse'); + } + undoErasing() { + this.canvas.isDrawingMode = true; + this.canvas.freeDrawingBrush.inverted = true; // 复原擦除 + this.editor.emit('modeEvent', 'undoEarse'); + } + // 快捷键扩展回调 + hotkeyEvent(eventName: string, e: KeyboardEvent) { + // 擦除功能 + if (eventName === 'e' && e.type === 'keydown') { + this.erase(); + } else if (eventName === 'q' && e.type === 'keydown') { + //复原功能 + this.undoErasing(); + } else if (eventName === 's' && e.type === 'keydown') { + // 框选功能 + this.select(); + } + } + + destroy() { + console.log('pluginDestroy'); + } +} + +export default EarsePlugin; From 84c8920e8aa67c778e4b5d29b7daa8f3d0742fe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=B1=E6=B8=8A=E5=8F=A3=E9=A6=99=E7=B3=96?= <5183454+yuanjianming666@user.noreply.gitee.com> Date: Tue, 5 Nov 2024 15:17:35 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=93=A6?= =?UTF-8?q?=E9=99=A4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc-auto-import.json | 7 + package.json | 1 + packages/core/Instance.ts | 2 + packages/core/ServersPlugin.ts | 2 + packages/core/index.ts | 2 + packages/core/plugin/AddBaseTypePlugin.ts | 3 +- packages/core/plugin/EarsePlugin.ts | 7 +- src/components/earse.vue | 177 ++++++++++++++++++++++ src/components/selectMode.vue | 47 ++++++ src/views/home/index.vue | 16 +- vite.config.ts | 1 + 11 files changed, 259 insertions(+), 6 deletions(-) create mode 100644 src/components/earse.vue create mode 100644 src/components/selectMode.vue diff --git a/.eslintrc-auto-import.json b/.eslintrc-auto-import.json index 61875e3b..a9f62599 100644 --- a/.eslintrc-auto-import.json +++ b/.eslintrc-auto-import.json @@ -3,11 +3,14 @@ "Component": true, "ComponentPublicInstance": true, "ComputedRef": true, + "DirectiveBinding": true, "EffectScope": true, "ExtractDefaultPropTypes": true, "ExtractPropTypes": true, "ExtractPublicPropTypes": true, "InjectionKey": true, + "MaybeRef": true, + "MaybeRefOrGetter": true, "PropType": true, "Ref": true, "VNode": true, @@ -41,6 +44,7 @@ "onServerPrefetch": true, "onUnmounted": true, "onUpdated": true, + "onWatcherCleanup": true, "provide": true, "reactive": true, "readonly": true, @@ -58,7 +62,10 @@ "useAttrs": true, "useCssModule": true, "useCssVars": true, + "useId": true, + "useModel": true, "useSlots": true, + "useTemplateRef": true, "watch": true, "watchEffect": true, "watchPostEffect": true, diff --git a/package.json b/package.json index d51c0b93..9354c63d 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "dayjs": "^1.11.11", "events": "^3.3.0", "fabric": "^5.3.0", + "fabric-eraser-brush": "^1.0.1", "fontfaceobserver": "^2.1.0", "lodash-es": "^4.17.21", "number-precision": "^1.6.0", diff --git a/packages/core/Instance.ts b/packages/core/Instance.ts index f8370768..42cf32c4 100644 --- a/packages/core/Instance.ts +++ b/packages/core/Instance.ts @@ -39,6 +39,7 @@ import ImageStroke from './plugin/ImageStroke'; import ResizePlugin from './plugin/ResizePlugin'; import LockPlugin from './plugin/LockPlugin'; import AddBaseTypePlugin from './plugin/AddBaseTypePlugin'; +import EarsePlugin from './plugin/EarsePlugin'; const AllEditor = { Editor, @@ -75,6 +76,7 @@ const AllEditor = { ResizePlugin, LockPlugin, AddBaseTypePlugin, + EarsePlugin, }; declare type KuaituEditor = typeof AllEditor; diff --git a/packages/core/ServersPlugin.ts b/packages/core/ServersPlugin.ts index 030e6c8d..87985643 100644 --- a/packages/core/ServersPlugin.ts +++ b/packages/core/ServersPlugin.ts @@ -134,6 +134,8 @@ class ServersPlugin implements IPluginTempl { textPaths.push({ id: item.id, path: item.path }); item.path = null; } + // 设置erasable属性 + item.erasable = false; }); // hookTransform遍历 diff --git a/packages/core/index.ts b/packages/core/index.ts index c0ef129c..4d1cd3bf 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -39,6 +39,8 @@ export { default as ImageStroke } from './plugin/ImageStroke'; export { default as ResizePlugin } from './plugin/ResizePlugin'; export { default as LockPlugin } from './plugin/LockPlugin'; export { default as AddBaseTypePlugin } from './plugin/AddBaseTypePlugin'; +export { default as EarsePlugin } from './plugin/EarsePlugin'; + import EventType from './eventType'; import Utils from './utils/utils'; import CustomRect from './objects/CustomRect'; diff --git a/packages/core/plugin/AddBaseTypePlugin.ts b/packages/core/plugin/AddBaseTypePlugin.ts index 6b933c7f..77bd10e2 100644 --- a/packages/core/plugin/AddBaseTypePlugin.ts +++ b/packages/core/plugin/AddBaseTypePlugin.ts @@ -36,7 +36,8 @@ export default class AddBaseTypePlugin implements IPluginTempl { const { event = false, scale = false, center = true } = optons || {}; item.set({ id: uuid(), - }); + erasable: false, + } as any); scale && this._toScale(item); event && this._toEvent(item, event); this.canvas.add(item); diff --git a/packages/core/plugin/EarsePlugin.ts b/packages/core/plugin/EarsePlugin.ts index bb2630e8..65d975d6 100644 --- a/packages/core/plugin/EarsePlugin.ts +++ b/packages/core/plugin/EarsePlugin.ts @@ -24,33 +24,32 @@ class EarsePlugin implements IPluginTempl { workspace.set({ erasable: false } as any); this.canvas.freeDrawingBrush = new fabric.EraserBrush(this.canvas); this.canvas.freeDrawingBrush.width = 20; // 画笔宽度 - this.canvas.requestRenderAll(); } select() { this.canvas.isDrawingMode = false; - this.editor.emit('modeEvent', 'select'); } erase() { this.canvas.isDrawingMode = true; this.canvas.freeDrawingBrush.inverted = false; // 复原擦除 - this.editor.emit('modeEvent', 'earse'); } undoErasing() { this.canvas.isDrawingMode = true; this.canvas.freeDrawingBrush.inverted = true; // 复原擦除 - this.editor.emit('modeEvent', 'undoEarse'); } // 快捷键扩展回调 hotkeyEvent(eventName: string, e: KeyboardEvent) { // 擦除功能 if (eventName === 'e' && e.type === 'keydown') { this.erase(); + this.editor.emit('modeEvent', 'earse'); } else if (eventName === 'q' && e.type === 'keydown') { //复原功能 this.undoErasing(); + this.editor.emit('modeEvent', 'undoEarse'); } else if (eventName === 's' && e.type === 'keydown') { // 框选功能 this.select(); + this.editor.emit('modeEvent', 'select'); } } diff --git a/src/components/earse.vue b/src/components/earse.vue new file mode 100644 index 00000000..71d89b87 --- /dev/null +++ b/src/components/earse.vue @@ -0,0 +1,177 @@ + + + + + diff --git a/src/components/selectMode.vue b/src/components/selectMode.vue new file mode 100644 index 00000000..427e0330 --- /dev/null +++ b/src/components/selectMode.vue @@ -0,0 +1,47 @@ + + + diff --git a/src/views/home/index.vue b/src/views/home/index.vue index b53039c2..6b2573f1 100644 --- a/src/views/home/index.vue +++ b/src/views/home/index.vue @@ -16,6 +16,7 @@ + @@ -42,6 +43,7 @@ + @@ -129,6 +131,7 @@ + @@ -201,6 +204,7 @@ import dele from '@/components/del.vue'; import waterMark from '@/components/waterMark.vue'; import login from '@/components/login'; import admin from '@/components/admin'; +import selectMode from '@/components/selectMode.vue'; // 左侧组件 import importTmpl from '@/components/importTmpl.vue'; import fontStyle from '@/components/fontStyle.vue'; @@ -227,6 +231,7 @@ import attributeTextFloat from '@/components/attributeTextFloat.vue'; import attributeColor from '@/components/attributeColor.vue'; import attributeBarcode from '@/components/attributeBarcode.vue'; import attributeQrCode from '@/components/attributeQrCode.vue'; +import earse from '@/components/earse.vue'; // 功能组件 import { fabric } from 'fabric'; @@ -274,6 +279,7 @@ import Editor, { LockPlugin, AddBaseTypePlugin, MaskPlugin, + EarsePlugin, } from '@kuaitu/core'; import Edit from '@/components/edit.vue'; import ClipImage from '@/components/clipImage.vue'; @@ -392,7 +398,8 @@ onMounted(() => { .use(ResizePlugin) .use(LockPlugin) .use(AddBaseTypePlugin) - .use(MaskPlugin); + .use(MaskPlugin) + .use(EarsePlugin); state.show = true; // 默认打开标尺 @@ -451,6 +458,7 @@ provide('canvasEditor', canvasEditor); width: 380px; } } + // 右侧容器 .right-bar { width: 304px; @@ -507,6 +515,7 @@ provide('canvasEditor', canvasEditor); border-radius: 4px; display: flex; align-items: center; + .ivu-tooltip { text-align: center; flex: 1; @@ -539,11 +548,13 @@ provide('canvasEditor', canvasEditor); .right { display: flex; align-items: center; + img { display: block; margin-right: 10px; } } + .home, .ivu-layout { height: 100vh; @@ -556,6 +567,7 @@ provide('canvasEditor', canvasEditor); .canvas-box { position: relative; } + // 画布内阴影 .inside-shadow { position: absolute; @@ -591,10 +603,12 @@ provide('canvasEditor', canvasEditor); .ivu-menu-light.ivu-menu-vertical .ivu-menu-item-active:not(.ivu-menu-submenu) { background: none; } + // 标尺 .switch { margin-right: 10px; } + // 网格背景 .design-stage-grid { --offsetX: 0px; diff --git a/vite.config.ts b/vite.config.ts index c20d4e98..03c38585 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -36,6 +36,7 @@ const config = ({ mode }) => { vueSetupExtend(), // 增加下面的配置项,这样在运行时就能检查eslint规范 eslintPlugin({ + fix: true, include: ['src/**/*.js', 'src/**/*.vue', 'src/*.js', 'src/*.vue'], }), vueJsx({