添加debounce函数实现
drawApp添加绑定/取消绑定表单对象(处理表单更新覆盖图形变换等操作) 调整图形选中事件发布逻辑和触发总的图形选中事件发布
This commit is contained in:
parent
cc737578ba
commit
3e1bbc92bf
@ -5,7 +5,7 @@
|
|||||||
outlined
|
outlined
|
||||||
v-model.number="linkModel.lineWidth"
|
v-model.number="linkModel.lineWidth"
|
||||||
type="number"
|
type="number"
|
||||||
@blur="onUpdate"
|
@blur="onFormUpdate"
|
||||||
label="线宽"
|
label="线宽"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
:rules="[(val) => (val && val > 0) || '画布宽必须大于0']"
|
:rules="[(val) => (val && val > 0) || '画布宽必须大于0']"
|
||||||
@ -14,7 +14,7 @@
|
|||||||
<q-input
|
<q-input
|
||||||
outlined
|
outlined
|
||||||
v-model="linkModel.lineColor"
|
v-model="linkModel.lineColor"
|
||||||
@blur="onUpdate"
|
@blur="onFormUpdate"
|
||||||
label="线色"
|
label="线色"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
:rules="[(val) => (val && val.length > 0) || '线色不能为空']"
|
:rules="[(val) => (val && val.length > 0) || '线色不能为空']"
|
||||||
@ -27,7 +27,7 @@
|
|||||||
@change="
|
@change="
|
||||||
(val) => {
|
(val) => {
|
||||||
linkModel.lineColor = val;
|
linkModel.lineColor = val;
|
||||||
onUpdate();
|
onFormUpdate();
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
@ -50,7 +50,7 @@
|
|||||||
outlined
|
outlined
|
||||||
v-model.number="linkModel.segmentsCount"
|
v-model.number="linkModel.segmentsCount"
|
||||||
type="number"
|
type="number"
|
||||||
@blur="onUpdate"
|
@blur="onFormUpdate"
|
||||||
label="曲线分段数量"
|
label="曲线分段数量"
|
||||||
lazy-rules
|
lazy-rules
|
||||||
:rules="[(val) => (val && val > 0) || '曲线分段数量必须大于0']"
|
:rules="[(val) => (val && val > 0) || '曲线分段数量必须大于0']"
|
||||||
@ -62,34 +62,41 @@
|
|||||||
import { LinkData } from 'src/examples/app/graphics/LinkInteraction';
|
import { LinkData } from 'src/examples/app/graphics/LinkInteraction';
|
||||||
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, reactive, watch } from 'vue';
|
import { onMounted, onUnmounted, reactive, watch } from 'vue';
|
||||||
|
|
||||||
const drawStore = useDrawStore();
|
const drawStore = useDrawStore();
|
||||||
const linkModel = reactive(new LinkData());
|
const linkModel = reactive(new LinkData());
|
||||||
|
|
||||||
drawStore.$subscribe;
|
drawStore.$subscribe;
|
||||||
watch(
|
// watch(
|
||||||
() => drawStore.selectedGraphic,
|
// () => drawStore.selectedGraphic,
|
||||||
(val) => {
|
// (val) => {
|
||||||
if (val && val.type == Link.Type) {
|
// console.log('监控');
|
||||||
// console.log('link变更');
|
// if (val && val.type == Link.Type) {
|
||||||
linkModel.copyFrom(val.saveData() as LinkData);
|
// console.log('link变更');
|
||||||
}
|
// linkModel.copyFrom(val.saveData() as LinkData);
|
||||||
}
|
// }
|
||||||
);
|
// }
|
||||||
|
// );
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// console.log('link 属性表单 mounted');
|
// console.log('link 属性表单 mounted');
|
||||||
const link = drawStore.selectedGraphic as Link;
|
drawStore.bindFormData(linkModel);
|
||||||
if (link) {
|
// const link = drawStore.selectedGraphic as Link;
|
||||||
linkModel.copyFrom(link.saveData());
|
// if (link) {
|
||||||
}
|
// linkModel.copyFrom(link.saveData());
|
||||||
|
// }
|
||||||
});
|
});
|
||||||
|
|
||||||
function onUpdate() {
|
onUnmounted(() => {
|
||||||
console.log('link 属性更新');
|
console.log('link 属性表单 unmounted');
|
||||||
|
drawStore.unbindFormData(linkModel);
|
||||||
|
});
|
||||||
|
|
||||||
|
function onFormUpdate() {
|
||||||
const link = drawStore.selectedGraphic as Link;
|
const link = drawStore.selectedGraphic as Link;
|
||||||
if (link) {
|
if (link) {
|
||||||
|
console.log('link 属性更新', link);
|
||||||
drawStore.getDrawApp().updateGraphicAndRecord(link, linkModel);
|
drawStore.getDrawApp().updateGraphicAndRecord(link, linkModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
import { SignalData } from 'src/examples/app/graphics/SignalInteraction';
|
import { SignalData } from 'src/examples/app/graphics/SignalInteraction';
|
||||||
import { Signal } from 'src/graphics/signal/Signal';
|
import { Signal } from 'src/graphics/signal/Signal';
|
||||||
import { useDrawStore } from 'src/stores/draw-store';
|
import { useDrawStore } from 'src/stores/draw-store';
|
||||||
import { onMounted, reactive, ref, watch } from 'vue';
|
import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
||||||
|
|
||||||
const drawStore = useDrawStore();
|
const drawStore = useDrawStore();
|
||||||
const signalModel = reactive(new SignalData());
|
const signalModel = reactive(new SignalData());
|
||||||
@ -40,6 +40,7 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
drawStore.bindFormData(signalModel);
|
||||||
const signal = drawStore.selectedGraphic as Signal;
|
const signal = drawStore.selectedGraphic as Signal;
|
||||||
if (signal) {
|
if (signal) {
|
||||||
signalModel.copyFrom(signal.saveData());
|
signalModel.copyFrom(signal.saveData());
|
||||||
@ -47,6 +48,10 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
drawStore.unbindFormData(signalModel);
|
||||||
|
});
|
||||||
|
|
||||||
function onUpdate() {
|
function onUpdate() {
|
||||||
signalModel.direction = (directionSelect as never)[signalDirection.value];
|
signalModel.direction = (directionSelect as never)[signalDirection.value];
|
||||||
const signal = drawStore.selectedGraphic as Signal;
|
const signal = drawStore.selectedGraphic as Signal;
|
||||||
|
@ -22,7 +22,15 @@ import {
|
|||||||
} 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,
|
||||||
|
DebouncedFunction,
|
||||||
|
LEFT,
|
||||||
|
RIGHT,
|
||||||
|
UP,
|
||||||
|
debounce,
|
||||||
|
recursiveChildren,
|
||||||
|
} from '../utils';
|
||||||
import {
|
import {
|
||||||
GraphicDataUpdateOperation,
|
GraphicDataUpdateOperation,
|
||||||
UpdateCanvasOperation,
|
UpdateCanvasOperation,
|
||||||
@ -233,6 +241,16 @@ export interface IDrawApp extends IGraphicApp {
|
|||||||
* @param data
|
* @param data
|
||||||
*/
|
*/
|
||||||
updateGraphicAndRecord(g: JlGraphic, data: GraphicData): void;
|
updateGraphicAndRecord(g: JlGraphic, data: GraphicData): void;
|
||||||
|
/**
|
||||||
|
* 绑定form表单对象
|
||||||
|
* @param form
|
||||||
|
*/
|
||||||
|
bindFormData(form: GraphicData): void;
|
||||||
|
/**
|
||||||
|
* 解绑form表单对象
|
||||||
|
* @param form
|
||||||
|
*/
|
||||||
|
unbindFormData(form: GraphicData): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,6 +276,8 @@ export class JlDrawApp extends GraphicApp implements IDrawApp {
|
|||||||
drawAssistants: DrawAssistant[] = [];
|
drawAssistants: DrawAssistant[] = [];
|
||||||
_drawing = false;
|
_drawing = false;
|
||||||
|
|
||||||
|
private debouncedFormDataUpdator: DebouncedFunction<(g: JlGraphic) => void>;
|
||||||
|
|
||||||
get drawing(): boolean {
|
get drawing(): boolean {
|
||||||
return this._drawing;
|
return this._drawing;
|
||||||
}
|
}
|
||||||
@ -274,6 +294,9 @@ export class JlDrawApp extends GraphicApp implements IDrawApp {
|
|||||||
this.appOperationRecord();
|
this.appOperationRecord();
|
||||||
// 绑定通用键盘操作
|
// 绑定通用键盘操作
|
||||||
this.bindKeyboardOperation();
|
this.bindKeyboardOperation();
|
||||||
|
this.formDataSyncListen();
|
||||||
|
|
||||||
|
this.debouncedFormDataUpdator = debounce(this.doFormDataUpdate, 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions(options: DrawAppOptions): void {
|
setOptions(options: DrawAppOptions): void {
|
||||||
@ -484,6 +507,57 @@ export class JlDrawApp extends GraphicApp implements IDrawApp {
|
|||||||
graphic.eventMode = 'static';
|
graphic.eventMode = 'static';
|
||||||
graphic.selectable = true;
|
graphic.selectable = true;
|
||||||
graphic.draggable = true;
|
graphic.draggable = true;
|
||||||
|
graphic.on('repaint', () => {
|
||||||
|
this.handleFormDataUpdate(graphic);
|
||||||
|
});
|
||||||
|
graphic.on('transformend', () => {
|
||||||
|
this.handleFormDataUpdate(graphic);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
formData: GraphicData | undefined = undefined;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定form表单对象
|
||||||
|
* @param form
|
||||||
|
*/
|
||||||
|
bindFormData(form: GraphicData): void {
|
||||||
|
this.formData = form;
|
||||||
|
if (this.selectedGraphics.length == 1) {
|
||||||
|
this.formData.copyFrom(this.selectedGraphics[0].saveData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除form绑定
|
||||||
|
* @param form
|
||||||
|
*/
|
||||||
|
unbindFormData(form: GraphicData): void {
|
||||||
|
if (this.formData == form) {
|
||||||
|
this.formData = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private formDataSyncListen(): void {
|
||||||
|
this.on('graphicselected', () => {
|
||||||
|
if (this.selectedGraphics.length == 1) {
|
||||||
|
this.handleFormDataUpdate(this.selectedGraphics[0]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理表单数据更新(使用debounce限流)
|
||||||
|
*/
|
||||||
|
private handleFormDataUpdate(g: JlGraphic): void {
|
||||||
|
this.debouncedFormDataUpdator(this, g);
|
||||||
|
}
|
||||||
|
|
||||||
|
private doFormDataUpdate(g: JlGraphic): void {
|
||||||
|
if (this.selectedGraphics.length > 1) return;
|
||||||
|
if (this.formData && g.type === this.formData.graphicType) {
|
||||||
|
this.formData.copyFrom(g.saveData());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateCanvasAndRecord(data: ICanvasProperties) {
|
updateCanvasAndRecord(data: ICanvasProperties) {
|
||||||
|
@ -46,6 +46,7 @@ import {
|
|||||||
} from '../plugins/KeyboardPlugin';
|
} from '../plugins/KeyboardPlugin';
|
||||||
import { ContextMenu, ContextMenuPlugin } from '../ui/ContextMenu';
|
import { ContextMenu, ContextMenuPlugin } from '../ui/ContextMenu';
|
||||||
import { MenuItemOptions } from '../ui/Menu';
|
import { MenuItemOptions } from '../ui/Menu';
|
||||||
|
import { DebouncedFunction, debounce } from '../utils';
|
||||||
import { getRectangleCenter, recursiveChildren } from '../utils/GraphicUtils';
|
import { getRectangleCenter, recursiveChildren } from '../utils/GraphicUtils';
|
||||||
import {
|
import {
|
||||||
GraphicCreateOperation,
|
GraphicCreateOperation,
|
||||||
@ -317,6 +318,7 @@ export interface GraphicAppEvents extends GlobalMixins.GraphicAppEvents {
|
|||||||
'options-update': [options: GraphicAppOptions]; // 配置更新
|
'options-update': [options: GraphicAppOptions]; // 配置更新
|
||||||
graphicselectedchange: [graphic: JlGraphic, selected: boolean];
|
graphicselectedchange: [graphic: JlGraphic, selected: boolean];
|
||||||
graphicchildselectedchange: [child: DisplayObject, selected: boolean];
|
graphicchildselectedchange: [child: DisplayObject, selected: boolean];
|
||||||
|
graphicselected: [graphics: JlGraphic[]];
|
||||||
'viewport-scaled': [vp: Viewport];
|
'viewport-scaled': [vp: Viewport];
|
||||||
drag_op_start: [event: AppDragEvent];
|
drag_op_start: [event: AppDragEvent];
|
||||||
drag_op_move: [event: AppDragEvent];
|
drag_op_move: [event: AppDragEvent];
|
||||||
@ -509,11 +511,6 @@ export interface IGraphicScene extends EventEmitter<GraphicAppEvents> {
|
|||||||
* @param graphics
|
* @param graphics
|
||||||
*/
|
*/
|
||||||
updateSelected(...graphics: JlGraphic[]): void;
|
updateSelected(...graphics: JlGraphic[]): void;
|
||||||
/**
|
|
||||||
* 发布选中对象改变事件
|
|
||||||
* @param graphic
|
|
||||||
*/
|
|
||||||
fireSelectedChange(graphic: JlGraphic): void;
|
|
||||||
/**
|
/**
|
||||||
* 选中所有图形
|
* 选中所有图形
|
||||||
*/
|
*/
|
||||||
@ -563,6 +560,8 @@ abstract class GraphicSceneBase
|
|||||||
|
|
||||||
menuPlugin: ContextMenuPlugin; // 菜单插件
|
menuPlugin: ContextMenuPlugin; // 菜单插件
|
||||||
|
|
||||||
|
private debounceEmitFunc: DebouncedFunction<() => void>;
|
||||||
|
|
||||||
wsMsgBroker: AppWsMsgBroker; // websocket消息代理
|
wsMsgBroker: AppWsMsgBroker; // websocket消息代理
|
||||||
constructor(options: GraphicAppOptions) {
|
constructor(options: GraphicAppOptions) {
|
||||||
super();
|
super();
|
||||||
@ -628,6 +627,11 @@ abstract class GraphicSceneBase
|
|||||||
this.menuPlugin = new ContextMenuPlugin(this);
|
this.menuPlugin = new ContextMenuPlugin(this);
|
||||||
|
|
||||||
this.wsMsgBroker = new AppWsMsgBroker(this);
|
this.wsMsgBroker = new AppWsMsgBroker(this);
|
||||||
|
|
||||||
|
this.debounceEmitFunc = debounce(this.doEmitAppGraphicSelected, 50);
|
||||||
|
this.on('graphicselectedchange', () => {
|
||||||
|
this.debounceEmitFunc(this);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
abstract get app(): GraphicApp;
|
abstract get app(): GraphicApp;
|
||||||
|
|
||||||
@ -883,12 +887,10 @@ abstract class GraphicSceneBase
|
|||||||
// graphic可能是vue的Proxy对象,会导致canvas删除时因不是同一个对象而无法从画布移除
|
// graphic可能是vue的Proxy对象,会导致canvas删除时因不是同一个对象而无法从画布移除
|
||||||
const g = this.graphicStore.deleteGraphics(graphic);
|
const g = this.graphicStore.deleteGraphics(graphic);
|
||||||
if (g) {
|
if (g) {
|
||||||
|
// 清除选中
|
||||||
|
g.updateSelected(false);
|
||||||
// 从画布移除
|
// 从画布移除
|
||||||
this.canvas.removeGraphic(g);
|
this.canvas.removeGraphic(g);
|
||||||
// 清除选中
|
|
||||||
if (g.updateSelected(false)) {
|
|
||||||
this.fireSelectedChange(g);
|
|
||||||
}
|
|
||||||
// 对象删除处理
|
// 对象删除处理
|
||||||
g.onDelete();
|
g.onDelete();
|
||||||
this.emit('graphicdeleted', g);
|
this.emit('graphicdeleted', g);
|
||||||
@ -936,15 +938,6 @@ abstract class GraphicSceneBase
|
|||||||
this.updateSelected(...this.queryStore.getAllGraphics());
|
this.updateSelected(...this.queryStore.getAllGraphics());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送选中变化事件
|
|
||||||
* @param graphic
|
|
||||||
*/
|
|
||||||
fireSelectedChange(graphic: JlGraphic) {
|
|
||||||
// console.log('通知选中变化', this.selecteds)
|
|
||||||
const select = graphic.selected;
|
|
||||||
this.emit('graphicselectedchange', graphic, select);
|
|
||||||
}
|
|
||||||
/**
|
/**
|
||||||
* 更新选中
|
* 更新选中
|
||||||
*/
|
*/
|
||||||
@ -955,16 +948,19 @@ abstract class GraphicSceneBase
|
|||||||
}
|
}
|
||||||
if (graphic.selected) {
|
if (graphic.selected) {
|
||||||
graphic.updateSelected(false);
|
graphic.updateSelected(false);
|
||||||
this.fireSelectedChange(graphic);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
graphics.forEach((graphic) => {
|
graphics.forEach((graphic) => {
|
||||||
if (graphic.updateSelected(true)) {
|
graphic.updateSelected(true);
|
||||||
this.fireSelectedChange(graphic);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private doEmitAppGraphicSelected(): void {
|
||||||
|
// 场景发布图形选中
|
||||||
|
this.emit('graphicselected', this.selectedGraphics);
|
||||||
|
// this.app.emit('graphicselected', this.selectedGraphics);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新画布
|
* 更新画布
|
||||||
* @param param
|
* @param param
|
||||||
|
@ -642,6 +642,10 @@ export abstract class JlGraphic extends Container {
|
|||||||
this.removeAllChildSelected();
|
this.removeAllChildSelected();
|
||||||
this.emit('unselected', this);
|
this.emit('unselected', this);
|
||||||
}
|
}
|
||||||
|
const app = this.getGraphicApp();
|
||||||
|
if (app) {
|
||||||
|
app.emit('graphicselectedchange', this, this.selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasSelectedChilds(): boolean {
|
hasSelectedChilds(): boolean {
|
||||||
@ -678,11 +682,16 @@ export abstract class JlGraphic extends Container {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
fireChildSelected(child: DisplayObject) {
|
fireChildSelected(child: DisplayObject) {
|
||||||
if (child.selected) {
|
const selected = child.selected;
|
||||||
|
if (selected) {
|
||||||
this.emit('childselected', child);
|
this.emit('childselected', child);
|
||||||
} else {
|
} else {
|
||||||
this.emit('childunselected', child);
|
this.emit('childunselected', child);
|
||||||
}
|
}
|
||||||
|
const app = this.getGraphicApp();
|
||||||
|
if (app) {
|
||||||
|
app.emit('graphicchildselectedchange', child, selected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exitChildEdit() {
|
exitChildEdit() {
|
||||||
this.childEdit = false;
|
this.childEdit = false;
|
||||||
|
@ -271,7 +271,6 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
graphic.invertChildSelected(target);
|
graphic.invertChildSelected(target);
|
||||||
} else {
|
} else {
|
||||||
graphic.invertSelected();
|
graphic.invertSelected();
|
||||||
app.fireSelectedChange(graphic);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
DisplayObject,
|
DisplayObject,
|
||||||
@ -17,9 +18,11 @@ import { JlGraphic } from '../core';
|
|||||||
import { AbsorbablePosition, VectorText } from '../graphic';
|
import { AbsorbablePosition, VectorText } from '../graphic';
|
||||||
import { DraggablePoint } from '../graphic/DraggablePoint';
|
import { DraggablePoint } from '../graphic/DraggablePoint';
|
||||||
import {
|
import {
|
||||||
|
DebouncedFunction,
|
||||||
angleToAxisx,
|
angleToAxisx,
|
||||||
calculateLineMidpoint,
|
calculateLineMidpoint,
|
||||||
convertRectangleToPolygonPoints,
|
convertRectangleToPolygonPoints,
|
||||||
|
debounce,
|
||||||
distance,
|
distance,
|
||||||
recursiveChildren,
|
recursiveChildren,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
@ -298,6 +301,8 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
ap.tryAbsorb(...targets);
|
ap.tryAbsorb(...targets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// const start = new Date().getTime();
|
||||||
|
|
||||||
// 事件发布
|
// 事件发布
|
||||||
targets.forEach((target) => {
|
targets.forEach((target) => {
|
||||||
if (target.shiftStartPoint && target.shiftLastPoint) {
|
if (target.shiftStartPoint && target.shiftLastPoint) {
|
||||||
@ -314,6 +319,8 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// const dt = new Date().getTime() - start;
|
||||||
|
// console.log('拖拽耗时', `${dt}ms`, targets);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,11 +854,14 @@ export class BoundsGraphic extends Graphics {
|
|||||||
alpha: 1,
|
alpha: 1,
|
||||||
};
|
};
|
||||||
obj: DisplayObject;
|
obj: DisplayObject;
|
||||||
|
debouncedRedraw: DebouncedFunction<() => void>;
|
||||||
constructor(graphic: DisplayObject) {
|
constructor(graphic: DisplayObject) {
|
||||||
super();
|
super();
|
||||||
this.obj = graphic;
|
this.obj = graphic;
|
||||||
this.name = BoundsGraphic.Name;
|
this.name = BoundsGraphic.Name;
|
||||||
this.visible = false;
|
this.visible = false;
|
||||||
|
|
||||||
|
this.debouncedRedraw = debounce(this.doRedraw, 50);
|
||||||
this.obj.on('transformstart', this.onObjTransformStart, this);
|
this.obj.on('transformstart', this.onObjTransformStart, this);
|
||||||
this.obj.on('transformend', this.onObjTransformEnd, this);
|
this.obj.on('transformend', this.onObjTransformEnd, this);
|
||||||
if (this.obj.children && this.obj.children.length > 0) {
|
if (this.obj.children && this.obj.children.length > 0) {
|
||||||
@ -880,7 +890,6 @@ export class BoundsGraphic extends Graphics {
|
|||||||
onGraphicRepaint(): void {
|
onGraphicRepaint(): void {
|
||||||
if (this.visible) {
|
if (this.visible) {
|
||||||
this.redraw();
|
this.redraw();
|
||||||
this.visible = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -892,8 +901,13 @@ export class BoundsGraphic extends Graphics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
redraw() {
|
redraw() {
|
||||||
|
this.debouncedRedraw(this);
|
||||||
|
}
|
||||||
|
doRedraw() {
|
||||||
|
const visible = this.visible;
|
||||||
this.visible = false; // 屏蔽包围框本身
|
this.visible = false; // 屏蔽包围框本身
|
||||||
const bounds = new Polygon(this.obj.localBoundsToCanvasPoints());
|
const bounds = new Polygon(this.obj.localBoundsToCanvasPoints());
|
||||||
this.clear().lineStyle(BoundsGraphic.BoundsLineStyle).drawShape(bounds);
|
this.clear().lineStyle(BoundsGraphic.BoundsLineStyle).drawShape(bounds);
|
||||||
|
this.visible = visible;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
37
src/jlgraphic/utils/debounce.ts
Normal file
37
src/jlgraphic/utils/debounce.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
export interface DebouncedFunction<F extends (...args: any[]) => any> {
|
||||||
|
(context: ThisParameterType<F>, ...args: Parameters<F>): void;
|
||||||
|
cancel: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function debounce<F extends (...args: Parameters<F>) => any>(
|
||||||
|
fn: F,
|
||||||
|
waitMs = 250
|
||||||
|
): DebouncedFunction<F> {
|
||||||
|
let timeoutId: ReturnType<typeof setTimeout> | undefined;
|
||||||
|
|
||||||
|
const debouncedFunction = function (
|
||||||
|
context: ThisParameterType<F>,
|
||||||
|
...args: Parameters<F>
|
||||||
|
) {
|
||||||
|
const invokeFunction = function () {
|
||||||
|
timeoutId = undefined;
|
||||||
|
fn.apply(context, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (timeoutId !== undefined) {
|
||||||
|
console.debug('debounce clear timeout', fn);
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeoutId = setTimeout(invokeFunction, waitMs);
|
||||||
|
};
|
||||||
|
|
||||||
|
debouncedFunction.cancel = function () {
|
||||||
|
if (timeoutId !== undefined) {
|
||||||
|
clearTimeout(timeoutId);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return debouncedFunction;
|
||||||
|
}
|
@ -3,6 +3,8 @@ import { Point, Rectangle } from 'pixi.js';
|
|||||||
export * from './GraphicUtils';
|
export * from './GraphicUtils';
|
||||||
export * from './IntersectUtils';
|
export * from './IntersectUtils';
|
||||||
|
|
||||||
|
export * from './debounce';
|
||||||
|
|
||||||
export const UP: Point = new Point(0, -1);
|
export const UP: Point = new Point(0, -1);
|
||||||
export const DOWN: Point = new Point(0, 1);
|
export const DOWN: Point = new Point(0, 1);
|
||||||
export const LEFT: Point = new Point(-1, 0);
|
export const LEFT: Point = new Point(-1, 0);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
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 { DrawAssistant, IDrawApp, JlGraphic } from 'src/jlgraphic';
|
import { DrawAssistant, GraphicData, IDrawApp, JlGraphic } from 'src/jlgraphic';
|
||||||
import { IJlCanvas } from 'src/jlgraphic/app/JlGraphicApp';
|
import { IJlCanvas } from 'src/jlgraphic/app/JlGraphicApp';
|
||||||
|
|
||||||
export const useDrawStore = defineStore('draw', {
|
export const useDrawStore = defineStore('draw', {
|
||||||
@ -52,6 +52,22 @@ export const useDrawStore = defineStore('draw', {
|
|||||||
getJlCanvas(): IJlCanvas {
|
getJlCanvas(): IJlCanvas {
|
||||||
return this.getDrawApp().canvas;
|
return this.getDrawApp().canvas;
|
||||||
},
|
},
|
||||||
|
bindFormData(form: GraphicData): void {
|
||||||
|
console.log('绑定form数据', form);
|
||||||
|
const app = this.getDrawApp();
|
||||||
|
app.bindFormData(form);
|
||||||
|
// app.app.on('graphicselectedchange', () => {
|
||||||
|
// if (app.selectedGraphics.length == 1) {
|
||||||
|
// const g = app.selectedGraphics[0];
|
||||||
|
// if (g.type === form.graphicType) {
|
||||||
|
// form.copyFrom(g.saveData());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
},
|
||||||
|
unbindFormData(form: GraphicData): void {
|
||||||
|
console.log('取消绑定form数据', form);
|
||||||
|
},
|
||||||
initDrawApp() {
|
initDrawApp() {
|
||||||
const app = initDrawApp();
|
const app = initDrawApp();
|
||||||
app.on('interaction-plugin-resume', (plugin) => {
|
app.on('interaction-plugin-resume', (plugin) => {
|
||||||
@ -63,7 +79,8 @@ export const useDrawStore = defineStore('draw', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
app.on('graphicselectedchange', () => {
|
app.on('graphicselected', () => {
|
||||||
|
console.log('批量选中事件', app.selectedGraphics.length);
|
||||||
this.selectedGraphics = app.selectedGraphics;
|
this.selectedGraphics = app.selectedGraphics;
|
||||||
});
|
});
|
||||||
this.selectedGraphics = [];
|
this.selectedGraphics = [];
|
||||||
|
Loading…
Reference in New Issue
Block a user