graphics框架更新
This commit is contained in:
parent
97fa9307b7
commit
f980c4f557
@ -1 +1 @@
|
|||||||
Subproject commit 6dde86d63f08cefdea5d6532cf95e8e83f0dd0dc
|
Subproject commit 7e9c9eb31176294726103306dcca61b80b896cf7
|
@ -11,7 +11,6 @@ import {
|
|||||||
} from 'pixi.js';
|
} from 'pixi.js';
|
||||||
import { GraphicIdGenerator } from '../core/IdGenerator';
|
import { GraphicIdGenerator } from '../core/IdGenerator';
|
||||||
import { GraphicData, GraphicTemplate, JlGraphic } from '../core/JlGraphic';
|
import { GraphicData, GraphicTemplate, JlGraphic } from '../core/JlGraphic';
|
||||||
import { JlOperation } from '../operation/JlOperation';
|
|
||||||
import {
|
import {
|
||||||
AppDragEvent,
|
AppDragEvent,
|
||||||
AppInteractionPlugin,
|
AppInteractionPlugin,
|
||||||
@ -24,11 +23,16 @@ import {
|
|||||||
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 {
|
||||||
|
GraphicDataUpdateOperation,
|
||||||
|
UpdateCanvasOperation,
|
||||||
|
} from './BasicOperation';
|
||||||
import {
|
import {
|
||||||
GraphicApp,
|
GraphicApp,
|
||||||
GraphicAppOptions,
|
GraphicAppOptions,
|
||||||
ICanvasProperties,
|
ICanvasProperties,
|
||||||
JlCanvas,
|
IGraphicApp,
|
||||||
|
IJlCanvas,
|
||||||
} from './JlGraphicApp';
|
} from './JlGraphicApp';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +43,7 @@ export abstract class GraphicDrawAssistant<
|
|||||||
GD extends GraphicData
|
GD extends GraphicData
|
||||||
> extends AppInteractionPlugin {
|
> extends AppInteractionPlugin {
|
||||||
readonly __GraphicDrawAssistant = true;
|
readonly __GraphicDrawAssistant = true;
|
||||||
app: JlDrawApp;
|
app: IDrawApp;
|
||||||
type: string; // 图形对象类型
|
type: string; // 图形对象类型
|
||||||
description: string; // 描述
|
description: string; // 描述
|
||||||
icon: string; // 界面显示的图标
|
icon: string; // 界面显示的图标
|
||||||
@ -58,7 +62,7 @@ export abstract class GraphicDrawAssistant<
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
graphicApp: JlDrawApp,
|
graphicApp: IDrawApp,
|
||||||
graphicTemplate: GT,
|
graphicTemplate: GT,
|
||||||
icon: string,
|
icon: string,
|
||||||
description: string
|
description: string
|
||||||
@ -72,12 +76,12 @@ export abstract class GraphicDrawAssistant<
|
|||||||
this.app.registerGraphicTemplates(this.graphicTemplate);
|
this.app.registerGraphicTemplates(this.graphicTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
public get canvas(): JlCanvas {
|
public get canvas(): IJlCanvas {
|
||||||
return this.app.canvas;
|
return this.app.canvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
bind(): void {
|
bind(): void {
|
||||||
this.app._drawing = true;
|
this.app.drawing = true;
|
||||||
const canvas = this.canvas;
|
const canvas = this.canvas;
|
||||||
canvas.addChild(this.container);
|
canvas.addChild(this.container);
|
||||||
canvas.on('mousedown', this.onLeftDown, this);
|
canvas.on('mousedown', this.onLeftDown, this);
|
||||||
@ -113,7 +117,7 @@ export abstract class GraphicDrawAssistant<
|
|||||||
this.app.removeKeyboardListener(this.escListener);
|
this.app.removeKeyboardListener(this.escListener);
|
||||||
|
|
||||||
this.app.viewport.plugins.remove('drag');
|
this.app.viewport.plugins.remove('drag');
|
||||||
this.app._drawing = false;
|
this.app.drawing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onLeftDown(e: FederatedMouseEvent) {}
|
onLeftDown(e: FederatedMouseEvent) {}
|
||||||
@ -152,9 +156,7 @@ export abstract class GraphicDrawAssistant<
|
|||||||
* 保存创建的图形对象
|
* 保存创建的图形对象
|
||||||
*/
|
*/
|
||||||
storeGraphic(...graphics: JlGraphic[]): void {
|
storeGraphic(...graphics: JlGraphic[]): void {
|
||||||
this.app.addGraphics(...graphics);
|
this.app.addGraphicAndRecord(...graphics);
|
||||||
// 创建图形对象操作记录
|
|
||||||
this.app.opRecord.record(new GraphicCreateOperation(this.app, graphics));
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* 创建并添加到图形App
|
* 创建并添加到图形App
|
||||||
@ -189,21 +191,54 @@ export abstract class GraphicDrawAssistant<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制助手类型
|
||||||
|
*/
|
||||||
export type DrawAssistant = GraphicDrawAssistant<GraphicTemplate, GraphicData>;
|
export type DrawAssistant = GraphicDrawAssistant<GraphicTemplate, GraphicData>;
|
||||||
|
|
||||||
export interface IDrawAppOptions {
|
/**
|
||||||
/**
|
* 绘制配置选项
|
||||||
* 绘制辅助交互插件
|
*/
|
||||||
*/
|
export type DrawAppOptions = GraphicAppOptions;
|
||||||
drawAssistants: DrawAssistant[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export type DrawAppOptions = GraphicAppOptions & IDrawAppOptions;
|
/**
|
||||||
|
* 绘制应用接口
|
||||||
|
*/
|
||||||
|
export interface IDrawApp extends IGraphicApp {
|
||||||
|
/**
|
||||||
|
* 是否正在绘制图形
|
||||||
|
*/
|
||||||
|
get drawing(): boolean;
|
||||||
|
/**
|
||||||
|
* 更新绘制中状态
|
||||||
|
*/
|
||||||
|
set drawing(value: boolean);
|
||||||
|
/**
|
||||||
|
* 设置配置选项
|
||||||
|
* @param options
|
||||||
|
*/
|
||||||
|
setOptions(options: DrawAppOptions): void;
|
||||||
|
/**
|
||||||
|
* 获取绘制助手
|
||||||
|
*/
|
||||||
|
getDrawAssistant<DA extends DrawAssistant>(graphicType: string): DA;
|
||||||
|
/**
|
||||||
|
* 更新画布并记录
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
updateCanvasAndRecord(data: ICanvasProperties): void;
|
||||||
|
/**
|
||||||
|
* 更新图形并记录
|
||||||
|
* @param g
|
||||||
|
* @param data
|
||||||
|
*/
|
||||||
|
updateGraphicAndRecord(g: JlGraphic, data: GraphicData): void;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 绘制应用
|
* 绘制应用
|
||||||
*/
|
*/
|
||||||
export class JlDrawApp extends GraphicApp {
|
export class JlDrawApp extends GraphicApp implements IDrawApp {
|
||||||
font: BitmapFont = BitmapFont.from(
|
font: BitmapFont = BitmapFont.from(
|
||||||
'coordinates',
|
'coordinates',
|
||||||
{
|
{
|
||||||
@ -223,8 +258,15 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
drawAssistants: DrawAssistant[] = [];
|
drawAssistants: DrawAssistant[] = [];
|
||||||
_drawing = false;
|
_drawing = false;
|
||||||
|
|
||||||
constructor(dom: HTMLElement) {
|
get drawing(): boolean {
|
||||||
super(dom);
|
return this._drawing;
|
||||||
|
}
|
||||||
|
set drawing(value: boolean) {
|
||||||
|
this._drawing = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(options: DrawAppOptions) {
|
||||||
|
super(options);
|
||||||
|
|
||||||
this.appendDrawStatesDisplay();
|
this.appendDrawStatesDisplay();
|
||||||
|
|
||||||
@ -236,7 +278,6 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
|
|
||||||
setOptions(options: DrawAppOptions): void {
|
setOptions(options: DrawAppOptions): void {
|
||||||
super.setOptions(options);
|
super.setOptions(options);
|
||||||
// this.registerInteractionPlugin(...options.drawAssistants);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
registerInteractionPlugin(...plugins: InteractionPlugin[]): void {
|
registerInteractionPlugin(...plugins: InteractionPlugin[]): void {
|
||||||
@ -310,8 +351,8 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
* 绘制状态信息显示
|
* 绘制状态信息显示
|
||||||
*/
|
*/
|
||||||
private appendDrawStatesDisplay(): void {
|
private appendDrawStatesDisplay(): void {
|
||||||
this.app.stage.addChild(this.coordinates);
|
this.pixi.stage.addChild(this.coordinates);
|
||||||
this.app.stage.addChild(this.scaleText);
|
this.pixi.stage.addChild(this.scaleText);
|
||||||
const bound = this.coordinates.getLocalBounds();
|
const bound = this.coordinates.getLocalBounds();
|
||||||
this.scaleText.position.set(bound.width + 10, 0);
|
this.scaleText.position.set(bound.width + 10, 0);
|
||||||
this.canvas.on('mousemove', (e) => {
|
this.canvas.on('mousemove', (e) => {
|
||||||
@ -336,7 +377,7 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'KeyA',
|
value: 'KeyA',
|
||||||
combinations: [CombinationKey.Ctrl],
|
combinations: [CombinationKey.Ctrl],
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
if (e.ctrlKey) {
|
if (e.ctrlKey) {
|
||||||
(app as JlDrawApp).selectAllGraphics();
|
(app as JlDrawApp).selectAllGraphics();
|
||||||
}
|
}
|
||||||
@ -349,8 +390,8 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'KeyD',
|
value: 'KeyD',
|
||||||
combinations: [CombinationKey.Shift],
|
combinations: [CombinationKey.Shift],
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
app.graphicCopyPlugin.init();
|
this.graphicCopyPlugin.init();
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -360,7 +401,7 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
value: 'KeyZ',
|
value: 'KeyZ',
|
||||||
global: true,
|
global: true,
|
||||||
combinations: [CombinationKey.Ctrl],
|
combinations: [CombinationKey.Ctrl],
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
app.opRecord.undo();
|
app.opRecord.undo();
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -371,7 +412,7 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
value: 'KeyZ',
|
value: 'KeyZ',
|
||||||
global: true,
|
global: true,
|
||||||
combinations: [CombinationKey.Ctrl, CombinationKey.Shift],
|
combinations: [CombinationKey.Ctrl, CombinationKey.Shift],
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
app.opRecord.redo();
|
app.opRecord.redo();
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -380,8 +421,8 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
this.addKeyboardListener(
|
this.addKeyboardListener(
|
||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'Delete',
|
value: 'Delete',
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
(app as JlDrawApp).deleteSelectedGraphics();
|
app.deleteGraphicAndRecord(...app.selectedGraphics);
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
@ -389,10 +430,10 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'ArrowUp',
|
value: 'ArrowUp',
|
||||||
pressTriggerAsOriginalEvent: true,
|
pressTriggerAsOriginalEvent: true,
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
updateGraphicPositionOnKeyboardEvent(app, UP);
|
updateGraphicPositionOnKeyboardEvent(app, UP);
|
||||||
},
|
},
|
||||||
onRelease: (e: KeyboardEvent, app: GraphicApp) => {
|
onRelease: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
recordGraphicMoveOperation(app);
|
recordGraphicMoveOperation(app);
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -401,10 +442,10 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'ArrowDown',
|
value: 'ArrowDown',
|
||||||
pressTriggerAsOriginalEvent: true,
|
pressTriggerAsOriginalEvent: true,
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
updateGraphicPositionOnKeyboardEvent(app, DOWN);
|
updateGraphicPositionOnKeyboardEvent(app, DOWN);
|
||||||
},
|
},
|
||||||
onRelease: (e: KeyboardEvent, app: GraphicApp) => {
|
onRelease: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
recordGraphicMoveOperation(app);
|
recordGraphicMoveOperation(app);
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -413,10 +454,10 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'ArrowLeft',
|
value: 'ArrowLeft',
|
||||||
pressTriggerAsOriginalEvent: true,
|
pressTriggerAsOriginalEvent: true,
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
updateGraphicPositionOnKeyboardEvent(app, LEFT);
|
updateGraphicPositionOnKeyboardEvent(app, LEFT);
|
||||||
},
|
},
|
||||||
onRelease: (e: KeyboardEvent, app: GraphicApp) => {
|
onRelease: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
recordGraphicMoveOperation(app);
|
recordGraphicMoveOperation(app);
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -425,23 +466,16 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
new KeyListener({
|
new KeyListener({
|
||||||
value: 'ArrowRight',
|
value: 'ArrowRight',
|
||||||
pressTriggerAsOriginalEvent: true,
|
pressTriggerAsOriginalEvent: true,
|
||||||
onPress: (e: KeyboardEvent, app: GraphicApp) => {
|
onPress: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
updateGraphicPositionOnKeyboardEvent(app, RIGHT);
|
updateGraphicPositionOnKeyboardEvent(app, RIGHT);
|
||||||
},
|
},
|
||||||
onRelease: (e: KeyboardEvent, app: GraphicApp) => {
|
onRelease: (e: KeyboardEvent, app: IGraphicApp) => {
|
||||||
recordGraphicMoveOperation(app);
|
recordGraphicMoveOperation(app);
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 全选
|
|
||||||
*/
|
|
||||||
selectAllGraphics() {
|
|
||||||
this.updateSelected(...this.queryStore.getAllGraphics());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图形对象存储处理,默认添加图形交互
|
* 图形对象存储处理,默认添加图形交互
|
||||||
* @param graphic
|
* @param graphic
|
||||||
@ -452,19 +486,6 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
graphic.draggable = true;
|
graphic.draggable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除选中图形对象
|
|
||||||
*/
|
|
||||||
deleteSelectedGraphics() {
|
|
||||||
const deletes = this.deleteGraphics(...this.selectedGraphics);
|
|
||||||
if (deletes.length > 0) {
|
|
||||||
// 删除图形对象操作记录
|
|
||||||
this.opRecord.record(new GraphicDeleteOperation(this, deletes));
|
|
||||||
} else {
|
|
||||||
console.debug('没有删除元素,不记录');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateCanvasAndRecord(data: ICanvasProperties) {
|
updateCanvasAndRecord(data: ICanvasProperties) {
|
||||||
const old = this.canvas.properties.clone();
|
const old = this.canvas.properties.clone();
|
||||||
this.canvas.update(data);
|
this.canvas.update(data);
|
||||||
@ -487,7 +508,7 @@ export class JlDrawApp extends GraphicApp {
|
|||||||
let dragStartDatas: GraphicData[] = [];
|
let dragStartDatas: GraphicData[] = [];
|
||||||
|
|
||||||
function handleArrowKeyMoveGraphics(
|
function handleArrowKeyMoveGraphics(
|
||||||
app: GraphicApp,
|
app: IGraphicApp,
|
||||||
handler: (obj: DisplayObject) => void
|
handler: (obj: DisplayObject) => void
|
||||||
) {
|
) {
|
||||||
if (
|
if (
|
||||||
@ -506,7 +527,10 @@ function handleArrowKeyMoveGraphics(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateGraphicPositionOnKeyboardEvent(app: GraphicApp, dp: IPointData) {
|
function updateGraphicPositionOnKeyboardEvent(
|
||||||
|
app: IGraphicApp,
|
||||||
|
dp: IPointData
|
||||||
|
) {
|
||||||
let dragStart = false;
|
let dragStart = false;
|
||||||
if (dragStartDatas.length === 0) {
|
if (dragStartDatas.length === 0) {
|
||||||
dragStartDatas = app.selectedGraphics.map((g) => g.saveData());
|
dragStartDatas = app.selectedGraphics.map((g) => g.saveData());
|
||||||
@ -541,7 +565,7 @@ function updateGraphicPositionOnKeyboardEvent(app: GraphicApp, dp: IPointData) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function recordGraphicMoveOperation(app: GraphicApp) {
|
function recordGraphicMoveOperation(app: IGraphicApp) {
|
||||||
if (
|
if (
|
||||||
dragStartDatas.length > 0 &&
|
dragStartDatas.length > 0 &&
|
||||||
dragStartDatas.length === app.selectedGraphics.length
|
dragStartDatas.length === app.selectedGraphics.length
|
||||||
@ -570,110 +594,3 @@ function recordGraphicMoveOperation(app: GraphicApp) {
|
|||||||
}
|
}
|
||||||
dragStartDatas = [];
|
dragStartDatas = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新画布操作
|
|
||||||
*/
|
|
||||||
export class UpdateCanvasOperation extends JlOperation {
|
|
||||||
obj: JlCanvas;
|
|
||||||
old: ICanvasProperties;
|
|
||||||
data: ICanvasProperties;
|
|
||||||
description = '';
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
app: GraphicApp,
|
|
||||||
obj: JlCanvas,
|
|
||||||
old: ICanvasProperties,
|
|
||||||
data: ICanvasProperties
|
|
||||||
) {
|
|
||||||
super(app, 'update-canvas');
|
|
||||||
this.app = app;
|
|
||||||
this.obj = obj;
|
|
||||||
this.old = old;
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
undo(): JlGraphic[] {
|
|
||||||
this.obj.update(this.old);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
redo(): JlGraphic[] {
|
|
||||||
this.obj.update(this.data);
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 创建图形操作
|
|
||||||
*/
|
|
||||||
export class GraphicCreateOperation extends JlOperation {
|
|
||||||
obj: JlGraphic[];
|
|
||||||
description = '';
|
|
||||||
|
|
||||||
constructor(app: GraphicApp, obj: JlGraphic[]) {
|
|
||||||
super(app, 'graphic-create');
|
|
||||||
this.app = app;
|
|
||||||
this.obj = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
undo(): JlGraphic[] | void {
|
|
||||||
this.app.deleteGraphics(...this.obj);
|
|
||||||
}
|
|
||||||
redo(): JlGraphic[] {
|
|
||||||
this.app.addGraphics(...this.obj);
|
|
||||||
return this.obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 删除图形操作
|
|
||||||
*/
|
|
||||||
export class GraphicDeleteOperation extends JlOperation {
|
|
||||||
obj: JlGraphic[];
|
|
||||||
|
|
||||||
constructor(app: GraphicApp, obj: JlGraphic[]) {
|
|
||||||
super(app, 'graphic-delete');
|
|
||||||
this.app = app;
|
|
||||||
this.obj = obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
undo(): JlGraphic[] {
|
|
||||||
this.app.addGraphics(...this.obj);
|
|
||||||
return this.obj;
|
|
||||||
}
|
|
||||||
redo(): void {
|
|
||||||
this.app.deleteGraphics(...this.obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class GraphicDataUpdateOperation extends JlOperation {
|
|
||||||
obj: JlGraphic[];
|
|
||||||
oldData: GraphicData[];
|
|
||||||
newData: GraphicData[];
|
|
||||||
constructor(
|
|
||||||
app: GraphicApp,
|
|
||||||
obj: JlGraphic[],
|
|
||||||
oldData: GraphicData[],
|
|
||||||
newData: GraphicData[]
|
|
||||||
) {
|
|
||||||
super(app, 'graphic-drag');
|
|
||||||
this.obj = [...obj];
|
|
||||||
this.oldData = oldData;
|
|
||||||
this.newData = newData;
|
|
||||||
}
|
|
||||||
|
|
||||||
undo(): void | JlGraphic[] {
|
|
||||||
for (let i = 0; i < this.obj.length; i++) {
|
|
||||||
const g = this.obj[i];
|
|
||||||
// g.exitChildEdit();
|
|
||||||
g.updateData(this.oldData[i]);
|
|
||||||
}
|
|
||||||
return this.obj;
|
|
||||||
}
|
|
||||||
redo(): void | JlGraphic[] {
|
|
||||||
for (let i = 0; i < this.obj.length; i++) {
|
|
||||||
const g = this.obj[i];
|
|
||||||
// g.exitChildEdit();
|
|
||||||
g.updateData(this.newData[i]);
|
|
||||||
}
|
|
||||||
return this.obj;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,2 +1,46 @@
|
|||||||
export * from './JlGraphicApp';
|
import {
|
||||||
export * from './JlDrawApp';
|
DrawAppOptions,
|
||||||
|
DrawAssistant,
|
||||||
|
GraphicDrawAssistant,
|
||||||
|
IDrawApp,
|
||||||
|
JlDrawApp,
|
||||||
|
} from './JlDrawApp';
|
||||||
|
import {
|
||||||
|
AppConsts,
|
||||||
|
GraphicApp,
|
||||||
|
GraphicAppOptions,
|
||||||
|
ICanvasProperties,
|
||||||
|
IGraphicApp,
|
||||||
|
IGraphicScene,
|
||||||
|
IGraphicStorage,
|
||||||
|
IJlCanvas,
|
||||||
|
} from './JlGraphicApp';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实例化图形app
|
||||||
|
* @param options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function newGraphicApp(options: GraphicAppOptions): IGraphicApp {
|
||||||
|
return new GraphicApp(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实例化绘图app
|
||||||
|
* @param options
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function newDrawApp(options: DrawAppOptions): IDrawApp {
|
||||||
|
return new JlDrawApp(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { AppConsts, GraphicDrawAssistant };
|
||||||
|
export type {
|
||||||
|
DrawAssistant,
|
||||||
|
ICanvasProperties,
|
||||||
|
IDrawApp,
|
||||||
|
IGraphicApp,
|
||||||
|
IGraphicScene,
|
||||||
|
IGraphicStorage,
|
||||||
|
IJlCanvas,
|
||||||
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { GraphicApp } from '../app/JlGraphicApp';
|
|
||||||
import { JlGraphic } from './JlGraphic';
|
import { JlGraphic } from './JlGraphic';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,11 +100,7 @@ export class GraphicRelation {
|
|||||||
* 图形关系管理
|
* 图形关系管理
|
||||||
*/
|
*/
|
||||||
export class RelationManage {
|
export class RelationManage {
|
||||||
app: GraphicApp;
|
|
||||||
relations: GraphicRelation[] = [];
|
relations: GraphicRelation[] = [];
|
||||||
constructor(app: GraphicApp) {
|
|
||||||
this.app = app;
|
|
||||||
}
|
|
||||||
|
|
||||||
isContainsRelation(
|
isContainsRelation(
|
||||||
rp1: GraphicRelationParam,
|
rp1: GraphicRelationParam,
|
||||||
@ -182,4 +177,11 @@ export class RelationManage {
|
|||||||
const relations = this.getRelationsOfGraphicAndOtherType(g, type);
|
const relations = this.getRelationsOfGraphicAndOtherType(g, type);
|
||||||
relations.forEach((rl) => this.deleteRelation(rl));
|
relations.forEach((rl) => this.deleteRelation(rl));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空
|
||||||
|
*/
|
||||||
|
clear() {
|
||||||
|
this.relations.splice(0, this.relations.length);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import { GraphicApp } from '../app/JlGraphicApp';
|
|
||||||
import { RelationManage } from './GraphicRelation';
|
import { RelationManage } from './GraphicRelation';
|
||||||
import { JlGraphic } from './JlGraphic';
|
import { JlGraphic } from './JlGraphic';
|
||||||
|
|
||||||
@ -67,13 +66,11 @@ export interface GraphicQueryStore {
|
|||||||
* 图形存储
|
* 图形存储
|
||||||
*/
|
*/
|
||||||
export class GraphicStore implements GraphicQueryStore {
|
export class GraphicStore implements GraphicQueryStore {
|
||||||
app: GraphicApp;
|
|
||||||
store: Map<string, JlGraphic>;
|
store: Map<string, JlGraphic>;
|
||||||
relationManage: RelationManage;
|
relationManage: RelationManage;
|
||||||
constructor(app: GraphicApp) {
|
constructor() {
|
||||||
this.app = app;
|
|
||||||
this.store = new Map<string, JlGraphic>();
|
this.store = new Map<string, JlGraphic>();
|
||||||
this.relationManage = new RelationManage(app);
|
this.relationManage = new RelationManage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -198,4 +195,12 @@ export class GraphicStore implements GraphicQueryStore {
|
|||||||
}
|
}
|
||||||
return remove;
|
return remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空
|
||||||
|
*/
|
||||||
|
clear() {
|
||||||
|
this.relationManage.clear();
|
||||||
|
this.store.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ import {
|
|||||||
Point,
|
Point,
|
||||||
Rectangle,
|
Rectangle,
|
||||||
} from 'pixi.js';
|
} from 'pixi.js';
|
||||||
import { AppConsts, JlCanvas } from '../app';
|
import { AppConsts, IJlCanvas } from '../app';
|
||||||
import {
|
import {
|
||||||
convertRectangleToPolygonPoints,
|
convertRectangleToPolygonPoints,
|
||||||
recursiveChildren,
|
recursiveChildren,
|
||||||
@ -277,7 +277,7 @@ DisplayObject.prototype.getCanvas = function getCanvas() {
|
|||||||
graphic = graphic.parent;
|
graphic = graphic.parent;
|
||||||
}
|
}
|
||||||
if (graphic) {
|
if (graphic) {
|
||||||
return graphic as JlCanvas;
|
return graphic as IJlCanvas;
|
||||||
}
|
}
|
||||||
throw new Error(`图形${this.name}不在画布中`);
|
throw new Error(`图形${this.name}不在画布中`);
|
||||||
};
|
};
|
||||||
@ -290,7 +290,7 @@ DisplayObject.prototype.getViewport = function getViewport() {
|
|||||||
};
|
};
|
||||||
DisplayObject.prototype.getGraphicApp = function getGraphicApp() {
|
DisplayObject.prototype.getGraphicApp = function getGraphicApp() {
|
||||||
const canvas = this.getCanvas();
|
const canvas = this.getCanvas();
|
||||||
return canvas.app;
|
return canvas.scene.app;
|
||||||
};
|
};
|
||||||
DisplayObject.prototype.localToCanvasPoint = function localToCanvasPoint(
|
DisplayObject.prototype.localToCanvasPoint = function localToCanvasPoint(
|
||||||
p: IPointData
|
p: IPointData
|
||||||
|
4
src/jl-graphic/global.d.ts
vendored
4
src/jl-graphic/global.d.ts
vendored
@ -1,8 +1,8 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
declare namespace GlobalMixins {
|
declare namespace GlobalMixins {
|
||||||
type JlCanvasType = import('./app').JlCanvas;
|
type JlCanvasType = import('./app').IJlCanvas;
|
||||||
type CanvasProperties = import('./app').ICanvasProperties;
|
type CanvasProperties = import('./app').ICanvasProperties;
|
||||||
type GraphicApp = import('./app').GraphicApp;
|
type GraphicApp = import('./app').IGraphicApp;
|
||||||
type JlGraphicType = import('./core').JlGraphic;
|
type JlGraphicType = import('./core').JlGraphic;
|
||||||
type GraphicData = import('./core').GraphicData;
|
type GraphicData = import('./core').GraphicData;
|
||||||
type GraphicState = import('./core').GraphicState;
|
type GraphicState = import('./core').GraphicState;
|
||||||
|
@ -29,8 +29,9 @@ export class VectorText extends Text implements VectorGraphic {
|
|||||||
* 设置矢量文字的字体大小
|
* 设置矢量文字的字体大小
|
||||||
*/
|
*/
|
||||||
setVectorFontSize(fontSize: number) {
|
setVectorFontSize(fontSize: number) {
|
||||||
this.vectorFontSize = fontSize;
|
if (this.vectorFontSize !== fontSize) {
|
||||||
// this.style.fontSize = fontSize;
|
this.vectorFontSize = fontSize;
|
||||||
this.updateOnScaled();
|
this.updateOnScaled();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import EventEmitter from 'eventemitter3';
|
import EventEmitter from 'eventemitter3';
|
||||||
import { GraphicApp } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { CompleteMessageCliOption, IMessageClient } from './MessageBroker';
|
import { CompleteMessageCliOption, IMessageClient } from './MessageBroker';
|
||||||
|
|
||||||
export interface MessageClientEvents {
|
export interface MessageClientEvents {
|
||||||
@ -14,7 +14,7 @@ export interface IMessageHandler {
|
|||||||
/**
|
/**
|
||||||
* id
|
* id
|
||||||
*/
|
*/
|
||||||
get App(): GraphicApp;
|
get App(): IGraphicScene;
|
||||||
/**
|
/**
|
||||||
* 处理消息数据
|
* 处理消息数据
|
||||||
* @param data
|
* @param data
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import EventEmitter from 'eventemitter3';
|
import EventEmitter from 'eventemitter3';
|
||||||
import { GraphicApp } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { GraphicState } from '../core';
|
import { GraphicState } from '../core';
|
||||||
import {
|
import {
|
||||||
IMessageHandler,
|
IMessageHandler,
|
||||||
@ -94,6 +94,10 @@ export class WsMsgCli {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static isInitiated(): boolean {
|
||||||
|
return !!WsMsgCli.client;
|
||||||
|
}
|
||||||
|
|
||||||
static emitConnectStateChangeEvent(connected: boolean) {
|
static emitConnectStateChangeEvent(connected: boolean) {
|
||||||
WsMsgCli.appMsgBroker.forEach((broker) => {
|
WsMsgCli.appMsgBroker.forEach((broker) => {
|
||||||
broker.app.emit('websocket-connect-state-change', connected);
|
broker.app.emit('websocket-connect-state-change', connected);
|
||||||
@ -167,16 +171,16 @@ export interface AppStateSubscription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class AppMessageHandler implements IMessageHandler {
|
class AppMessageHandler implements IMessageHandler {
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
sub: AppStateSubscription;
|
sub: AppStateSubscription;
|
||||||
constructor(app: GraphicApp, subOptions: AppStateSubscription) {
|
constructor(app: IGraphicScene, subOptions: AppStateSubscription) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
if (!subOptions.messageConverter && !subOptions.messageHandle) {
|
if (!subOptions.messageConverter && !subOptions.messageHandle) {
|
||||||
throw new Error(`没有消息处理器或图形状态消息转换器: ${subOptions}`);
|
throw new Error(`没有消息处理器或图形状态消息转换器: ${subOptions}`);
|
||||||
}
|
}
|
||||||
this.sub = subOptions;
|
this.sub = subOptions;
|
||||||
}
|
}
|
||||||
get App(): GraphicApp {
|
get App(): IGraphicScene {
|
||||||
return this.app;
|
return this.app;
|
||||||
}
|
}
|
||||||
handle(data: any): void {
|
handle(data: any): void {
|
||||||
@ -194,13 +198,13 @@ class AppMessageHandler implements IMessageHandler {
|
|||||||
* 图形APP的websocket消息代理
|
* 图形APP的websocket消息代理
|
||||||
*/
|
*/
|
||||||
export class AppWsMsgBroker {
|
export class AppWsMsgBroker {
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
subscriptions: Map<string, AppMessageHandler> = new Map<
|
subscriptions: Map<string, AppMessageHandler> = new Map<
|
||||||
string,
|
string,
|
||||||
AppMessageHandler
|
AppMessageHandler
|
||||||
>();
|
>();
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
WsMsgCli.registerAppMsgBroker(this);
|
WsMsgCli.registerAppMsgBroker(this);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { GraphicApp } from '../app/JlGraphicApp';
|
import { IGraphicApp } from '../app/JlGraphicApp';
|
||||||
import { JlGraphic } from '../core/JlGraphic';
|
import { JlGraphic } from '../core/JlGraphic';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7,12 +7,12 @@ import { JlGraphic } from '../core/JlGraphic';
|
|||||||
*/
|
*/
|
||||||
export abstract class JlOperation {
|
export abstract class JlOperation {
|
||||||
type: string; // 操作类型/名称
|
type: string; // 操作类型/名称
|
||||||
app: GraphicApp;
|
app: IGraphicApp;
|
||||||
obj?: any; // 操作对象
|
obj?: any; // 操作对象
|
||||||
data?: any; // 操作数据
|
data?: any; // 操作数据
|
||||||
description?: string = ''; // 操作描述
|
description?: string = ''; // 操作描述
|
||||||
|
|
||||||
constructor(app: GraphicApp, type: string) {
|
constructor(app: IGraphicApp, type: string) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
@ -1,31 +1,49 @@
|
|||||||
import { GraphicApp } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { GraphicAnimation, JlGraphic } from '../core';
|
import { GraphicAnimation, JlGraphic } from '../core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 图形动画管理
|
* 图形动画管理
|
||||||
*/
|
*/
|
||||||
export class AnimationManager {
|
export class AnimationManager {
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
|
_pause: boolean;
|
||||||
|
/**
|
||||||
|
* key - graphic.id
|
||||||
|
*/
|
||||||
graphicAnimationMap: Map<string, Map<string, GraphicAnimation>>;
|
graphicAnimationMap: Map<string, Map<string, GraphicAnimation>>;
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
|
this._pause = false;
|
||||||
this.graphicAnimationMap = new Map<string, Map<string, GraphicAnimation>>();
|
this.graphicAnimationMap = new Map<string, Map<string, GraphicAnimation>>();
|
||||||
// 动画控制
|
// 动画控制
|
||||||
app.app.ticker.add((dt: number) => {
|
app.pixi.ticker.add(this.run, this);
|
||||||
this.graphicAnimationMap.forEach((map) => {
|
}
|
||||||
map.forEach((animation) => {
|
|
||||||
if (animation.running) {
|
private run(dt: number) {
|
||||||
animation.run(dt);
|
if (this._pause) {
|
||||||
}
|
// 暂停
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
this.graphicAnimationMap.forEach((map) => {
|
||||||
|
map.forEach((animation) => {
|
||||||
|
if (animation.running) {
|
||||||
|
animation.run(dt);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static new(app: GraphicApp): AnimationManager {
|
pause() {
|
||||||
return new AnimationManager(app);
|
this._pause = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resume() {
|
||||||
|
this._pause = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.app.pixi.ticker.remove(this.run, this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 图形对象的所有动画map
|
* 图形对象的所有动画map
|
||||||
* @param graphic
|
* @param graphic
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { DisplayObject, FederatedMouseEvent, Graphics, Point } from 'pixi.js';
|
import { DisplayObject, FederatedMouseEvent, Graphics, Point } from 'pixi.js';
|
||||||
import { GraphicApp, JlCanvas } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { JlGraphic } from '../core';
|
import { JlGraphic } from '../core';
|
||||||
import {
|
import {
|
||||||
AppDragEvent,
|
AppDragEvent,
|
||||||
@ -73,7 +73,7 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
|
|
||||||
rightTarget: DisplayObject | null = null;
|
rightTarget: DisplayObject | null = null;
|
||||||
|
|
||||||
constructor(graphicApp: GraphicApp) {
|
constructor(graphicApp: IGraphicScene) {
|
||||||
super(CommonMouseTool.Name, graphicApp);
|
super(CommonMouseTool.Name, graphicApp);
|
||||||
this.options = new CompleteMouseToolOptions();
|
this.options = new CompleteMouseToolOptions();
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static new(app: GraphicApp) {
|
static new(app: IGraphicScene) {
|
||||||
return new CommonMouseTool(app);
|
return new CommonMouseTool(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,19 +173,20 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setCursor(e: FederatedMouseEvent) {
|
setCursor(e: FederatedMouseEvent) {
|
||||||
this.rightTarget = e.target as DisplayObject;
|
const target = e.target as DisplayObject;
|
||||||
if (e.target instanceof JlCanvas && this.app.app.view.style) {
|
this.rightTarget = target;
|
||||||
this.app.app.view.style.cursor = 'grab';
|
if (target.isCanvas() && this.app.pixi.view.style) {
|
||||||
|
this.app.pixi.view.style.cursor = 'grab';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resumeCursor() {
|
resumeCursor() {
|
||||||
if (
|
if (
|
||||||
this.rightTarget &&
|
this.rightTarget &&
|
||||||
this.rightTarget instanceof JlCanvas &&
|
this.rightTarget.isCanvas() &&
|
||||||
this.app.app.view.style
|
this.app.pixi.view.style
|
||||||
) {
|
) {
|
||||||
this.app.app.view.style.cursor = 'inherit';
|
this.app.pixi.view.style.cursor = 'inherit';
|
||||||
}
|
}
|
||||||
this.rightTarget = null;
|
this.rightTarget = null;
|
||||||
}
|
}
|
||||||
@ -248,7 +249,7 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// 非多选
|
// 非多选
|
||||||
if (e.target instanceof JlCanvas) {
|
if ((e.target as DisplayObject).isCanvas()) {
|
||||||
this.app.updateSelected();
|
this.app.updateSelected();
|
||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
import { Container, FederatedPointerEvent, Point } from 'pixi.js';
|
import { Container, FederatedPointerEvent, Point } from 'pixi.js';
|
||||||
import { GraphicApp, GraphicCreateOperation } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { JlGraphic } from '../core';
|
import { JlGraphic } from '../core';
|
||||||
import { KeyListener } from './KeyboardPlugin';
|
import { KeyListener } from './KeyboardPlugin';
|
||||||
|
|
||||||
export class GraphicCopyPlugin {
|
export class GraphicCopyPlugin {
|
||||||
container: Container;
|
container: Container;
|
||||||
app: GraphicApp;
|
scene: IGraphicScene;
|
||||||
keyListeners: KeyListener[];
|
keyListeners: KeyListener[];
|
||||||
copys: JlGraphic[];
|
copys: JlGraphic[];
|
||||||
start?: Point;
|
start?: Point;
|
||||||
running = false;
|
running = false;
|
||||||
moveLimit?: 'x' | 'y';
|
moveLimit?: 'x' | 'y';
|
||||||
constructor(app: GraphicApp) {
|
constructor(scene: IGraphicScene) {
|
||||||
this.app = app;
|
this.scene = scene;
|
||||||
this.container = new Container();
|
this.container = new Container();
|
||||||
this.copys = [];
|
this.copys = [];
|
||||||
this.keyListeners = [];
|
this.keyListeners = [];
|
||||||
@ -57,15 +57,15 @@ export class GraphicCopyPlugin {
|
|||||||
|
|
||||||
init(): void {
|
init(): void {
|
||||||
if (this.running) return;
|
if (this.running) return;
|
||||||
if (this.app.selectedGraphics.length === 0) {
|
if (this.scene.selectedGraphics.length === 0) {
|
||||||
throw new Error('没有选中图形,复制取消');
|
throw new Error('没有选中图形,复制取消');
|
||||||
}
|
}
|
||||||
this.running = true;
|
this.running = true;
|
||||||
this.copys = [];
|
this.copys = [];
|
||||||
this.container.alpha = 0.5;
|
this.container.alpha = 0.5;
|
||||||
this.app.canvas.addChild(this.container);
|
this.scene.canvas.addChild(this.container);
|
||||||
const app = this.app;
|
const app = this.scene;
|
||||||
this.app.selectedGraphics.forEach((g) => {
|
this.scene.selectedGraphics.forEach((g) => {
|
||||||
const template = app.getGraphicTemplatesByType(g.type);
|
const template = app.getGraphicTemplatesByType(g.type);
|
||||||
const clone = template.clone(g);
|
const clone = template.clone(g);
|
||||||
this.copys.push(clone);
|
this.copys.push(clone);
|
||||||
@ -73,11 +73,11 @@ export class GraphicCopyPlugin {
|
|||||||
this.container.addChild(clone);
|
this.container.addChild(clone);
|
||||||
clone.repaint();
|
clone.repaint();
|
||||||
});
|
});
|
||||||
this.app.canvas.on('mousemove', this.onPointerMove, this);
|
this.scene.canvas.on('mousemove', this.onPointerMove, this);
|
||||||
this.app.canvas.on('mouseup', this.onFinish, this);
|
this.scene.canvas.on('mouseup', this.onFinish, this);
|
||||||
this.app.canvas.on('rightup', this.cancle, this);
|
this.scene.canvas.on('rightup', this.cancle, this);
|
||||||
this.keyListeners.forEach((kl) => {
|
this.keyListeners.forEach((kl) => {
|
||||||
this.app.addKeyboardListener(kl);
|
this.scene.app.addKeyboardListener(kl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,17 +87,17 @@ export class GraphicCopyPlugin {
|
|||||||
this.moveLimit = undefined;
|
this.moveLimit = undefined;
|
||||||
this.copys = [];
|
this.copys = [];
|
||||||
this.container.removeChildren();
|
this.container.removeChildren();
|
||||||
this.app.canvas.removeChild(this.container);
|
this.scene.canvas.removeChild(this.container);
|
||||||
this.app.canvas.off('mousemove', this.onPointerMove, this);
|
this.scene.canvas.off('mousemove', this.onPointerMove, this);
|
||||||
this.app.canvas.off('mouseup', this.onFinish, this);
|
this.scene.canvas.off('mouseup', this.onFinish, this);
|
||||||
this.app.canvas.off('rightup', this.cancle, this);
|
this.scene.canvas.off('rightup', this.cancle, this);
|
||||||
this.keyListeners.forEach((kl) => {
|
this.keyListeners.forEach((kl) => {
|
||||||
this.app.removeKeyboardListener(kl);
|
this.scene.app.removeKeyboardListener(kl);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onPointerMove(e: FederatedPointerEvent): void {
|
onPointerMove(e: FederatedPointerEvent): void {
|
||||||
const cp = this.app.toCanvasCoordinates(e.global);
|
const cp = this.scene.toCanvasCoordinates(e.global);
|
||||||
if (!this.start) {
|
if (!this.start) {
|
||||||
this.start = cp;
|
this.start = cp;
|
||||||
} else {
|
} else {
|
||||||
@ -125,17 +125,15 @@ export class GraphicCopyPlugin {
|
|||||||
g.position.x += this.container.position.x;
|
g.position.x += this.container.position.x;
|
||||||
g.position.y += this.container.position.y;
|
g.position.y += this.container.position.y;
|
||||||
});
|
});
|
||||||
this.app.addGraphics(...this.copys);
|
this.scene.app.addGraphicAndRecord(...this.copys);
|
||||||
// 创建图形对象操作记录
|
this.scene.detectRelations();
|
||||||
this.app.opRecord.record(new GraphicCreateOperation(this.app, this.copys));
|
this.scene.updateSelected(...this.copys);
|
||||||
this.app.detectRelations();
|
|
||||||
this.app.updateSelected(...this.copys);
|
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
cancle(): void {
|
cancle(): void {
|
||||||
console.log('复制操作取消');
|
console.log('复制操作取消');
|
||||||
this.app.canvas.removeChild(this.container);
|
this.scene.canvas.removeChild(this.container);
|
||||||
this.clear();
|
this.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import {
|
|||||||
InteractionPluginType,
|
InteractionPluginType,
|
||||||
KeyListener,
|
KeyListener,
|
||||||
} from '.';
|
} from '.';
|
||||||
import { GraphicApp } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { JlGraphic } from '../core';
|
import { JlGraphic } from '../core';
|
||||||
import { AbsorbablePosition, VectorText } from '../graphic';
|
import { AbsorbablePosition, VectorText } from '../graphic';
|
||||||
import { DraggablePoint } from '../graphic/DraggablePoint';
|
import { DraggablePoint } from '../graphic/DraggablePoint';
|
||||||
@ -164,7 +164,7 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
apContainer: Container;
|
apContainer: Container;
|
||||||
static AbsorbablePosisiontsName = '__AbsorbablePosisionts';
|
static AbsorbablePosisiontsName = '__AbsorbablePosisionts';
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
super(app, GraphicTransformPlugin.Name, InteractionPluginType.Other);
|
super(app, GraphicTransformPlugin.Name, InteractionPluginType.Other);
|
||||||
this.apContainer = new Container();
|
this.apContainer = new Container();
|
||||||
this.apContainer.name = GraphicTransformPlugin.AbsorbablePosisiontsName;
|
this.apContainer.name = GraphicTransformPlugin.AbsorbablePosisiontsName;
|
||||||
@ -205,7 +205,7 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
return aps;
|
return aps;
|
||||||
}
|
}
|
||||||
|
|
||||||
static new(app: GraphicApp) {
|
static new(app: IGraphicScene) {
|
||||||
return new GraphicTransformPlugin(app);
|
return new GraphicTransformPlugin(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,11 @@ import {
|
|||||||
FederatedPointerEvent,
|
FederatedPointerEvent,
|
||||||
Point,
|
Point,
|
||||||
} from 'pixi.js';
|
} from 'pixi.js';
|
||||||
import { GraphicApp, IGraphicAppConfig } from '../app/JlGraphicApp';
|
import {
|
||||||
|
IGraphicApp,
|
||||||
|
IGraphicAppConfig,
|
||||||
|
IGraphicScene,
|
||||||
|
} from '../app/JlGraphicApp';
|
||||||
import { JlGraphic } from '../core/JlGraphic';
|
import { JlGraphic } from '../core/JlGraphic';
|
||||||
|
|
||||||
export enum InteractionPluginType {
|
export enum InteractionPluginType {
|
||||||
@ -19,7 +23,7 @@ export enum InteractionPluginType {
|
|||||||
export interface InteractionPlugin {
|
export interface InteractionPlugin {
|
||||||
readonly _type: string;
|
readonly _type: string;
|
||||||
name: string; // 唯一标识
|
name: string; // 唯一标识
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 恢复
|
* 恢复
|
||||||
@ -41,10 +45,10 @@ export interface InteractionPlugin {
|
|||||||
export abstract class InteractionPluginBase implements InteractionPlugin {
|
export abstract class InteractionPluginBase implements InteractionPlugin {
|
||||||
readonly _type: string;
|
readonly _type: string;
|
||||||
name: string; // 唯一标识
|
name: string; // 唯一标识
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
_pause: boolean;
|
_pause: boolean;
|
||||||
|
|
||||||
constructor(app: GraphicApp, name: string, type: string) {
|
constructor(app: IGraphicScene, name: string, type: string) {
|
||||||
this._type = type;
|
this._type = type;
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
@ -89,19 +93,19 @@ export abstract class InteractionPluginBase implements InteractionPlugin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export abstract class OtherInteractionPlugin extends InteractionPluginBase {
|
export abstract class OtherInteractionPlugin extends InteractionPluginBase {
|
||||||
constructor(app: GraphicApp, name: string) {
|
constructor(app: IGraphicScene, name: string) {
|
||||||
super(app, name, InteractionPluginType.Other);
|
super(app, name, InteractionPluginType.Other);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppDragEvent {
|
export class AppDragEvent {
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
type: 'start' | 'move' | 'end';
|
type: 'start' | 'move' | 'end';
|
||||||
target: DisplayObject;
|
target: DisplayObject;
|
||||||
original: FederatedPointerEvent;
|
original: FederatedPointerEvent;
|
||||||
start: Point; // 画布坐标
|
start: Point; // 画布坐标
|
||||||
constructor(
|
constructor(
|
||||||
app: GraphicApp,
|
app: IGraphicScene,
|
||||||
type: 'start' | 'move' | 'end',
|
type: 'start' | 'move' | 'end',
|
||||||
target: DisplayObject,
|
target: DisplayObject,
|
||||||
original: FederatedPointerEvent,
|
original: FederatedPointerEvent,
|
||||||
@ -191,7 +195,7 @@ export class DragPlugin extends OtherInteractionPlugin {
|
|||||||
start: Point | null = null;
|
start: Point | null = null;
|
||||||
startClientPoint: Point | null = null;
|
startClientPoint: Point | null = null;
|
||||||
drag = false;
|
drag = false;
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
super(app, DragPlugin.Name);
|
super(app, DragPlugin.Name);
|
||||||
app.on('options-update', (options: IGraphicAppConfig) => {
|
app.on('options-update', (options: IGraphicAppConfig) => {
|
||||||
if (options.threshold !== undefined) {
|
if (options.threshold !== undefined) {
|
||||||
@ -199,7 +203,7 @@ export class DragPlugin extends OtherInteractionPlugin {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static new(app: GraphicApp) {
|
static new(app: IGraphicScene) {
|
||||||
return new DragPlugin(app);
|
return new DragPlugin(app);
|
||||||
}
|
}
|
||||||
bind(): void {
|
bind(): void {
|
||||||
@ -301,11 +305,11 @@ export class ViewportMovePlugin extends OtherInteractionPlugin {
|
|||||||
moveSpeedx = 0;
|
moveSpeedx = 0;
|
||||||
moveSpeedy = 0;
|
moveSpeedy = 0;
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
super(app, ViewportMovePlugin.Name);
|
super(app, ViewportMovePlugin.Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static new(app: GraphicApp): ViewportMovePlugin {
|
static new(app: IGraphicScene): ViewportMovePlugin {
|
||||||
return new ViewportMovePlugin(app);
|
return new ViewportMovePlugin(app);
|
||||||
}
|
}
|
||||||
pause(): void {
|
pause(): void {
|
||||||
@ -393,7 +397,7 @@ export class ViewportMovePlugin extends OtherInteractionPlugin {
|
|||||||
* 应用交互插件,同时只能生效一个
|
* 应用交互插件,同时只能生效一个
|
||||||
*/
|
*/
|
||||||
export abstract class AppInteractionPlugin extends InteractionPluginBase {
|
export abstract class AppInteractionPlugin extends InteractionPluginBase {
|
||||||
constructor(name: string, app: GraphicApp) {
|
constructor(name: string, app: IGraphicScene) {
|
||||||
super(app, name, InteractionPluginType.App);
|
super(app, name, InteractionPluginType.App);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,10 +417,10 @@ export abstract class GraphicInteractionPlugin<G extends JlGraphic>
|
|||||||
implements InteractionPlugin
|
implements InteractionPlugin
|
||||||
{
|
{
|
||||||
readonly _type = InteractionPluginType.Graphic;
|
readonly _type = InteractionPluginType.Graphic;
|
||||||
app: GraphicApp;
|
app: IGraphicApp;
|
||||||
name: string; // 唯一标识
|
name: string; // 唯一标识
|
||||||
_pause: boolean;
|
_pause: boolean;
|
||||||
constructor(name: string, app: GraphicApp) {
|
constructor(name: string, app: IGraphicApp) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this._pause = true;
|
this._pause = true;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { GraphicApp } from '../app/JlGraphicApp';
|
import { IGraphicApp } from '../app/JlGraphicApp';
|
||||||
|
|
||||||
let target: Node | undefined;
|
let target: Node | undefined;
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ export class GlobalKeyboardHelper {
|
|||||||
const GlobalKeyboardPlugin = new GlobalKeyboardHelper();
|
const GlobalKeyboardPlugin = new GlobalKeyboardHelper();
|
||||||
|
|
||||||
export class JlGraphicAppKeyboardPlugin {
|
export class JlGraphicAppKeyboardPlugin {
|
||||||
app: GraphicApp;
|
app: IGraphicApp;
|
||||||
/**
|
/**
|
||||||
* 结构为Map<key.code|key.key|key.keyCode, Map<KeyListener.identifier, KeyListener>>
|
* 结构为Map<key.code|key.key|key.keyCode, Map<KeyListener.identifier, KeyListener>>
|
||||||
*/
|
*/
|
||||||
@ -75,7 +75,7 @@ export class JlGraphicAppKeyboardPlugin {
|
|||||||
KeyListener[]
|
KeyListener[]
|
||||||
>(); // 键值监听栈(多次注册相同的监听会把之前注册的监听器入栈,移除最新的监听会从栈中弹出一个作为指定事件监听处理器)
|
>(); // 键值监听栈(多次注册相同的监听会把之前注册的监听器入栈,移除最新的监听会从栈中弹出一个作为指定事件监听处理器)
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicApp) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
GlobalKeyboardPlugin.registerGAKPlugin(this);
|
GlobalKeyboardPlugin.registerGAKPlugin(this);
|
||||||
const onMouseUpdateTarget = (e: MouseEvent) => {
|
const onMouseUpdateTarget = (e: MouseEvent) => {
|
||||||
@ -85,7 +85,7 @@ export class JlGraphicAppKeyboardPlugin {
|
|||||||
};
|
};
|
||||||
const keydownHandle = (e: KeyboardEvent) => {
|
const keydownHandle = (e: KeyboardEvent) => {
|
||||||
// console.debug(e.key, e.code, e.keyCode);
|
// console.debug(e.key, e.code, e.keyCode);
|
||||||
if (target && target == this.app.dom.getElementsByTagName('canvas')[0]) {
|
if (target && target == this.app.dom?.getElementsByTagName('canvas')[0]) {
|
||||||
const listenerMap = this.getKeyListener(e);
|
const listenerMap = this.getKeyListener(e);
|
||||||
listenerMap?.forEach((listener) => {
|
listenerMap?.forEach((listener) => {
|
||||||
if (!listener.global) {
|
if (!listener.global) {
|
||||||
@ -95,7 +95,7 @@ export class JlGraphicAppKeyboardPlugin {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
const keyupHandle = (e: KeyboardEvent) => {
|
const keyupHandle = (e: KeyboardEvent) => {
|
||||||
if (target && target == this.app.dom.getElementsByTagName('canvas')[0]) {
|
if (target && target == this.app.dom?.getElementsByTagName('canvas')[0]) {
|
||||||
const listenerMap = this.getKeyListener(e);
|
const listenerMap = this.getKeyListener(e);
|
||||||
listenerMap?.forEach((listener) => {
|
listenerMap?.forEach((listener) => {
|
||||||
if (!listener.global) {
|
if (!listener.global) {
|
||||||
@ -202,7 +202,7 @@ export class JlGraphicAppKeyboardPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyboardKeyHandler = (e: KeyboardEvent, app: GraphicApp) => void;
|
type KeyboardKeyHandler = (e: KeyboardEvent, app: IGraphicApp) => void;
|
||||||
|
|
||||||
export enum CombinationKey {
|
export enum CombinationKey {
|
||||||
Ctrl = 'Ctrl',
|
Ctrl = 'Ctrl',
|
||||||
@ -300,7 +300,7 @@ export class KeyListener {
|
|||||||
this.options.pressTriggerAsOriginalEvent = v;
|
this.options.pressTriggerAsOriginalEvent = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
press(e: KeyboardEvent, app: GraphicApp): void {
|
press(e: KeyboardEvent, app: IGraphicApp): void {
|
||||||
if (!this.checkCombinations(e)) {
|
if (!this.checkCombinations(e)) {
|
||||||
console.debug('组合键不匹配, 不执行press', e, this);
|
console.debug('组合键不匹配, 不执行press', e, this);
|
||||||
return;
|
return;
|
||||||
@ -335,7 +335,7 @@ export class KeyListener {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
release(e: KeyboardEvent, app: GraphicApp): void {
|
release(e: KeyboardEvent, app: IGraphicApp): void {
|
||||||
if (this.isPress) {
|
if (this.isPress) {
|
||||||
// console.log('Keyup : ', e.key, e);
|
// console.log('Keyup : ', e.key, e);
|
||||||
this.isPress = false;
|
this.isPress = false;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { Color, Container, Graphics, Point, Rectangle, Text } from 'pixi.js';
|
import { Color, Container, Graphics, Point, Rectangle, Text } from 'pixi.js';
|
||||||
import { GraphicApp } from '../app';
|
import { IGraphicScene } from '../app';
|
||||||
import { OutOfBound } from '../utils';
|
import { OutOfBound } from '../utils';
|
||||||
import {
|
import {
|
||||||
DefaultWhiteMenuOptions,
|
DefaultWhiteMenuOptions,
|
||||||
@ -12,10 +12,10 @@ import {
|
|||||||
} from './Menu';
|
} from './Menu';
|
||||||
|
|
||||||
export class ContextMenuPlugin {
|
export class ContextMenuPlugin {
|
||||||
app: GraphicApp;
|
app: IGraphicScene;
|
||||||
contextMenuMap: Map<string, ContextMenu> = new Map<string, ContextMenu>();
|
contextMenuMap: Map<string, ContextMenu> = new Map<string, ContextMenu>();
|
||||||
|
|
||||||
constructor(app: GraphicApp) {
|
constructor(app: IGraphicScene) {
|
||||||
this.app = app;
|
this.app = app;
|
||||||
const canvas = this.app.canvas;
|
const canvas = this.app.canvas;
|
||||||
canvas.on('pointerdown', () => {
|
canvas.on('pointerdown', () => {
|
||||||
@ -52,7 +52,7 @@ export class ContextMenuPlugin {
|
|||||||
open(menu: ContextMenu, global: Point) {
|
open(menu: ContextMenu, global: Point) {
|
||||||
if (!menu.opened) {
|
if (!menu.opened) {
|
||||||
menu.opened = true;
|
menu.opened = true;
|
||||||
this.app.app.stage.addChild(menu);
|
this.app.pixi.stage.addChild(menu);
|
||||||
}
|
}
|
||||||
// 处理超出显示范围
|
// 处理超出显示范围
|
||||||
const screenHeight = this.screenHeight;
|
const screenHeight = this.screenHeight;
|
||||||
@ -88,7 +88,7 @@ export class ContextMenuPlugin {
|
|||||||
close(menu: ContextMenu) {
|
close(menu: ContextMenu) {
|
||||||
if (menu.opened) {
|
if (menu.opened) {
|
||||||
menu.opened = false;
|
menu.opened = false;
|
||||||
this.app.app.stage.removeChild(menu);
|
this.app.pixi.stage.removeChild(menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
@ -453,6 +453,12 @@ class MenuGroup extends Container {
|
|||||||
this.config.items.forEach((item) => {
|
this.config.items.forEach((item) => {
|
||||||
this.items.push(new ContextMenuItem(this.menu, item));
|
this.items.push(new ContextMenuItem(this.menu, item));
|
||||||
});
|
});
|
||||||
|
if (this.items.length === 0) {
|
||||||
|
console.error('菜单group为空', this.config, this.menu);
|
||||||
|
throw new Error(
|
||||||
|
`{name=${this.menu.name}}的菜单的group为{name=${this.config.name}}的条目为空!`
|
||||||
|
);
|
||||||
|
}
|
||||||
this.addChild(...this.items);
|
this.addChild(...this.items);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user