diff --git a/README.md b/README.md index ce78943..05ea352 100644 --- a/README.md +++ b/README.md @@ -24,11 +24,10 @@ - 元素拖拽、组合、缩放、层级调整、对齐等操作。 - 图片素材插入、替换、裁剪,图片容器等功能。 - SVG 素材颜色、透明度编辑,文字花字组合。 -- 画布自定义尺寸、滚轮缩放、自适应画布 +- 支持图层管理、多画板管理、自适应画布。 - 吸附对齐、辅助引导线、标尺功能。 - 键盘快捷键、右键菜单快捷操作,复制删除等常用操作。 - 风格二维码编辑,支持单色、渐变、自定义 logo 等。 -- 图层操作,支持拖拽变更层级。 - 颜色调色板,原生级取色器颜色吸管(Chrome)。 ## 快速开始 diff --git a/package-lock.json b/package-lock.json index 7eb36fe..4669e20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,8 @@ "element-plus": "^2.6.3", "fontfaceobserver": "^2.1.0", "html2canvas": "^1.4.1", + "immer": "^10.0.4", + "microdiff": "^1.4.0", "mitt": "^3.0.1", "moveable": "^0.26.0", "moveable-helper": "^0.4.0", @@ -2674,6 +2676,15 @@ "node": ">=0.10.0" } }, + "node_modules/immer": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.4.tgz", + "integrity": "sha512-cuBuGK40P/sk5IzWa9QPUaAdvPHjkk1c+xYsd9oZw+YQQEV+10G0P5uMpGctZZKnyQ+ibRO08bD25nWLmYi2pw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -2991,6 +3002,11 @@ "node": ">= 8" } }, + "node_modules/microdiff": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/microdiff/-/microdiff-1.4.0.tgz", + "integrity": "sha512-OBKBOa1VBznvLPb/3ljeJaENVe0fO0lnWl77lR4vhPlQD71UpjEoRV5P0KdQkcjbFlBu1Oy2mEUBMU3wxcBAGg==" + }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", diff --git a/package.json b/package.json index a18ed3a..9c6a202 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,8 @@ "element-plus": "^2.6.3", "fontfaceobserver": "^2.1.0", "html2canvas": "^1.4.1", + "immer": "^10.0.4", + "microdiff": "^1.4.0", "mitt": "^3.0.1", "moveable": "^0.26.0", "moveable-helper": "^0.4.0", diff --git a/src/common/hooks/dragHelper.ts b/src/common/hooks/dragHelper.ts index 877a648..7c82d1c 100644 --- a/src/common/hooks/dragHelper.ts +++ b/src/common/hooks/dragHelper.ts @@ -3,13 +3,11 @@ * @Date: 2023-07-10 14:58:48 * @Description: 拖拽优化 * @LastEditors: ShawnPhang - * @LastEditTime: 2023-11-22 18:11:15 + * @LastEditTime: 2024-04-18 16:17:36 */ import { useControlStore, useWidgetStore } from "@/store" -// import store from '@/store' - type TInitial = { offsetX: number offsetY: number diff --git a/src/common/hooks/history.ts b/src/common/hooks/history.ts new file mode 100644 index 0000000..0e3c060 --- /dev/null +++ b/src/common/hooks/history.ts @@ -0,0 +1,76 @@ +/* + * @Author: ShawnPhang + * @Date: 2024-04-18 16:10:07 + * @Description: 事件自动注册,WebWorker处理差分补丁,双栈记录 + * 事件自动注册的逻辑是鼠标事件黑名单,键盘事件白名单,跑一段时间看看实际情况如何 + * 差分补丁目前已知的问题是,对于预期以外的影响状态树的修改,现在都会写进历史记录,看起来就像多了一段毫无变化的历史栈一样 + * 例如图层的 left 在修改后可能为 12.6262638 但为了输入框中显示友好,在 input 组件中将自动格式化为 12.63,这个逻辑以前不会有问题,现在则不能这么做了 + * @LastEditors: ShawnPhang + * @LastEditTime: 2024-04-18 18:40:27 + */ +import { onMounted } from 'vue' +import WebWorker from '@/utils/plugins/webWorker' +import { useHistoryStore, useWidgetStore } from '@/store' + +const blackClass: string[] = ['operation-item', 'icon-undo', 'icon-redo'] +const whiteKey: string[] = ['ArrowLeft', 'ArrowDown', 'ArrowRight', 'ArrowUp', 'Backspace'] + +const historyStore = useHistoryStore() +const widgetStore = useWidgetStore() +const historyWorker = new WebWorker('history') +let processing = false +let historyTimer: any = null + +function noPutHistory(target: any) { + const classList = Array.from(target.classList) + return classList.filter((v: any) => blackClass.includes(v)).length > 0 +} + +export default () => { + historyWorker.start(null, (changes: any) => { + changes.patches.length > 0 && historyStore.changeHistory(changes) + processing = false + }) + onMounted(() => { + document.addEventListener( + 'mousedown', + (e: any) => { + if (noPutHistory(e.target)) return + historyWorker.send(!processing ? { op: 'diff', data: JSON.stringify(widgetStore.dLayouts) } : null) + processing = true + }, + false, + ) + document.addEventListener( + 'mouseup', + (e: any) => { + if (noPutHistory(e.target)) return + clearTimeout(historyTimer) + historyTimer = setTimeout(() => { + historyWorker.send({ op: 'done', data: JSON.stringify(widgetStore.dLayouts) }) + }, 150) + }, + false, + ) + document.addEventListener( + 'keydown', + (e) => { + if (!whiteKey.includes(e.key)) return + historyWorker.send(!processing ? { op: 'diff', data: JSON.stringify(widgetStore.dLayouts) } : null) + processing = true + }, + false, + ) + document.addEventListener( + 'keyup', + (e) => { + if (!whiteKey.includes(e.key)) return + clearTimeout(historyTimer) + historyTimer = setTimeout(() => { + historyWorker.send({ op: 'done', data: JSON.stringify(widgetStore.dLayouts) }) + }, 150) + }, + false, + ) + }) +} diff --git a/src/common/hooks/mapGetters.ts b/src/common/hooks/mapGetters.ts deleted file mode 100644 index 4748b33..0000000 --- a/src/common/hooks/mapGetters.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * @Author: Jeremy-Yu - * @Date: 2024-02-14 14:58:48 - * @Description: 同意处理vue3 Mapgetters 已废弃 - * @LastEditors: ShawnPhang - * @LastEditTime: 2023-11-22 18:11:15 - */ - -// import { ComputedRef, computed } from 'vue' - - -// export function useSetupMapGetters(strList: T[]) { -// const mapData: Partial<{[x in T]: ComputedRef}> = {} -// const getters = useStore().getters - -// strList.forEach(val => { -// mapData[val] = computed(() => getters[val]) -// }) - -// return mapData as {[x in T]: ComputedRef} -// } diff --git a/src/components/modules/layout/multipleBoards/multipleBoards.vue b/src/components/modules/layout/multipleBoards/multipleBoards.vue index 7b02532..77e415f 100644 --- a/src/components/modules/layout/multipleBoards/multipleBoards.vue +++ b/src/components/modules/layout/multipleBoards/multipleBoards.vue @@ -3,7 +3,7 @@ * @Date: 2024-04-11 17:27:58 * @Description: 多画板操作界面 * @LastEditors: ShawnPhang - * @LastEditTime: 2024-04-17 11:53:48 + * @LastEditTime: 2024-04-18 17:12:34 -->