diff --git a/package.json b/package.json index 2ebe69b..80d4257 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "build": "quasar build" }, "dependencies": { + "@pixi/graphics-extras": "^7.2.4", "@quasar/extras": "^1.0.0", "@stomp/stompjs": "^7.0.0", "google-protobuf": "^3.21.2", diff --git a/quasar.config.js b/quasar.config.js index 6d7aa33..c8f1936 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -28,7 +28,7 @@ module.exports = configure(function (/* ctx */) { // app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli-vite/boot-files - boot: [], + boot: ['@pixi/graphics-extras'], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css css: ['app.scss'], diff --git a/src/boot/@pixi/graphics-extras.ts b/src/boot/@pixi/graphics-extras.ts new file mode 100644 index 0000000..4a70eb8 --- /dev/null +++ b/src/boot/@pixi/graphics-extras.ts @@ -0,0 +1,7 @@ +import { boot } from 'quasar/wrappers'; +import * as GraphicsExtras from '@pixi/graphics-extras'; +// "async" is optional; +// more info on params: https://v2.quasar.dev/quasar-cli/boot-files +export default boot(async (/* { app, router, ... } */) => { + GraphicsExtras; +}); diff --git a/src/examples/app/app_message/protos/draw_data_storage.proto b/src/examples/app/app_message/protos/draw_data_storage.proto index 9a55916..3ded330 100644 --- a/src/examples/app/app_message/protos/draw_data_storage.proto +++ b/src/examples/app/app_message/protos/draw_data_storage.proto @@ -131,8 +131,4 @@ message Turnout {} message Signal { CommonInfo common = 1; string code = 2; - string codeColor = 3; // 信号机字体颜色 - int32 codeFontSize = 4; // 信号机字体大小 - Point point = 5; // 位置坐标 - string direction = 6; //信号机朝向 } diff --git a/src/examples/app/graphics/GraphicDataBase.ts b/src/examples/app/graphics/GraphicDataBase.ts index e004380..26cd669 100644 --- a/src/examples/app/graphics/GraphicDataBase.ts +++ b/src/examples/app/graphics/GraphicDataBase.ts @@ -27,10 +27,10 @@ export abstract class GraphicDataBase implements GraphicData { this._data = data; } - static defaultCommonInfo(): graphicData.CommonInfo { + static defaultCommonInfo(graphicType: string): graphicData.CommonInfo { return new graphicData.CommonInfo({ id: '', - graphicType: '', + graphicType: graphicType, transform: new graphicData.Transform({ position: new graphicData.Point({ x: 0, y: 0 }), scale: new graphicData.Point({ x: 1, y: 1 }), diff --git a/src/examples/app/graphics/SignalInteraction.ts b/src/examples/app/graphics/SignalInteraction.ts index 6ff2540..78fb97f 100644 --- a/src/examples/app/graphics/SignalInteraction.ts +++ b/src/examples/app/graphics/SignalInteraction.ts @@ -1,6 +1,5 @@ import * as pb_1 from 'google-protobuf'; -import { IPointData } from 'pixi.js'; -import { ISignalData } from 'src/graphics/signal/Signal'; +import { ISignalData, Signal } from 'src/graphics/signal/Signal'; import { graphicData } from '../protos/draw_data_storage'; import { GraphicDataBase } from './GraphicDataBase'; @@ -9,7 +8,7 @@ export class SignalData extends GraphicDataBase implements ISignalData { let signal; if (!data) { signal = new graphicData.Signal({ - common: GraphicDataBase.defaultCommonInfo(), + common: GraphicDataBase.defaultCommonInfo(Signal.Type), }); } else { signal = data; @@ -26,30 +25,6 @@ export class SignalData extends GraphicDataBase implements ISignalData { set code(v: string) { this.data.code = v; } - get codeColor(): string { - return this.data.codeColor; - } - set codeColor(v: string) { - this.data.codeColor = v; - } - get codeFontSize(): number { - return this.data.codeFontSize; - } - set codeFontSize(v: number) { - this.data.codeFontSize = v; - } - get point(): IPointData { - return this.data.point; - } - set point(point: IPointData) { - this.data.point = new graphicData.Point({ x: point.x, y: point.y }); - } - get direction(): string { - return this.data.direction; - } - set direction(v: string) { - this.data.direction = v; - } clone(): SignalData { return new SignalData(this.data.cloneMessage()); } diff --git a/src/examples/app/index.ts b/src/examples/app/index.ts index 947e88d..4895b10 100644 --- a/src/examples/app/index.ts +++ b/src/examples/app/index.ts @@ -106,18 +106,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp { new LinkDraw(app, () => { return new LinkData(); }), - new RectDraw(app, () => { - return new RectData(); - }), new IscsFanDraw(app, () => { return new IscsFanData(); }), - new PlatformDraw(app, () => { - return new PlatformData(); - }), - new StationDraw(app, () => { - return new StationData(); - }), new SignalDraw(app, () => { return new SignalData(); }), diff --git a/src/examples/app/protos/draw_data_storage.ts b/src/examples/app/protos/draw_data_storage.ts index 4ef1320..5467429 100644 --- a/src/examples/app/protos/draw_data_storage.ts +++ b/src/examples/app/protos/draw_data_storage.ts @@ -2334,10 +2334,6 @@ export namespace graphicData { constructor(data?: any[] | { common?: CommonInfo; code?: string; - codeColor?: string; - codeFontSize?: number; - point?: Point; - direction?: string; }) { super(); pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls); @@ -2348,18 +2344,6 @@ export namespace graphicData { if ("code" in data && data.code != undefined) { this.code = data.code; } - if ("codeColor" in data && data.codeColor != undefined) { - this.codeColor = data.codeColor; - } - if ("codeFontSize" in data && data.codeFontSize != undefined) { - this.codeFontSize = data.codeFontSize; - } - if ("point" in data && data.point != undefined) { - this.point = data.point; - } - if ("direction" in data && data.direction != undefined) { - this.direction = data.direction; - } } } get common() { @@ -2377,40 +2361,9 @@ export namespace graphicData { set code(value: string) { pb_1.Message.setField(this, 2, value); } - get codeColor() { - return pb_1.Message.getFieldWithDefault(this, 3, "") as string; - } - set codeColor(value: string) { - pb_1.Message.setField(this, 3, value); - } - get codeFontSize() { - return pb_1.Message.getFieldWithDefault(this, 4, 0) as number; - } - set codeFontSize(value: number) { - pb_1.Message.setField(this, 4, value); - } - get point() { - return pb_1.Message.getWrapperField(this, Point, 5) as Point; - } - set point(value: Point) { - pb_1.Message.setWrapperField(this, 5, value); - } - get has_point() { - return pb_1.Message.getField(this, 5) != null; - } - get direction() { - return pb_1.Message.getFieldWithDefault(this, 6, "") as string; - } - set direction(value: string) { - pb_1.Message.setField(this, 6, value); - } static fromObject(data: { common?: ReturnType; code?: string; - codeColor?: string; - codeFontSize?: number; - point?: ReturnType; - direction?: string; }): Signal { const message = new Signal({}); if (data.common != null) { @@ -2419,28 +2372,12 @@ export namespace graphicData { if (data.code != null) { message.code = data.code; } - if (data.codeColor != null) { - message.codeColor = data.codeColor; - } - if (data.codeFontSize != null) { - message.codeFontSize = data.codeFontSize; - } - if (data.point != null) { - message.point = Point.fromObject(data.point); - } - if (data.direction != null) { - message.direction = data.direction; - } return message; } toObject() { const data: { common?: ReturnType; code?: string; - codeColor?: string; - codeFontSize?: number; - point?: ReturnType; - direction?: string; } = {}; if (this.common != null) { data.common = this.common.toObject(); @@ -2448,18 +2385,6 @@ export namespace graphicData { if (this.code != null) { data.code = this.code; } - if (this.codeColor != null) { - data.codeColor = this.codeColor; - } - if (this.codeFontSize != null) { - data.codeFontSize = this.codeFontSize; - } - if (this.point != null) { - data.point = this.point.toObject(); - } - if (this.direction != null) { - data.direction = this.direction; - } return data; } serialize(): Uint8Array; @@ -2470,14 +2395,6 @@ export namespace graphicData { writer.writeMessage(1, this.common, () => this.common.serialize(writer)); if (this.code.length) writer.writeString(2, this.code); - if (this.codeColor.length) - writer.writeString(3, this.codeColor); - if (this.codeFontSize != 0) - writer.writeInt32(4, this.codeFontSize); - if (this.has_point) - writer.writeMessage(5, this.point, () => this.point.serialize(writer)); - if (this.direction.length) - writer.writeString(6, this.direction); if (!w) return writer.getResultBuffer(); } @@ -2493,18 +2410,6 @@ export namespace graphicData { case 2: message.code = reader.readString(); break; - case 3: - message.codeColor = reader.readString(); - break; - case 4: - message.codeFontSize = reader.readInt32(); - break; - case 5: - reader.readMessage(message.point, () => message.point = Point.deserialize(reader)); - break; - case 6: - message.direction = reader.readString(); - break; default: reader.skipField(); } } diff --git a/src/graphics/CommonGraphics.ts b/src/graphics/CommonGraphics.ts new file mode 100644 index 0000000..60e935f --- /dev/null +++ b/src/graphics/CommonGraphics.ts @@ -0,0 +1,51 @@ +import { Graphics } from 'pixi.js'; +export function drawArrow( + polygon: Graphics, + x: number, + y: number, + length: number, + radius: number, + lineWidth: number +) { + const trianglAcme = { x, y }; + const triangleP1 = { + x: x - radius - Math.sin(Math.PI / 6), + y: y + Math.cos(Math.PI / 6) * radius, + }; + const triangleP2 = { + x: x - radius - Math.sin(Math.PI / 6), + y: y - Math.cos(Math.PI / 6) * radius, + }; + const lineP1 = { + x: x - radius - Math.sin(Math.PI / 6), + y: y + lineWidth / 2, + }; + const lineP2 = { + x: x - length, + y: y + lineWidth / 2, + }; + const lineP3 = { + x: x - length, + y: y - lineWidth / 2, + }; + const lineP4 = { + x: x - radius - Math.sin(Math.PI / 6), + y: y - lineWidth / 2, + }; + polygon.drawPolygon( + trianglAcme.x, + trianglAcme.y, + triangleP1.x, + triangleP1.y, + lineP1.x, + lineP1.y, + lineP2.x, + lineP2.y, + lineP3.x, + lineP3.y, + lineP4.x, + lineP4.y, + triangleP2.x, + triangleP2.y + ); +} diff --git a/src/graphics/signal/Lamp.ts b/src/graphics/signal/Lamp.ts new file mode 100644 index 0000000..1b0d564 --- /dev/null +++ b/src/graphics/signal/Lamp.ts @@ -0,0 +1,52 @@ +import { Container } from '@pixi/display'; +import { Graphics } from 'pixi.js'; + +export enum LampEnum { + lampPostColor = '0xc0c0c0', + lampDefaultColor = '0xff0000', + logicModeColor = '0x000000', +} + +const lampConsts = { + lampRadius: 10, + logicModeLineWidth: 2, + logicModeDistance: 7, +}; + +export class Lamp extends Container { + circleLamp: Graphics = new Graphics(); + logicMode: Graphics = new Graphics(); + + constructor() { + super(); + this.addChild(this.circleLamp); + this.addChild(this.logicMode); + } + paint(radiusX: number, radiusY: number) { + this.circleLamp.clear(); + this.circleLamp + .beginFill(LampEnum.lampDefaultColor, 1) + .drawCircle(radiusX, radiusY, lampConsts.lampRadius) + .endFill(); + + this.logicMode + .clear() + .lineStyle(lampConsts.logicModeLineWidth, LampEnum.logicModeColor) + .moveTo( + radiusX - lampConsts.logicModeDistance, + radiusY + lampConsts.logicModeDistance + ) + .lineTo( + radiusX + lampConsts.logicModeDistance, + radiusY - lampConsts.logicModeDistance + ) + .moveTo( + radiusX - lampConsts.logicModeDistance, + radiusY - lampConsts.logicModeDistance + ) + .lineTo( + radiusX + lampConsts.logicModeDistance, + radiusY + lampConsts.logicModeDistance + ); + } +} diff --git a/src/graphics/signal/LampMainBody.ts b/src/graphics/signal/LampMainBody.ts new file mode 100644 index 0000000..7436303 --- /dev/null +++ b/src/graphics/signal/LampMainBody.ts @@ -0,0 +1,51 @@ +import { Container } from '@pixi/display'; +import { Graphics } from 'pixi.js'; +import { Lamp } from './Lamp'; + +export enum LampEnum { + lampPostColor = '0xc0c0c0', +} + +const lampConsts = { + verticalLampPostLength: 20, + levelLampPostLength: 5, + postLineWidth: 3, + lampRadius: 10, +}; + +export class LampMainBody extends Container { + lampNum = 1; + lampPost: Graphics = new Graphics(); + lamps: Lamp[] = []; + + constructor() { + super(); + } + paint(lampNum: number) { + if (lampNum < 1) { + throw new Error('信号机灯数量异常'); + } + this.lampNum = lampNum; + this.removeChildren(0); + this.lampPost = new Graphics(); + this.lampPost + .lineStyle(lampConsts.postLineWidth, LampEnum.lampPostColor) + .moveTo(0, -lampConsts.verticalLampPostLength / 2) + .lineTo(0, lampConsts.verticalLampPostLength / 2) + .moveTo(0, 0) + .lineTo(lampConsts.levelLampPostLength, 0); + this.addChild(this.lampPost); + + this.lamps = []; + for (let i = 0; i < this.lampNum; i++) { + const lamp = new Lamp(); + const radiusX = + (1 + i * 2) * lampConsts.lampRadius + lampConsts.levelLampPostLength; + lamp.paint(radiusX, 0); + this.addChild(lamp); + this.lamps.push(lamp); + } + } + + // setState() {} +} diff --git a/src/graphics/signal/Signal.ts b/src/graphics/signal/Signal.ts index edabfb3..4c0fa61 100644 --- a/src/graphics/signal/Signal.ts +++ b/src/graphics/signal/Signal.ts @@ -1,190 +1,98 @@ -import { IPointData, Graphics, Color } from 'pixi.js'; +import { Graphics } from 'pixi.js'; import { GraphicData, JlGraphic, JlGraphicTemplate, VectorText, } from 'src/jlgraphic'; +import { LampMainBody } from './LampMainBody'; +import { drawArrow } from '../CommonGraphics'; export interface ISignalData extends GraphicData { get code(): string; // 编号 set code(v: string); - get codeColor(): string; - set codeColor(v: string); - get codeFontSize(): number; - set codeFontSize(v: number); - get point(): IPointData; - set point(point: IPointData); - get direction(): string; - set direction(v: string); clone(): ISignalData; copyFrom(data: ISignalData): void; eq(other: ISignalData): boolean; } -//站台颜色 export enum SignalColorEnum { - lampPostColor = '0xc0c0c0', - lampColor = '0xff0000', humanControlColor = '0xffff00', fleetModeColor = '0x00ff00', - logicModeColor = '0x000000', + codeColor = '0X000000', } const signalConsts = { - verticalLampPostLength: 20, - levelLampPostLength: 5, - lineWidth: 3, - lampRadius: 10, + lampNum: 1, + codeFontSize: 11, nameOffsetY: 20, - humanControlPath: [-2, 0, -17, 10, -17, -10], - logicModeLineWidth: 2, - logicModeDistance: 7, - fleetModePath: [2, -4, 22, -4, 22, -10, 35, 0, 22, 10, 22, 4, 2, 4], + fleetModeLength: 33, + fleetModeRadius: 10, + fleetModeLineWidth: 6, }; export class Signal extends JlGraphic { static Type = 'signal'; codeGraph: VectorText = new VectorText(''); - lampPost: Graphics = new Graphics(); - circularLamp: Graphics = new Graphics(); humanControl: Graphics = new Graphics(); fleetMode: Graphics = new Graphics(); - logicMode: Graphics = new Graphics(); + lampMainBody: LampMainBody = new LampMainBody(); constructor() { super(Signal.Type); + this.codeGraph.name = 'signalCode'; this.addChild(this.codeGraph); - this.addChild(this.lampPost); - this.addChild(this.circularLamp); this.addChild(this.humanControl); this.addChild(this.fleetMode); - this.addChild(this.logicMode); + this.addChild(this.lampMainBody); } get datas(): ISignalData { return this.getDatas(); } - doRepaint(): void { - console.log(this.datas, 'this.datas'); - const codeGraph = this.codeGraph; - this.lampPost.clear(); - this.lampPost.lineStyle( - signalConsts.lineWidth, - new Color(SignalColorEnum.lampPostColor) - ); - this.lampPost.moveTo(0, -signalConsts.verticalLampPostLength / 2); - this.lampPost.lineTo(0, signalConsts.verticalLampPostLength / 2); - this.lampPost.moveTo(0, 0); - this.lampPost.lineTo(signalConsts.levelLampPostLength, 0); - this.circularLamp.beginFill(SignalColorEnum.lampColor, 1); - this.circularLamp.drawCircle( - signalConsts.levelLampPostLength + signalConsts.lampRadius, - 0, - signalConsts.lampRadius - ); - this.circularLamp.endFill(); + + paint(): void { + this.lampMainBody.paint(signalConsts.lampNum); this.humanControl.beginFill(SignalColorEnum.humanControlColor, 1); - this.humanControl.drawPolygon(signalConsts.humanControlPath); + if (this.humanControl.drawRegularPolygon) { + this.humanControl.drawRegularPolygon(-10, 0, 10, 3, Math.PI / 2); + } this.humanControl.endFill(); this.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1); - const fleetModePath: number[] = []; - signalConsts.fleetModePath.forEach((item: number, index: number) => { - if (!(index % 2)) { - fleetModePath.push( - item + signalConsts.levelLampPostLength + signalConsts.lampRadius * 2 - ); - } else { - fleetModePath.push(item); - } - }); - this.fleetMode.drawPolygon(fleetModePath); + drawArrow( + this.fleetMode, + this.lampMainBody.width + signalConsts.fleetModeLength, + 0, + signalConsts.fleetModeLength, + signalConsts.fleetModeRadius, + signalConsts.fleetModeLineWidth + ); this.fleetMode.endFill(); - this.logicMode.lineStyle(2, new Color(SignalColorEnum.logicModeColor)); - this.logicMode.moveTo( - signalConsts.levelLampPostLength + - signalConsts.lampRadius - - signalConsts.logicModeDistance, - signalConsts.logicModeDistance + this.codeGraph.text = this.datas?.code || '信号机编号'; + this.codeGraph.style.fill = SignalColorEnum.codeColor; + this.codeGraph.setVectorFontSize(signalConsts.codeFontSize); + this.codeGraph.anchor.set(0.5); + this.codeGraph.style.fill = SignalColorEnum.codeColor; + const codeTransform = this.datas?.childTransforms?.find( + (item) => item.name === 'signalCode' ); - this.logicMode.lineTo( - signalConsts.levelLampPostLength + - signalConsts.lampRadius + - signalConsts.logicModeDistance, - -signalConsts.logicModeDistance - ); - this.logicMode.moveTo( - signalConsts.levelLampPostLength + - signalConsts.lampRadius - - signalConsts.logicModeDistance, - -signalConsts.logicModeDistance - ); - this.logicMode.lineTo( - signalConsts.levelLampPostLength + - signalConsts.lampRadius + - signalConsts.logicModeDistance, - signalConsts.logicModeDistance - ); - if (this.datas.code == '') { - codeGraph.text = '信号机Signal'; + if (codeTransform) { + const position = codeTransform?.transform.position; + const rotation = codeTransform?.transform?.rotation; + this.codeGraph.position.set(position?.x, position?.y); + this.codeGraph.rotation = rotation || 0; } else { - codeGraph.text = this.datas.code; + this.codeGraph.position.set(0, signalConsts.nameOffsetY); } - codeGraph.style.fill = this.datas.codeColor; - codeGraph.setVectorFontSize(this.datas.codeFontSize); - codeGraph.anchor.set(0.5); - codeGraph.style.fill = this.datas.codeColor; - codeGraph.position.set(0, signalConsts.nameOffsetY); - this.position.set(this.datas.point.x, this.datas.point.y); + } + + doRepaint(): void { + this.paint(); } } export class SignalTemplate extends JlGraphicTemplate { - codeColor: string; - codeFontSize: number; - direction: string; - verticalLampPostLength: number; - levelLampPostLength: number; - lineWidth: number; - lampRadius: number; - lampPostColor: string; - lampColor: string; - humanControlColor: string; - fleetModeColor: string; - logicModeColor: string; - humanControlPath: number[]; - logicModeLineWidth: number; - logicModeDistance: number; - fleetModePath: number[]; - nameOffsetY: number; constructor() { super(Signal.Type); - this.codeColor = '0xff0000'; - this.codeFontSize = 11; - this.direction = 'right'; - this.verticalLampPostLength = signalConsts.verticalLampPostLength; - this.levelLampPostLength = signalConsts.levelLampPostLength; - this.lineWidth = signalConsts.lineWidth; - this.lampRadius = signalConsts.lampRadius; - this.lampPostColor = SignalColorEnum.lampPostColor; - this.lampColor = SignalColorEnum.lampColor; - this.humanControlColor = SignalColorEnum.humanControlColor; - this.fleetModeColor = SignalColorEnum.fleetModeColor; - this.logicModeColor = SignalColorEnum.logicModeColor; - this.humanControlPath = signalConsts.humanControlPath; - this.logicModeLineWidth = signalConsts.logicModeLineWidth; - this.logicModeDistance = signalConsts.logicModeDistance; - this.nameOffsetY = signalConsts.nameOffsetY; - const fleetModePath: number[] = []; - signalConsts.fleetModePath.forEach((item: number, index: number) => { - if (!(index % 2)) { - fleetModePath.push( - item + signalConsts.levelLampPostLength + signalConsts.lampRadius * 2 - ); - } else { - fleetModePath.push(item); - } - }); - this.fleetModePath = fleetModePath; } new(): Signal { return new Signal(); diff --git a/src/graphics/signal/SignalDrawAssistant.ts b/src/graphics/signal/SignalDrawAssistant.ts index 0e3de06..52b84e8 100644 --- a/src/graphics/signal/SignalDrawAssistant.ts +++ b/src/graphics/signal/SignalDrawAssistant.ts @@ -1,13 +1,10 @@ -import { FederatedPointerEvent, Point, Graphics, Color } from 'pixi.js'; +import { FederatedPointerEvent, Point } from 'pixi.js'; import { GraphicDrawAssistant, GraphicInteractionPlugin, JlDrawApp, JlGraphic, - KeyListener, - VectorText, } from 'src/jlgraphic'; - import { ISignalData, Signal, SignalTemplate } from './Signal'; export interface ISignalDrawOptions { @@ -18,41 +15,27 @@ export class SignalDraw extends GraphicDrawAssistant< SignalTemplate, ISignalData > { - point: Point = new Point(0, 0); - codeGraph: VectorText = new VectorText(''); - lampPost: Graphics = new Graphics(); - circularLamp: Graphics = new Graphics(); - humanControl: Graphics = new Graphics(); - fleetMode: Graphics = new Graphics(); - logicMode: Graphics = new Graphics(); - - // 快捷绘制 - keypListener: KeyListener = new KeyListener({ - value: 'KeyH', - global: true, - onPress: () => { - //this.graphicTemplate.hasdoor = true; - }, - }); + _signal: Signal | null = null; constructor(app: JlDrawApp, createData: () => ISignalData) { - super(app, new SignalTemplate(), createData, Signal.Type, '信号机Signal'); - this.container.addChild(this.codeGraph); - this.container.addChild(this.lampPost); - this.container.addChild(this.circularLamp); - this.container.addChild(this.humanControl); - this.container.addChild(this.fleetMode); - this.container.addChild(this.logicMode); + super( + app, + new SignalTemplate(), + createData, + 'svguse: ../../drawIcon.svg#icon-signal', + '信号机Signal' + ); + signalInteraction.init(app); } - bind(): void { - super.bind(); - this.app.addKeyboardListener(this.keypListener); - } - unbind(): void { - super.unbind(); - this.app.removeKeyboardListener(this.keypListener); + public get signal(): Signal { + if (!this._signal) { + this._signal = this.graphicTemplate.new(); + this.signal.loadData(this.createGraphicData()); + this.container.addChild(this.signal); + } + return this._signal; } clearCache(): void { @@ -61,87 +44,17 @@ export class SignalDraw extends GraphicDrawAssistant< onRightClick(): void { this.createAndStore(true); } - onLeftDown(e: FederatedPointerEvent): void { - const { x, y } = this.toCanvasCoordinates(e.global); - const p = new Point(x, y); - this.point = p; + onLeftUp(e: FederatedPointerEvent): void { + this.container.position.copyFrom(this.toCanvasCoordinates(e.global)); this.createAndStore(true); } redraw(p: Point): void { - const codeGraph = this.codeGraph; - const template = this.graphicTemplate; - this.point.set(p.x, p.y); - this.lampPost.lineStyle( - template.lineWidth, - new Color(template.lampPostColor) - ); - this.lampPost.moveTo(0, -template.verticalLampPostLength / 2); - this.lampPost.lineTo(0, template.verticalLampPostLength / 2); - - this.lampPost.moveTo(0, 0); - this.lampPost.lineTo(template.levelLampPostLength, 0); - - this.lampPost.position.set(p.x, p.y); - this.circularLamp.beginFill(template.lampColor, 1); - this.circularLamp.drawCircle( - template.levelLampPostLength + template.lampRadius, - 0, - template.lampRadius - ); - this.circularLamp.endFill(); - this.circularLamp.position.set(p.x, p.y); - this.humanControl.beginFill(template.humanControlColor, 1); - this.humanControl.drawPolygon(template.humanControlPath); - this.humanControl.endFill(); - this.humanControl.position.set(p.x, p.y); - this.fleetMode.beginFill(template.fleetModeColor, 1); - this.fleetMode.drawPolygon(template.fleetModePath); - this.fleetMode.endFill(); - this.fleetMode.position.set(p.x, p.y); - this.logicMode.lineStyle( - template.logicModeLineWidth, - new Color(template.logicModeColor) - ); - this.logicMode.moveTo( - template.levelLampPostLength + - template.lampRadius - - template.logicModeDistance, - template.logicModeDistance - ); - this.logicMode.lineTo( - template.levelLampPostLength + - template.lampRadius + - template.logicModeDistance, - -template.logicModeDistance - ); - this.logicMode.moveTo( - template.levelLampPostLength + - template.lampRadius - - template.logicModeDistance, - -template.logicModeDistance - ); - this.logicMode.lineTo( - template.levelLampPostLength + - template.lampRadius + - template.logicModeDistance, - template.logicModeDistance - ); - this.logicMode.position.set(p.x, p.y); - codeGraph.text = '信号机Signal'; - - codeGraph.style.fill = template.codeColor; - codeGraph.setVectorFontSize(template.codeFontSize); - codeGraph.anchor.set(0.5); - codeGraph.style.fill = template.codeColor; - codeGraph.position.set(p.x, p.y + template.nameOffsetY); + this.signal.paint(); + this.container.position.set(p.x, p.y); } prepareData(data: ISignalData): boolean { - const template = this.graphicTemplate; - data.point = this.point; - data.codeColor = template.codeColor; - data.codeFontSize = template.codeFontSize; - data.direction = template.direction; + data.transform = this.container.saveTransform(); return true; } } @@ -164,10 +77,26 @@ export class signalInteraction extends GraphicInteractionPlugin { g.cursor = 'pointer'; g.scalable = true; g.rotatable = true; + g.codeGraph.draggable = true; + g.codeGraph.selectable = true; + g.codeGraph.rotatable = true; + g.codeGraph.scalable = true; + g.codeGraph.transformSave = true; + g.codeGraph.eventMode = 'static'; + // g.codeGraph.on('transformend', this.onScaleDragEnd, this); } + // onScaleDragEnd() { + // console.log('-----------------'); + // } unbind(g: Signal): void { g.eventMode = 'none'; g.scalable = false; g.rotatable = false; + g.codeGraph.draggable = false; + g.codeGraph.selectable = false; + g.codeGraph.rotatable = false; + g.codeGraph.scalable = false; + g.codeGraph.transformSave = false; + g.codeGraph.eventMode = 'none'; } } diff --git a/src/jlgraphic/plugins/GraphicTransformPlugin.ts b/src/jlgraphic/plugins/GraphicTransformPlugin.ts index cbc3cbd..46deec5 100644 --- a/src/jlgraphic/plugins/GraphicTransformPlugin.ts +++ b/src/jlgraphic/plugins/GraphicTransformPlugin.ts @@ -255,9 +255,10 @@ export class GraphicTransformPlugin extends InteractionPluginBase { targets.forEach((target) => { if (target.shiftStartPoint) { target.shiftLastPoint = target.position.clone(); + const { dx, dy } = e.toTargetShiftLen(target.parent); target.position.set( - target.shiftStartPoint.x + e.dsx, - target.shiftStartPoint.y + e.dsy + target.shiftStartPoint.x + dx, + target.shiftStartPoint.y + dy ); } }); diff --git a/src/jlgraphic/plugins/InteractionPlugin.ts b/src/jlgraphic/plugins/InteractionPlugin.ts index 34a5f5e..70226d6 100644 --- a/src/jlgraphic/plugins/InteractionPlugin.ts +++ b/src/jlgraphic/plugins/InteractionPlugin.ts @@ -99,7 +99,7 @@ export class AppDragEvent { type: 'start' | 'move' | 'end'; target: DisplayObject; original: FederatedPointerEvent; - start: Point; + start: Point; // 画布坐标 constructor( app: GraphicApp, type: 'start' | 'move' | 'end', @@ -146,6 +146,9 @@ export class AppDragEvent { return this.original.pointerType === 'touch'; } + /** + * 终点坐标(画布坐标) + */ public get end(): Point { return this.app.toCanvasCoordinates(this.original.global); } @@ -167,6 +170,15 @@ export class AppDragEvent { public get dsy(): number { return this.end.y - this.start.y; } + + /** + * 转换为目标对象的位移距离 + */ + toTargetShiftLen(target: DisplayObject): { dx: number; dy: number } { + const sl = target.canvasToLocalPoint(this.start); + const el = target.canvasToLocalPoint(this.end); + return { dx: el.x - sl.x, dy: el.y - sl.y }; + } } /** diff --git a/yarn.lock b/yarn.lock index c5c9616..72e29cc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -185,7 +185,7 @@ "@pixi/graphics-extras@^7.2.4": version "7.2.4" - resolved "https://registry.yarnpkg.com/@pixi/graphics-extras/-/graphics-extras-7.2.4.tgz#72ac967992f239d3671d6e680ac891471619fe07" + resolved "https://registry.npmmirror.com/@pixi/graphics-extras/-/graphics-extras-7.2.4.tgz#72ac967992f239d3671d6e680ac891471619fe07" integrity sha512-0yT91yqF3KLiZI/iLRcfcYlTVpkVyWsfGtWEIorZs0eX+/zYx7um7EJ2h7tFORI/1FxA2maR4td5vpgCwOLJAQ== "@pixi/graphics@7.2.4":