实现图形模板表单、画布表单、link表单及drawStore相关功能

This commit is contained in:
walker 2023-05-21 18:04:39 +08:00
parent 7ece0182b9
commit 39d68c8fe0
12 changed files with 339 additions and 196 deletions

View File

@ -1,21 +1,45 @@
<template> <template>
<div v-if="drawStore.drawMode" class="q-pa-md"> <!-- 绘制图形模板属性 -->
<template v-if="drawStore.drawGraphicType === Link.Type"> <div v-if="drawStore.drawMode">
<link-template></link-template> <q-card flat>
</template> <q-card-section>
<div class="text-h6">{{ drawStore.drawGraphicName + ' 模板' }}</div>
</q-card-section>
<q-separator inset></q-separator>
<q-card-section>
<template v-if="drawStore.drawGraphicType === Link.Type">
<link-template></link-template>
</template>
</q-card-section>
</q-card>
</div>
<!-- 画布或图形对象属性 -->
<div v-else-if="drawStore.selectedGraphics !== null">
<q-card flat>
<q-card-section>
<div class="text-h6">{{ drawStore.selectedObjName + ' 属性' }}</div>
</q-card-section>
<q-separator inset></q-separator>
<template v-if="drawStore.selectedGraphics.length === 0">
<q-card-section>
<canvas-property></canvas-property>
</q-card-section>
</template>
<template v-else-if="drawStore.selectedGraphics.length === 1">
<q-card-section v-if="drawStore.selectedGraphicType === Link.Type">
<link-property></link-property>
</q-card-section>
</template>
</q-card>
</div> </div>
<div v-else class="q-pa-md"></div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import LinkTemplate from './templates/LinkTemplate.vue'; import LinkTemplate from './templates/LinkTemplate.vue';
import CanvasProperty from './properties/CanvasProperty.vue';
import LinkProperty from './properties/LinkProperty.vue';
import { Link } from 'src/graphics/link/Link'; import { Link } from 'src/graphics/link/Link';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, ref } from 'vue';
const drawStore = useDrawStore(); const drawStore = useDrawStore();
onMounted(() => {
console.log('绘制属性组件mounted');
});
</script> </script>

View File

@ -0,0 +1,80 @@
<template>
<q-form>
<q-input
outlined
v-model.number="canvas.width"
@blur="onUpdate"
label="画布宽 *"
lazy-rules
:rules="[(val) => (val && val > 0) || '画布宽必须大于0']"
/>
<q-input
outlined
type="number"
v-model.number="canvas.height"
@blur="onUpdate"
label="画布高 *"
lazy-rules
:rules="[(val) => val > 0 || '画布高必须大于0']"
/>
<q-input
outlined
v-model="canvas.backgroundColor"
@blur="onUpdate"
label="画布背景色 *"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '画布背景色必须设置']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
:model-value="canvas.backgroundColor"
@change="
(val) => {
canvas.backgroundColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
</q-form>
</template>
<script setup lang="ts">
import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, onUnmounted, reactive } from 'vue';
const drawStore = useDrawStore();
const canvas = reactive({
width: 1920,
height: 1080,
backgroundColor: '#ffffff',
});
onMounted(() => {
console.log('画布属性表单mounted');
const jc = drawStore.getJlCanvas();
canvas.width = jc.properties.width;
canvas.height = jc.properties.height;
canvas.backgroundColor = jc.properties.backgroundColor;
});
onUnmounted(() => {
console.log('画布属性表单unmounted');
});
function onUpdate() {
console.log('画布属性更新');
const app = drawStore.getDrawApp();
app.updateCanvasAndRecord({
...canvas,
viewportTransform: app.canvas.properties.viewportTransform,
});
}
</script>

View File

@ -1,65 +1,96 @@
<template> <template>
<q-form @submit="onSubmit" @reset="onReset" class="q-gutter-md"> <q-form>
<q-input outlined readonly v-model="linkModel.id" label="id" :rules="[]" />
<q-input <q-input
filled outlined
v-model="name" v-model.number="linkModel.lineWidth"
label="Your name *"
hint="Name and surname"
lazy-rules
:rules="[(val) => (val && val.length > 0) || 'Please type something']"
/>
<q-input
filled
type="number" type="number"
v-model="age" @blur="onUpdate"
label="Your age *" label="线宽"
lazy-rules lazy-rules
:rules="[ :rules="[(val) => (val && val > 0) || '画布宽必须大于0']"
(val) => (val !== null && val !== '') || 'Please type your age',
(val) => (val > 0 && val < 100) || 'Please type a real age',
]"
/> />
<q-toggle v-model="accept" label="I accept the license and terms" /> <q-input
outlined
v-model="linkModel.lineColor"
@blur="onUpdate"
label="线色"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '线色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="linkModel.lineColor"
@change="
(val) => {
linkModel.lineColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<div> <!-- <q-btn-toggle
<q-btn label="Submit" type="submit" color="primary" /> disable
<q-btn label="Reset" type="reset" color="primary" flat class="q-ml-sm" /> v-model="linkModel.curve"
</div> :options="[
{ label: '直线', value: false },
{ label: '曲线', value: true },
]"
/> -->
<q-input
v-if="linkModel.curve"
outlined
v-model.number="linkModel.segmentsCount"
type="number"
@blur="onUpdate"
label="曲线分段数量"
lazy-rules
:rules="[(val) => (val && val > 0) || '曲线分段数量必须大于0']"
/>
</q-form> </q-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useQuasar } from 'quasar'; import { LinkData } from 'src/examples/app/graphics/LinkInteraction';
import { ref } from 'vue'; import { Link } from 'src/graphics/link/Link';
const $q = useQuasar(); import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, watch } from 'vue';
const name = ref(null); const drawStore = useDrawStore();
const age = ref(null); const linkModel = reactive(new LinkData());
const accept = ref(false);
function onSubmit() { drawStore.$subscribe;
if (accept.value !== true) { watch(
$q.notify({ () => drawStore.selectedGraphic,
color: 'red-5', (val) => {
textColor: 'white', if (val && val.type == Link.Type) {
icon: 'warning', // console.log('link');
message: 'You need to accept the license and terms first', linkModel.copyFrom(val.saveData() as LinkData);
}); }
} else { }
$q.notify({ );
color: 'green-4',
textColor: 'white', onMounted(() => {
icon: 'cloud_done', // console.log('link mounted');
message: 'Submitted', const link = drawStore.selectedGraphic as Link;
}); if (link) {
linkModel.copyFrom(link.saveData());
}
});
function onUpdate() {
console.log('link 属性更新');
const link = drawStore.selectedGraphic as Link;
if (link) {
drawStore.getDrawApp().updateGraphicAndRecord(link, linkModel);
} }
} }
function onReset() {
name.value = null;
age.value = null;
accept.value = false;
}
</script> </script>

View File

@ -1,57 +1,96 @@
<template> <template>
<q-form class="q-gutter-md"> <q-form>
<q-input <q-input
filled outlined
v-model.number="template.lineWidth" v-model.number="template.lineWidth"
type="number" type="number"
@blur="onUpdate"
label="线宽 *" label="线宽 *"
lazy-rules lazy-rules
:rules="[(val) => (val && val.length > 0) || '线宽必须大于0']" :rules="[(val) => (val && val > 0) || '线宽必须大于0']"
/> />
<q-input <q-input
filled outlined
v-model="template.lineColor" v-model="template.lineColor"
@blur="onUpdate"
label="线色 *" label="线色 *"
lazy-rules lazy-rules
:rules="[(val) => (val && val.length > 0) || '线色必须设置']" :rules="[(val) => (val && val.length > 0) || '线色不能为空']"
> >
<template v-slot:append> <template v-slot:append>
<q-icon name="colorize" class="cursor-pointer"> <q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale"> <q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color v-model="template.lineColor" /> <q-color
v-model="template.lineColor"
@change="
(val) => {
template.lineColor = val;
onUpdate();
}
"
/>
</q-popup-proxy> </q-popup-proxy>
</q-icon> </q-icon>
</template> </template>
</q-input> </q-input>
<q-btn-toggle
v-model="template.curve"
@update:model-value="onUpdate"
:options="[
{ label: '直线', value: false },
{ label: '曲线', value: true },
]"
/>
<q-input
v-if="template.curve"
outlined
v-model.number="template.segmentsCount"
type="number"
@blur="onUpdate"
label="曲线分段数量 *"
lazy-rules
:rules="[(val) => (val && val > 0) || '曲线分段数量必须大于0']"
/>
</q-form> </q-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useQuasar } from 'quasar'; import { LinkTemplate } from 'src/graphics/link/Link';
import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant';
import { useDrawStore } from 'src/stores/draw-store'; import { useDrawStore } from 'src/stores/draw-store';
import { onMounted, reactive, ref } from 'vue'; import { onMounted, reactive } from 'vue';
const $q = useQuasar();
const drawStore = useDrawStore(); const drawStore = useDrawStore();
const template = reactive({ const template = reactive({
lineWidth: 1, lineWidth: 1,
lineColor: '#0000ff', lineColor: '#0000ff',
curve: 0, curve: false,
segmentsCount: 10, segmentsCount: 10,
}); });
onMounted(() => { onMounted(() => {
const type = drawStore.drawGraphicType; const type = drawStore.drawGraphicType;
if (type) { if (type) {
const app = drawStore.getDrawApp(); const gt = drawStore.drawGraphicTemplate;
const plugin = app.interactionPlugin<LinkDraw>(type); if (gt) {
const gt = plugin.graphicTemplate; const lt = gt as LinkTemplate;
template.lineWidth = gt.lineWidth; template.lineWidth = lt.lineWidth;
template.lineColor = gt.lineColor; template.lineColor = lt.lineColor;
template.curve = gt.curve ? 1 : 0; template.curve = lt.curve;
template.segmentsCount = gt.segmentsCount; template.segmentsCount = lt.segmentsCount;
}
} }
}); });
function onUpdate() {
const gt = drawStore.drawGraphicTemplate as LinkTemplate;
if (gt) {
gt.lineWidth = template.lineWidth;
gt.lineColor = template.lineColor;
gt.curve = template.curve;
gt.segmentsCount = template.segmentsCount;
}
}
</script> </script>

View File

@ -33,6 +33,12 @@ export class LinkData extends GraphicDataBase implements ILinkData {
set curve(v: boolean) { set curve(v: boolean) {
this.data.curve = v; 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 { get segmentsCount(): number {
return this.data.segmentsCount; return this.data.segmentsCount;
} }

View File

@ -15,7 +15,7 @@ export class IscsFanDraw extends GraphicDrawAssistant<
constructor(app: JlDrawApp, createData: () => IIscsFanData) { constructor(app: JlDrawApp, createData: () => IIscsFanData) {
const template = new IscsFanTemplate(); const template = new IscsFanTemplate();
super(app, template, createData, IscsFan.Type, ''); super(app, template, createData, IscsFan.Type, '风机');
IscsFanInteraction.init(app); IscsFanInteraction.init(app);
} }
@ -41,9 +41,6 @@ export class IscsFanDraw extends GraphicDrawAssistant<
this.iscsFan.position.copyFrom(this.toCanvasCoordinates(e.global)); this.iscsFan.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(false); this.createAndStore(false);
} }
onRightUp(): void {
this.finish();
}
prepareData(data: IIscsFanData): boolean { prepareData(data: IIscsFanData): boolean {
data.transform = this.iscsFan.saveTransform(); data.transform = this.iscsFan.saveTransform();
return true; return true;

View File

@ -88,7 +88,7 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate, ILinkData> {
this.points = []; this.points = [];
this.graphic.clear(); this.graphic.clear();
} }
onRightUp(): void { onRightClick(): void {
this.createAndStore(true); this.createAndStore(true);
} }
onLeftDown(e: FederatedPointerEvent): void { onLeftDown(e: FederatedPointerEvent): void {

View File

@ -20,13 +20,11 @@ import {
InteractionPlugin, InteractionPlugin,
KeyListener, KeyListener,
ShiftData, ShiftData,
ViewportMovePlugin,
} from '../plugins'; } from '../plugins';
import { CommonMouseTool } from '../plugins/CommonMousePlugin'; import { CommonMouseTool } from '../plugins/CommonMousePlugin';
import { MenuItemOptions } from '../ui/Menu'; import { MenuItemOptions } from '../ui/Menu';
import { DOWN, LEFT, RIGHT, UP, recursiveChildren } from '../utils'; import { DOWN, LEFT, RIGHT, UP, recursiveChildren } from '../utils';
import { import {
CanvasData,
GraphicApp, GraphicApp,
GraphicAppOptions, GraphicAppOptions,
ICanvasProperties, ICanvasProperties,
@ -40,9 +38,10 @@ export abstract class GraphicDrawAssistant<
GT extends GraphicTemplate, GT extends GraphicTemplate,
GD extends GraphicData GD extends GraphicData
> extends AppInteractionPlugin { > extends AppInteractionPlugin {
readonly __GraphicDrawAssistant = true;
app: JlDrawApp; app: JlDrawApp;
type: string; // 图形对象类型 type: string; // 图形对象类型
description?: string; // 描述 description: string; // 描述
icon: string; // 界面显示的图标 icon: string; // 界面显示的图标
container: Container = new Container(); container: Container = new Container();
graphicTemplate: GT; graphicTemplate: GT;
@ -64,7 +63,7 @@ export abstract class GraphicDrawAssistant<
graphicTemplate: GT, graphicTemplate: GT,
createGraphicData: () => GD, createGraphicData: () => GD,
icon: string, icon: string,
description?: string description: string
) { ) {
super(graphicTemplate.type, graphicApp); super(graphicTemplate.type, graphicApp);
this.app = graphicApp; this.app = graphicApp;
@ -88,14 +87,16 @@ export abstract class GraphicDrawAssistant<
canvas.on('mouseup', this.onLeftUp, this); canvas.on('mouseup', this.onLeftUp, this);
canvas.on('rightdown', this.onRightDown, this); canvas.on('rightdown', this.onRightDown, this);
canvas.on('rightup', this.onRightUp, this); canvas.on('rightup', this.onRightUp, this);
canvas.on('_rightclick', this.onRightClick, this);
this.app.viewport.wheel({ this.app.viewport.wheel({
percent: 0.01, percent: 0.01,
}); });
this.app.addKeyboardListener(this.escListener); this.app.addKeyboardListener(this.escListener);
this.app this.app.viewport.drag({
.interactionPlugin<ViewportMovePlugin>(ViewportMovePlugin.Name) mouseButtons: 'right',
.resume(); });
} }
unbind(): void { unbind(): void {
this.clearCache(); this.clearCache();
@ -111,9 +112,7 @@ export abstract class GraphicDrawAssistant<
this.app.removeKeyboardListener(this.escListener); this.app.removeKeyboardListener(this.escListener);
this.app this.app.viewport.plugins.remove('drag');
.interactionPlugin<ViewportMovePlugin>(ViewportMovePlugin.Name)
.pause();
} }
onLeftDown(e: FederatedMouseEvent) {} onLeftDown(e: FederatedMouseEvent) {}
@ -125,6 +124,9 @@ export abstract class GraphicDrawAssistant<
onLeftUp(e: FederatedMouseEvent) {} onLeftUp(e: FederatedMouseEvent) {}
onRightDown(e: FederatedMouseEvent) {} onRightDown(e: FederatedMouseEvent) {}
onRightUp(e: FederatedMouseEvent) {} onRightUp(e: FederatedMouseEvent) {}
onRightClick(e: FederatedMouseEvent) {
this.finish();
}
/** /**
* id * id
*/ */
@ -186,13 +188,6 @@ export abstract class GraphicDrawAssistant<
} }
} }
/**
* App事件
*/
export enum DrawAppEvent {
propertiesupdate = 'propertiesupdate', // 图形对象数据变更
}
export type DrawAssistant = GraphicDrawAssistant<GraphicTemplate, GraphicData>; export type DrawAssistant = GraphicDrawAssistant<GraphicTemplate, GraphicData>;
export interface IDrawAppOptions { export interface IDrawAppOptions {
@ -226,16 +221,11 @@ export class JlDrawApp extends GraphicApp {
drawAssistants: DrawAssistant[] = []; drawAssistants: DrawAssistant[] = [];
selectedData: GraphicData | ICanvasProperties | null;
constructor(dom: HTMLElement) { constructor(dom: HTMLElement) {
super(dom); super(dom);
this.appendDrawStatesDisplay(); this.appendDrawStatesDisplay();
// 数据更新表单缓存处理
this.selectedData = null;
this.initSelectedDataUpdateListen();
// 拖拽操作记录 // 拖拽操作记录
this.appOperationRecord(); 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)); this.opRecord.record(new GraphicDeleteOperation(this, deletes));
} }
onSubmit(): void { updateCanvasAndRecord(data: ICanvasProperties) {
if (this.selectedData == null) return; const old = this.canvas.properties.clone();
if (this.selectedGraphics.length === 0) { this.canvas.update(data);
const cp = this.selectedData as ICanvasProperties; const newVal = this.canvas.properties.clone();
this.opRecord.record( this.opRecord.record(
new UpdateCanvasOperation( new UpdateCanvasOperation(this, this.canvas, old, newVal)
this, );
this.canvas, }
cp,
this.canvas.properties.clone() updateGraphicAndRecord(g: JlGraphic, data: GraphicData) {
) const old = g.saveData();
); g.updateData(data);
this.canvas.update(this.selectedData as ICanvasProperties); const newVal = g.saveData();
} else if (this.selectedGraphics.length === 1) { this.opRecord.record(
const g = this.selectedGraphics[0]; new GraphicDataUpdateOperation(this, [g], [old], [newVal])
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]
)
);
}
}
} }
} }
@ -561,21 +496,10 @@ function handleArrowKeyMoveGraphics(
if (child.selected && child.draggable) { if (child.selected && child.draggable) {
handler(child); 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 { } else {
app.selectedGraphics.forEach((g) => { app.selectedGraphics.forEach((g) => {
handler(g); handler(g);
// g.emit('transformstart', GraphicTransformEvent.init(g, 'shift'));
// g.position.x += dp.x;
// g.position.y += dp.y;
}); });
} }
} }

View File

@ -380,8 +380,8 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
this.interactiveTypeOptions = { interactiveGraphicTypeIncludes: [] }; this.interactiveTypeOptions = { interactiveGraphicTypeIncludes: [] };
// 创建pixi渲染app // 创建pixi渲染app
this.app = new Application({ this.app = new Application({
// width: dom.clientWidth, width: dom.clientWidth,
// height: dom.clientHeight, height: dom.clientHeight,
antialias: true, antialias: true,
resizeTo: dom, resizeTo: dom,
}); });
@ -829,6 +829,7 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
} }
const worldWidth = this.canvas._properties.width; const worldWidth = this.canvas._properties.width;
const worldHeight = this.canvas._properties.height; const worldHeight = this.canvas._properties.height;
this.app.resize();
this.viewport.resize(screenWidth, screenHeight, worldWidth, worldHeight); this.viewport.resize(screenWidth, screenHeight, worldWidth, worldHeight);
if (this.viewport.OOB().right) { if (this.viewport.OOB().right) {
this.viewport.right = this.viewport.right + 1; this.viewport.right = this.viewport.right + 1;

View File

@ -33,7 +33,7 @@ declare namespace GlobalMixins {
// eslint-disable-next-line @typescript-eslint/no-empty-interface // eslint-disable-next-line @typescript-eslint/no-empty-interface
interface GraphicAppEvents { interface GraphicAppEvents {
propertiesupdate: [selectedData: GraphicData | CanvasProperties | null]; // propertiesupdate: [selectedData: GraphicData | CanvasProperties | null];
} }
interface DisplayObject { interface DisplayObject {

View File

@ -133,6 +133,7 @@ onMounted(() => {
if (dom) { if (dom) {
const drawApp = drawStore.initDrawApp(dom); const drawApp = drawStore.initDrawApp(dom);
loadDrawDatas(drawApp); loadDrawDatas(drawApp);
onResize();
} }
}); });

View File

@ -1,13 +1,44 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import { destroyDrawApp, getDrawApp, initDrawApp } from 'src/examples/app'; 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', { export const useDrawStore = defineStore('draw', {
state: () => ({ state: () => ({
drawGraphicType: null as string | null, drawAssistant: null as DrawAssistant | null,
selectedGraphics: null as JlGraphic[] | null,
}), }),
getters: { 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: { actions: {
getDrawApp(): JlDrawApp { getDrawApp(): JlDrawApp {
@ -17,21 +48,30 @@ export const useDrawStore = defineStore('draw', {
} }
return app; return app;
}, },
getJlCanvas(): JlCanvas {
return this.getDrawApp().canvas;
},
initDrawApp(dom: HTMLElement) { initDrawApp(dom: HTMLElement) {
const app = initDrawApp(dom); const app = initDrawApp(dom);
app.on('interaction-plugin-resume', (plugin) => { app.on('interaction-plugin-resume', (plugin) => {
if (plugin.isAppPlugin()) { if (plugin.isAppPlugin()) {
if (plugin instanceof GraphicDrawAssistant) { if (Object.hasOwn(plugin, '__GraphicDrawAssistant')) {
this.drawGraphicType = plugin.name; this.drawAssistant = plugin as DrawAssistant;
} else { } else {
this.drawGraphicType = null; this.drawAssistant = null;
} }
} }
}); });
app.on('graphicselectedchange', () => {
this.selectedGraphics = app.selectedGraphics;
});
this.selectedGraphics = [];
return app; return app;
}, },
destroy() { destroy() {
this.drawGraphicType = null; // console.log('绘制状态清空,绘制应用销毁');
this.drawAssistant = null;
this.selectedGraphics = null;
destroyDrawApp(); destroyDrawApp();
}, },
}, },