From 258879e5524c8288379d832e6e162fa587cbb08e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A7=A6=E5=B0=91=E5=8D=AB?= Date: Mon, 22 Jul 2024 11:58:21 +0800 Subject: [PATCH] =?UTF-8?q?fix(TS):=20=E4=BF=AE=E5=A4=8D=20TS=20=E8=AF=AD?= =?UTF-8?q?=E6=B3=95=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/core/Instance.ts | 77 ++++++++++++++++++- packages/core/package.json | 3 +- packages/core/plugin/GroupAlignPlugin.ts | 97 ++++-------------------- packages/core/plugin/LockPlugin.ts | 29 ++++--- packages/core/plugin/QrCodePlugin.ts | 6 +- packages/core/plugin/WorkspacePlugin.ts | 10 ++- packages/core/utils/utils.ts | 4 +- tsconfig.json | 3 + typings/editor.d.ts | 2 +- typings/env.d.ts | 23 ------ typings/extends.d.ts | 28 ++++++- 11 files changed, 149 insertions(+), 133 deletions(-) diff --git a/packages/core/Instance.ts b/packages/core/Instance.ts index e891758a..f8370768 100644 --- a/packages/core/Instance.ts +++ b/packages/core/Instance.ts @@ -2,6 +2,81 @@ * @Author: 秦少卫 * @Date: 2024-04-10 15:38:47 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-04-10 15:38:48 + * @LastEditTime: 2024-07-22 11:56:28 * @Description: 类型文件 */ +import Editor from './Editor'; +import DringPlugin from './plugin/DringPlugin'; +import AlignGuidLinePlugin from './plugin/AlignGuidLinePlugin'; +import ControlsPlugin from './plugin/ControlsPlugin'; +import ControlsRotatePlugin from './plugin/ControlsRotatePlugin'; +import CenterAlignPlugin from './plugin/CenterAlignPlugin'; +import LayerPlugin from './plugin/LayerPlugin'; +import CopyPlugin from './plugin/CopyPlugin'; +import MoveHotKeyPlugin from './plugin/MoveHotKeyPlugin'; +import DeleteHotKeyPlugin from './plugin/DeleteHotKeyPlugin'; +import GroupPlugin from './plugin/GroupPlugin'; +import DrawLinePlugin from './plugin/DrawLinePlugin'; +import GroupTextEditorPlugin from './plugin/GroupTextEditorPlugin'; +import GroupAlignPlugin from './plugin/GroupAlignPlugin'; +import WorkspacePlugin from './plugin/WorkspacePlugin'; +import MaskPlugin from './plugin/MaskPlugin'; +import HistoryPlugin from './plugin/HistoryPlugin'; +import FlipPlugin from './plugin/FlipPlugin'; +import RulerPlugin from './plugin/RulerPlugin'; +import MaterialPlugin from './plugin/MaterialPlugin'; +import WaterMarkPlugin from './plugin/WaterMarkPlugin'; +import FontPlugin from './plugin/FontPlugin'; +import PolygonModifyPlugin from './plugin/PolygonModifyPlugin'; +import DrawPolygonPlugin from './plugin/DrawPolygonPlugin'; +import FreeDrawPlugin from './plugin/FreeDrawPlugin'; +import PathTextPlugin from './plugin/PathTextPlugin'; +import PsdPlugin from './plugin/PsdPlugin'; +import SimpleClipImagePlugin from './plugin/SimpleClipImagePlugin'; +import BarCodePlugin from './plugin/BarCodePlugin'; +import QrCodePlugin from './plugin/QrCodePlugin'; +import ImageStroke from './plugin/ImageStroke'; +import ResizePlugin from './plugin/ResizePlugin'; +import LockPlugin from './plugin/LockPlugin'; +import AddBaseTypePlugin from './plugin/AddBaseTypePlugin'; + +const AllEditor = { + Editor, + DringPlugin, + AlignGuidLinePlugin, + ControlsPlugin, + ControlsRotatePlugin, + CenterAlignPlugin, + LayerPlugin, + CopyPlugin, + MoveHotKeyPlugin, + DeleteHotKeyPlugin, + GroupPlugin, + DrawLinePlugin, + GroupTextEditorPlugin, + GroupAlignPlugin, + WorkspacePlugin, + MaskPlugin, + HistoryPlugin, + FlipPlugin, + RulerPlugin, + MaterialPlugin, + WaterMarkPlugin, + FontPlugin, + PolygonModifyPlugin, + DrawPolygonPlugin, + FreeDrawPlugin, + PathTextPlugin, + PsdPlugin, + SimpleClipImagePlugin, + BarCodePlugin, + QrCodePlugin, + ImageStroke, + ResizePlugin, + LockPlugin, + AddBaseTypePlugin, +}; + +declare type KuaituEditor = typeof AllEditor; + +export default KuaituEditor; diff --git a/packages/core/package.json b/packages/core/package.json index a75c669f..87bfb008 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -24,7 +24,8 @@ "license": "ISC", "devDependencies": { "@types/jsdom": "^21.1.6", + "@types/qs": "^6.9.15", "jsdom": "^24.0.0", "vitest": "^1.6.0" } -} \ No newline at end of file +} diff --git a/packages/core/plugin/GroupAlignPlugin.ts b/packages/core/plugin/GroupAlignPlugin.ts index 908215e7..295ab703 100644 --- a/packages/core/plugin/GroupAlignPlugin.ts +++ b/packages/core/plugin/GroupAlignPlugin.ts @@ -2,7 +2,7 @@ * @Author: 秦少卫 * @Date: 2023-06-22 16:19:46 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-04-10 17:33:17 + * @LastEditTime: 2024-07-22 10:21:05 * @Description: 组对齐插件 */ @@ -18,18 +18,6 @@ class GroupAlignPlugin implements IPluginTempl { left() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // const activeObjectLeft = -(activeObject.width / 2); - // activeSelection.forEachObject((item) => { - // item.set({ - // left: activeObjectLeft, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -53,18 +41,6 @@ class GroupAlignPlugin implements IPluginTempl { right() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // const activeObjectLeft = activeObject.width / 2; - // activeSelection.forEachObject((item) => { - // item.set({ - // left: activeObjectLeft - item.width * item.scaleX, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -87,17 +63,6 @@ class GroupAlignPlugin implements IPluginTempl { xcenter() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // activeSelection.forEachObject((item) => { - // item.set({ - // left: 0 - (item.width * item.scaleX) / 2, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -120,17 +85,6 @@ class GroupAlignPlugin implements IPluginTempl { ycenter() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // activeSelection.forEachObject((item) => { - // item.set({ - // top: 0 - (item.height * item.scaleY) / 2, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -153,18 +107,6 @@ class GroupAlignPlugin implements IPluginTempl { top() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // const activeObjectTop = -(activeObject.height / 2); - // activeSelection.forEachObject((item) => { - // item.set({ - // top: activeObjectTop, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -187,18 +129,6 @@ class GroupAlignPlugin implements IPluginTempl { bottom() { const { canvas } = this; - // const activeObject = canvas.getActiveObject(); - // if (activeObject && activeObject.type === 'activeSelection') { - // const activeSelection = activeObject; - // const activeObjectTop = activeObject.height / 2; - // activeSelection.forEachObject((item) => { - // item.set({ - // top: activeObjectTop - item.height * item.scaleY, - // }); - // item.setCoords(); - // canvas.renderAll(); - // }); - // } const activeObject = canvas.getActiveObject(); const selectObjects = canvas.getActiveObjects(); @@ -221,9 +151,9 @@ class GroupAlignPlugin implements IPluginTempl { xequation() { const { canvas } = this; - const activeObject = canvas.getActiveObject(); + const activeObject = canvas.getActiveObject() as fabric.ActiveSelection; // width属性不准确,需要坐标换算 - function getItemWidth(item) { + function getItemWidth(item: fabric.Object) { let x1 = Infinity, x2 = -Infinity; for (const key in item.aCoords) { @@ -241,7 +171,7 @@ class GroupAlignPlugin implements IPluginTempl { function getAllItemHeight() { let count = 0; if (activeObject) { - activeObject.forEachObject((item) => { + activeObject.forEachObject((item: fabric.Object) => { count += getItemWidth(item); }); } @@ -258,7 +188,7 @@ class GroupAlignPlugin implements IPluginTempl { } // 获取当前元素之前所有元素的高度 - function getItemLeft(i) { + function getItemLeft(i: number) { if (i === 0) return 0; let width = 0; if (activeObject) { @@ -275,11 +205,11 @@ class GroupAlignPlugin implements IPluginTempl { activeSelection._objects.sort((a, b) => a.left - b.left); // 平均间距计算 - const itemSpac = spacWidth(); + const itemSpac = spacWidth() as number; // 组原点高度 const yHeight = Number(activeObject.width) / 2; - activeObject.forEachObject((item, i) => { + activeObject.forEachObject((item: fabric.Object, i: number) => { // 获取当前元素之前所有元素的高度 const preHeight = getItemLeft(i); // 顶部距离 间距 * 索引 + 之前元素高度 - 原点高度 @@ -290,7 +220,7 @@ class GroupAlignPlugin implements IPluginTempl { const objecs = canvas.getActiveObjects(); canvas.discardActiveObject(); - objecs.forEach((item) => { + objecs.forEach((item: fabric.Object) => { let x = Infinity; for (const key in item.aCoords) { if (item.aCoords[key].x < x) { @@ -309,9 +239,12 @@ class GroupAlignPlugin implements IPluginTempl { yequation() { const { canvas } = this; - const activeObject = canvas.getActiveObject() || { top: 0, height: 0 }; + const activeObject = (canvas.getActiveObject() as fabric.ActiveSelection) || { + top: 0, + height: 0, + }; // width属性不准确,需要坐标换算 - function getItemHeight(item) { + function getItemHeight(item: fabric.Object) { let y1 = Infinity, y2 = -Infinity; for (const key in item.aCoords) { @@ -327,7 +260,7 @@ class GroupAlignPlugin implements IPluginTempl { // 获取所有元素高度 function getAllItemHeight() { let count = 0; - activeObject.forEachObject((item) => { + activeObject.forEachObject((item: fabric.Object) => { count += getItemHeight(item); }); return count; @@ -340,7 +273,7 @@ class GroupAlignPlugin implements IPluginTempl { } // 获取当前元素之前所有元素的高度 - function getItemTop(i) { + function getItemTop(i: number) { if (i === 0) return 0; let height = 0; for (let index = 0; index < i; index++) { diff --git a/packages/core/plugin/LockPlugin.ts b/packages/core/plugin/LockPlugin.ts index 6ba1e2f6..09029b6f 100644 --- a/packages/core/plugin/LockPlugin.ts +++ b/packages/core/plugin/LockPlugin.ts @@ -2,26 +2,25 @@ * @Author: 秦少卫 * @Date: 2024-07-04 14:27:05 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-07-06 17:49:01 + * @LastEditTime: 2024-07-22 10:11:29 * @Description: 锁定文件 */ import { fabric } from 'fabric'; import type Editor from '../Editor'; import { SelectMode } from '../eventType'; +enum ItypeKey { + lockMovementX = 'lockMovementX', + lockMovementY = 'lockMovementY', + lockRotation = 'lockRotation', + lockScalingX = 'lockScalingX', + lockScalingY = 'lockScalingY', +} + export default class LockPlugin implements IPluginTempl { static pluginName = 'LockPlugin'; static apis = ['lock', 'unLock']; - lockAttrs: string[]; - constructor(public canvas: fabric.Canvas, public editor: Editor) { - this.lockAttrs = [ - 'lockMovementX', - 'lockMovementY', - 'lockRotation', - 'lockScalingX', - 'lockScalingY', - ]; - } + constructor(public canvas: fabric.Canvas, public editor: Editor) {} hookImportAfter() { this.canvas.forEachObject((obj) => { @@ -34,13 +33,13 @@ export default class LockPlugin implements IPluginTempl { } lock() { - const activeObject = this.canvas.getActiveObject(); + const activeObject = this.canvas.getActiveObject() as fabric.Object; if (activeObject) { activeObject.hasControls = false; activeObject.selectable = false; activeObject.evented = false; // 修改默认属性 - this.lockAttrs.forEach((key) => { + Object.values(ItypeKey).forEach((key: ItypeKey) => { activeObject[key] = true; }); this.canvas.discardActiveObject().renderAll(); @@ -48,13 +47,13 @@ export default class LockPlugin implements IPluginTempl { } unLock() { - const activeObject = this.canvas.getActiveObject(); + const activeObject = this.canvas.getActiveObject() as fabric.Object; if (activeObject) { activeObject.hasControls = true; activeObject.selectable = true; activeObject.evented = true; // 修改默认属性 - this.lockAttrs.forEach((key) => { + Object.values(ItypeKey).forEach((key: ItypeKey) => { activeObject[key] = false; }); this.canvas.discardActiveObject().renderAll(); diff --git a/packages/core/plugin/QrCodePlugin.ts b/packages/core/plugin/QrCodePlugin.ts index bce2f97b..6da4722e 100644 --- a/packages/core/plugin/QrCodePlugin.ts +++ b/packages/core/plugin/QrCodePlugin.ts @@ -2,7 +2,7 @@ * @Author: 秦少卫 * @Date: 2024-06-06 19:58:26 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-06-15 09:34:36 + * @LastEditTime: 2024-07-22 10:26:59 * @Description: 二维码生成工具 */ @@ -55,11 +55,11 @@ class QrCodePlugin implements IPluginTempl { } } - async _getBase64Str(options: any) { + async _getBase64Str(options: any): Promise { const qrCode = new QRCodeStyling(options); const blob = await qrCode.getRawData('png'); if (!blob) return ''; - const base64Str = await blobToBase64(blob); + const base64Str = (await blobToBase64(blob)) as string; return base64Str || ''; } diff --git a/packages/core/plugin/WorkspacePlugin.ts b/packages/core/plugin/WorkspacePlugin.ts index 08e2dc24..5087f917 100644 --- a/packages/core/plugin/WorkspacePlugin.ts +++ b/packages/core/plugin/WorkspacePlugin.ts @@ -2,7 +2,7 @@ * @Author: 秦少卫 * @Date: 2023-06-27 12:26:41 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-06-30 20:00:37 + * @LastEditTime: 2024-07-22 10:30:53 * @Description: 画布区域插件 */ @@ -59,8 +59,10 @@ class WorkspacePlugin implements IPluginTempl { workspace.set('selectable', false); workspace.set('hasControls', false); workspace.set('evented', false); - this.setSize(workspace.width, workspace.height); - this.editor.emit('sizeChange', workspace.width, workspace.height); + if (workspace.width && workspace.height) { + this.setSize(workspace.width, workspace.height); + this.editor.emit('sizeChange', workspace.width, workspace.height); + } } resolve(''); }); @@ -134,7 +136,7 @@ class WorkspacePlugin implements IPluginTempl { this.resizeObserver.observe(this.workspaceEl); } - setSize(width: number | undefined, height: number | undefined) { + setSize(width: number, height: number) { this._initBackground(); this.option.width = width; this.option.height = height; diff --git a/packages/core/utils/utils.ts b/packages/core/utils/utils.ts index fc4d63e4..aa778ace 100644 --- a/packages/core/utils/utils.ts +++ b/packages/core/utils/utils.ts @@ -2,7 +2,7 @@ * @Author: 秦少卫 * @Date: 2022-09-05 22:21:55 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-06-15 10:34:55 + * @LastEditTime: 2024-07-22 10:24:53 * @Description: 工具文件 */ import { v4 as uuid } from 'uuid'; @@ -130,7 +130,7 @@ export function blobToBase64(blob: Blob) { return new Promise((resolve) => { const reader = new FileReader(); reader.addEventListener('load', () => { - resolve(reader.result); + resolve(reader.result as string); }); reader.readAsDataURL(blob); }); diff --git a/tsconfig.json b/tsconfig.json index 1531db9a..be867bbe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "target": "esnext", + "outDir": "build", "useDefineForClassFields": true, "allowSyntheticDefaultImports": true, "module": "esnext", @@ -26,11 +27,13 @@ }, "files": [], "include": [ + "packages/**/*.ts", "src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "typings/**/*.ts", + "typings/**/*.d.ts", "src/hooks/useMaterial.js", ], "references": [ diff --git a/typings/editor.d.ts b/typings/editor.d.ts index 5555897b..986ec6c3 100644 --- a/typings/editor.d.ts +++ b/typings/editor.d.ts @@ -3,7 +3,7 @@ * @Author: 秦少卫 * @Date: 2023-05-13 18:53:44 * @LastEditors: 秦少卫 - * @LastEditTime: 2024-06-07 19:48:01 + * @LastEditTime: 2024-07-22 10:32:18 * @Description: file content */ diff --git a/typings/env.d.ts b/typings/env.d.ts index 504e329e..d970c850 100644 --- a/typings/env.d.ts +++ b/typings/env.d.ts @@ -1,31 +1,8 @@ /// -// import { Object } from 'fabric/fabric-impl'; - declare module '*.vue' { import type { DefineComponent } from 'vue'; // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types const component: DefineComponent<{}, {}, any>; export default component; } - -declare global { - declare module 'fabric/fabric-impl' {} -} - -export as namespace vfe; -declare module 'vfe' { - export as namespace vfe; - export interface ICanvas extends fabric.Canvas { - c: fabric.Canvas; - editor: Editor; - } -} - -import Editor from '@kuaitu/core'; - -declare global { - interface Window { - editor: Editor; - } -} diff --git a/typings/extends.d.ts b/typings/extends.d.ts index 698157d6..4f415bb5 100644 --- a/typings/extends.d.ts +++ b/typings/extends.d.ts @@ -7,7 +7,7 @@ declare namespace fabric { historyProcessing: boolean; _currentTransform: unknown; extraProps: any; - clearHistory(boolean): void; + clearHistory(boolean?): void; clearUndo(): void; _historyNext(): void; _historyInit(): void; @@ -20,6 +20,32 @@ declare namespace fabric { rotate: number; } + export interface Image { + extensionType?: string; + extension: any; + } + + export interface Object { + extensionType?: string; + extension: any; + type: string; + height: number; + top: number; + left: number; + lockMovementX: boolean; + lockMovementY: boolean; + lockRotation: boolean; + lockScalingX: boolean; + lockScalingY: boolean; + forEachObject?: ICollection.forEachObject; + fontFamily?: string; + _objects?: ICollection.Object[]; + aCoords?: any; + [string]?: any; + } + export interface Group { + _objects: ICollection.Object[]; + } export interface IObjectOptions { /** * 标识