diff --git a/src/components/draw-app/DrawProperties.vue b/src/components/draw-app/DrawProperties.vue index e29d9e9..8dc67ad 100644 --- a/src/components/draw-app/DrawProperties.vue +++ b/src/components/draw-app/DrawProperties.vue @@ -1,21 +1,45 @@ diff --git a/src/components/draw-app/properties/CanvasProperty.vue b/src/components/draw-app/properties/CanvasProperty.vue new file mode 100644 index 0000000..e5d4f11 --- /dev/null +++ b/src/components/draw-app/properties/CanvasProperty.vue @@ -0,0 +1,80 @@ + + + diff --git a/src/components/draw-app/properties/LinkProperty.vue b/src/components/draw-app/properties/LinkProperty.vue index 2e4673e..b74805f 100644 --- a/src/components/draw-app/properties/LinkProperty.vue +++ b/src/components/draw-app/properties/LinkProperty.vue @@ -1,65 +1,96 @@ diff --git a/src/components/draw-app/templates/LinkTemplate.vue b/src/components/draw-app/templates/LinkTemplate.vue index 2ba2193..a6b82a1 100644 --- a/src/components/draw-app/templates/LinkTemplate.vue +++ b/src/components/draw-app/templates/LinkTemplate.vue @@ -1,57 +1,96 @@ diff --git a/src/examples/app/graphics/LinkInteraction.ts b/src/examples/app/graphics/LinkInteraction.ts index 477b2c0..dab8c3f 100644 --- a/src/examples/app/graphics/LinkInteraction.ts +++ b/src/examples/app/graphics/LinkInteraction.ts @@ -33,6 +33,12 @@ export class LinkData extends GraphicDataBase implements ILinkData { set curve(v: boolean) { this.data.curve = v; } + get curveNumber(): number { + return this.data.curve ? 1 : 0; + } + set curveNumber(v: number) { + this.data.curve = v === 0 ? false : true; + } get segmentsCount(): number { return this.data.segmentsCount; } diff --git a/src/graphics/iscs-fan/IscsFanDrawAssistant.ts b/src/graphics/iscs-fan/IscsFanDrawAssistant.ts index 014a9fd..71ae98f 100644 --- a/src/graphics/iscs-fan/IscsFanDrawAssistant.ts +++ b/src/graphics/iscs-fan/IscsFanDrawAssistant.ts @@ -15,7 +15,7 @@ export class IscsFanDraw extends GraphicDrawAssistant< constructor(app: JlDrawApp, createData: () => IIscsFanData) { const template = new IscsFanTemplate(); - super(app, template, createData, IscsFan.Type, ''); + super(app, template, createData, IscsFan.Type, '风机'); IscsFanInteraction.init(app); } @@ -41,9 +41,6 @@ export class IscsFanDraw extends GraphicDrawAssistant< this.iscsFan.position.copyFrom(this.toCanvasCoordinates(e.global)); this.createAndStore(false); } - onRightUp(): void { - this.finish(); - } prepareData(data: IIscsFanData): boolean { data.transform = this.iscsFan.saveTransform(); return true; diff --git a/src/graphics/link/LinkDrawAssistant.ts b/src/graphics/link/LinkDrawAssistant.ts index e1c476e..fb798f3 100644 --- a/src/graphics/link/LinkDrawAssistant.ts +++ b/src/graphics/link/LinkDrawAssistant.ts @@ -88,7 +88,7 @@ export class LinkDraw extends GraphicDrawAssistant { this.points = []; this.graphic.clear(); } - onRightUp(): void { + onRightClick(): void { this.createAndStore(true); } onLeftDown(e: FederatedPointerEvent): void { diff --git a/src/jlgraphic/app/JlDrawApp.ts b/src/jlgraphic/app/JlDrawApp.ts index b9b9a42..bcc53c4 100644 --- a/src/jlgraphic/app/JlDrawApp.ts +++ b/src/jlgraphic/app/JlDrawApp.ts @@ -20,13 +20,11 @@ import { InteractionPlugin, KeyListener, ShiftData, - ViewportMovePlugin, } from '../plugins'; import { CommonMouseTool } from '../plugins/CommonMousePlugin'; import { MenuItemOptions } from '../ui/Menu'; import { DOWN, LEFT, RIGHT, UP, recursiveChildren } from '../utils'; import { - CanvasData, GraphicApp, GraphicAppOptions, ICanvasProperties, @@ -40,9 +38,10 @@ export abstract class GraphicDrawAssistant< GT extends GraphicTemplate, GD extends GraphicData > extends AppInteractionPlugin { + readonly __GraphicDrawAssistant = true; app: JlDrawApp; type: string; // 图形对象类型 - description?: string; // 描述 + description: string; // 描述 icon: string; // 界面显示的图标 container: Container = new Container(); graphicTemplate: GT; @@ -64,7 +63,7 @@ export abstract class GraphicDrawAssistant< graphicTemplate: GT, createGraphicData: () => GD, icon: string, - description?: string + description: string ) { super(graphicTemplate.type, graphicApp); this.app = graphicApp; @@ -88,14 +87,16 @@ export abstract class GraphicDrawAssistant< canvas.on('mouseup', this.onLeftUp, this); canvas.on('rightdown', this.onRightDown, this); canvas.on('rightup', this.onRightUp, this); + canvas.on('_rightclick', this.onRightClick, this); + this.app.viewport.wheel({ percent: 0.01, }); this.app.addKeyboardListener(this.escListener); - this.app - .interactionPlugin(ViewportMovePlugin.Name) - .resume(); + this.app.viewport.drag({ + mouseButtons: 'right', + }); } unbind(): void { this.clearCache(); @@ -111,9 +112,7 @@ export abstract class GraphicDrawAssistant< this.app.removeKeyboardListener(this.escListener); - this.app - .interactionPlugin(ViewportMovePlugin.Name) - .pause(); + this.app.viewport.plugins.remove('drag'); } onLeftDown(e: FederatedMouseEvent) {} @@ -125,6 +124,9 @@ export abstract class GraphicDrawAssistant< onLeftUp(e: FederatedMouseEvent) {} onRightDown(e: FederatedMouseEvent) {} onRightUp(e: FederatedMouseEvent) {} + onRightClick(e: FederatedMouseEvent) { + this.finish(); + } /** * 获取下一个id */ @@ -186,13 +188,6 @@ export abstract class GraphicDrawAssistant< } } -/** - * 图形App事件 - */ -export enum DrawAppEvent { - propertiesupdate = 'propertiesupdate', // 图形对象数据变更 -} - export type DrawAssistant = GraphicDrawAssistant; export interface IDrawAppOptions { @@ -226,16 +221,11 @@ export class JlDrawApp extends GraphicApp { drawAssistants: DrawAssistant[] = []; - selectedData: GraphicData | ICanvasProperties | null; - constructor(dom: HTMLElement) { super(dom); this.appendDrawStatesDisplay(); - // 数据更新表单缓存处理 - this.selectedData = null; - this.initSelectedDataUpdateListen(); // 拖拽操作记录 this.appOperationRecord(); // 绑定通用键盘操作 @@ -314,49 +304,6 @@ export class JlDrawApp extends GraphicApp { }); } - /** - * 因图形数据更新和表单数据更新存在Vue代理及记录需求,额外处理数据的缓存 - */ - private initSelectedDataUpdateListen() { - // 画布数据更新 - this.selectedData = new CanvasData(this.canvas.properties); - this.canvas.on('dataupdate', () => { - if (this.selectedGraphics.length === 0) { - this.selectedData = this.canvas.saveData(); - this.emit('propertiesupdate', this.selectedData); - } - }); - this.viewport.on('moved-end', () => { - if (this.selectedGraphics.length === 0) { - this.selectedData = this.canvas.saveData(); - this.emit('propertiesupdate', this.selectedData); - } - }); - // 图形对象数据更新 - const graphicPropertiesUpdate = (g: DisplayObject) => { - if (this.selectedGraphics.length === 1) { - this.selectedData = (g as JlGraphic).saveData(); - this.emit(DrawAppEvent.propertiesupdate, this.selectedData); - } - }; - this.on('graphicselectedchange', (g: DisplayObject, selected) => { - if (selected) { - g.on('repaint', graphicPropertiesUpdate, this); - } else { - g.off('repaint', graphicPropertiesUpdate, this); - } - if (this.selectedGraphics.length === 0) { - this.selectedData = this.canvas.properties.clone(); - } else if (this.selectedGraphics.length === 1) { - const g = this.selectedGraphics[0]; - this.selectedData = g.saveData(); - } else { - this.selectedData = null; - } - this.emit(DrawAppEvent.propertiesupdate, this.selectedData); - }); - } - /** * 绘制状态信息显示 */ @@ -516,34 +463,22 @@ export class JlDrawApp extends GraphicApp { this.opRecord.record(new GraphicDeleteOperation(this, deletes)); } - onSubmit(): void { - if (this.selectedData == null) return; - if (this.selectedGraphics.length === 0) { - const cp = this.selectedData as ICanvasProperties; - this.opRecord.record( - new UpdateCanvasOperation( - this, - this.canvas, - cp, - this.canvas.properties.clone() - ) - ); - this.canvas.update(this.selectedData as ICanvasProperties); - } else if (this.selectedGraphics.length === 1) { - const g = this.selectedGraphics[0]; - if (this.selectedData != null) { - const data = g.saveData(); - g.updateData(this.selectedData as GraphicData); - this.opRecord.record( - new GraphicDataUpdateOperation( - this, - [g], - [data], - [this.selectedData as GraphicData] - ) - ); - } - } + updateCanvasAndRecord(data: ICanvasProperties) { + const old = this.canvas.properties.clone(); + this.canvas.update(data); + const newVal = this.canvas.properties.clone(); + this.opRecord.record( + new UpdateCanvasOperation(this, this.canvas, old, newVal) + ); + } + + updateGraphicAndRecord(g: JlGraphic, data: GraphicData) { + const old = g.saveData(); + g.updateData(data); + const newVal = g.saveData(); + this.opRecord.record( + new GraphicDataUpdateOperation(this, [g], [old], [newVal]) + ); } } @@ -561,21 +496,10 @@ function handleArrowKeyMoveGraphics( if (child.selected && child.draggable) { handler(child); } - // if (child.selected && child.draggable) { - // child.emit( - // 'transformstart', - // GraphicTransformEvent.init(child, 'shift') - // ); - // child.position.x += dp.x; - // child.position.y += dp.y; - // } }); } else { app.selectedGraphics.forEach((g) => { handler(g); - // g.emit('transformstart', GraphicTransformEvent.init(g, 'shift')); - // g.position.x += dp.x; - // g.position.y += dp.y; }); } } diff --git a/src/jlgraphic/app/JlGraphicApp.ts b/src/jlgraphic/app/JlGraphicApp.ts index 73ce594..529f67d 100644 --- a/src/jlgraphic/app/JlGraphicApp.ts +++ b/src/jlgraphic/app/JlGraphicApp.ts @@ -380,8 +380,8 @@ export class GraphicApp extends EventEmitter { this.interactiveTypeOptions = { interactiveGraphicTypeIncludes: [] }; // 创建pixi渲染app this.app = new Application({ - // width: dom.clientWidth, - // height: dom.clientHeight, + width: dom.clientWidth, + height: dom.clientHeight, antialias: true, resizeTo: dom, }); @@ -829,6 +829,7 @@ export class GraphicApp extends EventEmitter { } const worldWidth = this.canvas._properties.width; const worldHeight = this.canvas._properties.height; + this.app.resize(); this.viewport.resize(screenWidth, screenHeight, worldWidth, worldHeight); if (this.viewport.OOB().right) { this.viewport.right = this.viewport.right + 1; diff --git a/src/jlgraphic/global.d.ts b/src/jlgraphic/global.d.ts index 83fed2d..df5fa49 100644 --- a/src/jlgraphic/global.d.ts +++ b/src/jlgraphic/global.d.ts @@ -33,7 +33,7 @@ declare namespace GlobalMixins { // eslint-disable-next-line @typescript-eslint/no-empty-interface interface GraphicAppEvents { - propertiesupdate: [selectedData: GraphicData | CanvasProperties | null]; + // propertiesupdate: [selectedData: GraphicData | CanvasProperties | null]; } interface DisplayObject { diff --git a/src/layouts/DrawLayout.vue b/src/layouts/DrawLayout.vue index d938a7b..8d23ae4 100644 --- a/src/layouts/DrawLayout.vue +++ b/src/layouts/DrawLayout.vue @@ -133,6 +133,7 @@ onMounted(() => { if (dom) { const drawApp = drawStore.initDrawApp(dom); loadDrawDatas(drawApp); + onResize(); } }); diff --git a/src/stores/draw-store.ts b/src/stores/draw-store.ts index 54a9025..9102554 100644 --- a/src/stores/draw-store.ts +++ b/src/stores/draw-store.ts @@ -1,13 +1,44 @@ import { defineStore } from 'pinia'; import { destroyDrawApp, getDrawApp, initDrawApp } from 'src/examples/app'; -import { GraphicDrawAssistant, JlDrawApp } from 'src/jlgraphic'; +import { DrawAssistant, JlCanvas, JlDrawApp, JlGraphic } from 'src/jlgraphic'; export const useDrawStore = defineStore('draw', { state: () => ({ - drawGraphicType: null as string | null, + drawAssistant: null as DrawAssistant | null, + selectedGraphics: null as JlGraphic[] | null, }), getters: { - drawMode: (state) => state.drawGraphicType != null, + drawMode: (state) => state.drawAssistant != null, + drawGraphicType: (state) => state.drawAssistant?.type, + drawGraphicName: (state) => state.drawAssistant?.description, + drawGraphicTemplate: (state) => state.drawAssistant?.graphicTemplate, + + selectedGraphicType: (state) => { + if (state.selectedGraphics) { + if (state.selectedGraphics.length === 1) { + return state.selectedGraphics[0].type; + } + } + }, + selectedObjName: (state) => { + if (state.selectedGraphics) { + if (state.selectedGraphics.length == 0) { + return '画布'; + } else if (state.selectedGraphics.length == 1) { + return state.selectedGraphics[0].type; + } + return '多选'; + } + return ''; + }, + selectedGraphic: (state) => { + if (state.selectedGraphics) { + if (state.selectedGraphics.length === 1) { + return state.selectedGraphics[0]; + } + } + return null; + }, }, actions: { getDrawApp(): JlDrawApp { @@ -17,21 +48,30 @@ export const useDrawStore = defineStore('draw', { } return app; }, + getJlCanvas(): JlCanvas { + return this.getDrawApp().canvas; + }, initDrawApp(dom: HTMLElement) { const app = initDrawApp(dom); app.on('interaction-plugin-resume', (plugin) => { if (plugin.isAppPlugin()) { - if (plugin instanceof GraphicDrawAssistant) { - this.drawGraphicType = plugin.name; + if (Object.hasOwn(plugin, '__GraphicDrawAssistant')) { + this.drawAssistant = plugin as DrawAssistant; } else { - this.drawGraphicType = null; + this.drawAssistant = null; } } }); + app.on('graphicselectedchange', () => { + this.selectedGraphics = app.selectedGraphics; + }); + this.selectedGraphics = []; return app; }, destroy() { - this.drawGraphicType = null; + // console.log('绘制状态清空,绘制应用销毁'); + this.drawAssistant = null; + this.selectedGraphics = null; destroyDrawApp(); }, },