diff --git a/package.json b/package.json index 6a236a6..7af8a86 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@pixi/filter-outline": "^5.2.0", + "@pixi/graphics-extras": "^7.2.4", "@quasar/extras": "^1.0.0", "@stomp/stompjs": "^7.0.0", "axios": "^1.2.1", diff --git a/quasar.config.js b/quasar.config.js index ce2c726..ee66d7a 100644 --- a/quasar.config.js +++ b/quasar.config.js @@ -30,7 +30,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: ['axios'], + boot: ['axios', '@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/drawApp/graphics/SignalInteraction.ts b/src/drawApp/graphics/SignalInteraction.ts index ee4f2b3..98f2853 100644 --- a/src/drawApp/graphics/SignalInteraction.ts +++ b/src/drawApp/graphics/SignalInteraction.ts @@ -13,9 +13,9 @@ export class SignalData extends GraphicDataBase implements ISignalData { } else { signal = data; } + signal.common.graphicType = 'signal'; super(signal); } - public get data(): graphicData.Signal { return this.getData(); } 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..e25410f --- /dev/null +++ b/src/graphics/signal/Lamp.ts @@ -0,0 +1,52 @@ +import { Container } from '@pixi/display'; +import { Graphics, Color } 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/Signal.ts b/src/graphics/signal/Signal.ts index 383bb0e..e6bc8c4 100644 --- a/src/graphics/signal/Signal.ts +++ b/src/graphics/signal/Signal.ts @@ -5,8 +5,8 @@ import { JlGraphicTemplate, VectorText, } from 'src/jl-graphic'; -import { LampBody } from './lampBody'; -import { SignalDraw } from './SignalDrawAssistant'; +import { LampBody } from './LampBody'; +import { drawArrow } from '../CommonGraphics'; export interface ISignalData extends GraphicData { get code(): string; // 编号 @@ -26,8 +26,9 @@ const signalConsts = { lampNum: 1, codeFontSize: 11, nameOffsetY: 20, - humanControlPath: [-2, 0, -17, 10, -17, -10], - 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'; @@ -49,47 +50,43 @@ export class Signal extends JlGraphic { return this.getDatas(); } - static computedFleetModePath(x: number): number[] { - const fleetModePath: number[] = []; - signalConsts.fleetModePath.forEach((item: number, index: number) => { - if (!(index % 2)) { - fleetModePath.push(item + x); - } else { - fleetModePath.push(item); - } - }); - return fleetModePath; - } - - static paint(signal: Signal | SignalDraw, data?: ISignalData): void { - signal.lampBody.paint(signalConsts.lampNum); - signal.humanControl.beginFill(SignalColorEnum.humanControlColor, 1); - signal.humanControl.drawPolygon(signalConsts.humanControlPath); - signal.humanControl.endFill(); - signal.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1); - const fleetModePath = Signal.computedFleetModePath(signal.lampBody.width); - signal.fleetMode.drawPolygon(fleetModePath); - signal.fleetMode.endFill(); - signal.codeGraph.text = data?.code || '信号机编号'; - signal.codeGraph.style.fill = SignalColorEnum.codeColor; - signal.codeGraph.setVectorFontSize(signalConsts.codeFontSize); - signal.codeGraph.anchor.set(0.5); - signal.codeGraph.style.fill = SignalColorEnum.codeColor; - const codeTransform = data?.childTransforms?.find( + paint(): void { + this.lampBody.paint(signalConsts.lampNum); + this.humanControl.beginFill(SignalColorEnum.humanControlColor, 1); + if (this.humanControl.drawRegularPolygon) { + this.humanControl.drawRegularPolygon(-10, 0, 10, 3, Math.PI / 2); + } + this.humanControl.endFill(); + this.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1); + drawArrow( + this.fleetMode, + this.lampBody.width + signalConsts.fleetModeLength, + 0, + signalConsts.fleetModeLength, + signalConsts.fleetModeRadius, + signalConsts.fleetModeLineWidth + ); + this.fleetMode.endFill(); + 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' ); if (codeTransform) { const position = codeTransform?.transform.position; const rotation = codeTransform?.transform?.rotation; - signal.codeGraph.position.set(position?.x, position?.y); - signal.codeGraph.rotation = rotation || 0; + this.codeGraph.position.set(position?.x, position?.y); + this.codeGraph.rotation = rotation || 0; } else { - signal.codeGraph.position.set(0, signalConsts.nameOffsetY); + this.codeGraph.position.set(0, signalConsts.nameOffsetY); } } doRepaint(): void { - Signal.paint(this, this.datas); + this.paint(); } } diff --git a/src/graphics/signal/SignalDrawAssistant.ts b/src/graphics/signal/SignalDrawAssistant.ts index 532d9e2..605cf78 100644 --- a/src/graphics/signal/SignalDrawAssistant.ts +++ b/src/graphics/signal/SignalDrawAssistant.ts @@ -1,14 +1,12 @@ -import { FederatedPointerEvent, Point, Graphics } from 'pixi.js'; +import { FederatedPointerEvent, Point } from 'pixi.js'; import { GraphicDrawAssistant, GraphicInteractionPlugin, JlDrawApp, JlGraphic, - GraphicTransformEvent, - VectorText, } from 'src/jl-graphic'; import { ISignalData, Signal, SignalTemplate } from './Signal'; -import { LampBody } from './lampBody'; +import { SignalData } from 'src/drawApp/graphics/SignalInteraction'; export interface ISignalDrawOptions { newData: () => ISignalData; @@ -18,10 +16,7 @@ export class SignalDraw extends GraphicDrawAssistant< SignalTemplate, ISignalData > { - codeGraph: VectorText = new VectorText(''); - humanControl: Graphics = new Graphics(); - fleetMode: Graphics = new Graphics(); - lampBody: LampBody = new LampBody(); + _signal: Signal | null = null; constructor(app: JlDrawApp, createData: () => ISignalData) { super( @@ -31,13 +26,19 @@ export class SignalDraw extends GraphicDrawAssistant< 'svguse:../drawIcon.svg#icon-signal', '信号机Signal' ); - this.container.addChild(this.codeGraph); - this.container.addChild(this.humanControl); - this.container.addChild(this.fleetMode); - this.container.addChild(this.lampBody); + signalInteraction.init(app); } + public get signal(): Signal { + if (!this._signal) { + this._signal = this.graphicTemplate.new(); + this.signal.loadData(new SignalData()); + this.container.addChild(this.signal); + } + return this._signal; + } + bind(): void { super.bind(); } @@ -57,8 +58,7 @@ export class SignalDraw extends GraphicDrawAssistant< } redraw(p: Point): void { - console.log(this); - Signal.paint(this); + this.signal.paint(); this.container.position.set(p.x, p.y); } prepareData(data: ISignalData): boolean { diff --git a/src/graphics/signal/lampBody.ts b/src/graphics/signal/lampBody.ts index 9928882..3c2dce3 100644 --- a/src/graphics/signal/lampBody.ts +++ b/src/graphics/signal/lampBody.ts @@ -1,11 +1,9 @@ import { Container } from '@pixi/display'; -import { Graphics, Color } from 'pixi.js'; +import { Graphics } from 'pixi.js'; +import { Lamp } from './Lamp'; export enum LampEnum { lampPostColor = '0xc0c0c0', - lampDefaultColor = '0xff0000', - logicModeColor = '0x000000', - codeColor = '0X000000', } const lampConsts = { @@ -13,15 +11,12 @@ const lampConsts = { levelLampPostLength: 5, postLineWidth: 3, lampRadius: 10, - logicModeLineWidth: 2, - logicModeDistance: 7, }; export class LampBody extends Container { lampNum = 1; lampPost: Graphics = new Graphics(); - lamps: Graphics[] = []; - logicModes: Graphics[] = []; + lamps: Lamp[] = []; constructor() { super(); @@ -33,50 +28,22 @@ export class LampBody extends Container { this.lampNum = lampNum; this.removeChildren(0); this.lampPost = new Graphics(); - this.lampPost.lineStyle( - lampConsts.postLineWidth, - new Color(LampEnum.lampPostColor) - ); - this.lampPost.moveTo(0, -lampConsts.verticalLampPostLength / 2); - this.lampPost.lineTo(0, lampConsts.verticalLampPostLength / 2); - this.lampPost.moveTo(0, 0); - this.lampPost.lineTo(lampConsts.levelLampPostLength, 0); + 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 = []; - this.logicModes = []; for (let i = 0; i < this.lampNum; i++) { - const lamp = new Graphics(); - lamp.beginFill(LampEnum.lampDefaultColor, 1); - const lampX = - lampConsts.lampRadius * (i * 2 + 1) + lampConsts.levelLampPostLength; - lamp.drawCircle(lampX, 0, lampConsts.lampRadius); - lamp.endFill(); + const lamp = new Lamp(); + const radiusX = + (1 + i * 2) * lampConsts.lampRadius + lampConsts.levelLampPostLength; + lamp.paint(radiusX, 0); this.addChild(lamp); this.lamps.push(lamp); - const logicMode = new Graphics(); - logicMode.lineStyle( - lampConsts.logicModeLineWidth, - new Color(LampEnum.logicModeColor) - ); - logicMode.moveTo( - lampX - lampConsts.logicModeDistance, - lampConsts.logicModeDistance - ); - logicMode.lineTo( - lampX + lampConsts.logicModeDistance, - -lampConsts.logicModeDistance - ); - logicMode.moveTo( - lampX - lampConsts.logicModeDistance, - -lampConsts.logicModeDistance - ); - logicMode.lineTo( - lampX + lampConsts.logicModeDistance, - lampConsts.logicModeDistance - ); - this.addChild(logicMode); - this.logicModes.push(logicMode); } } diff --git a/yarn.lock b/yarn.lock index 64d4a94..c12ff44 100644 --- a/yarn.lock +++ b/yarn.lock @@ -193,6 +193,11 @@ resolved "https://registry.npmmirror.com/@pixi/filter-outline/-/filter-outline-5.2.0.tgz#8572ed2c847c31c5a142db04e86f081baed0365a" integrity sha512-xKfAouhZNKl6A0RvxT5i+2/ean7r16dE/QswwIkbWvr2hhHlp4p9U6XsqdgUERCDxK+IZibMAumbWs4DGxOUeQ== +"@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" + integrity sha512-0yT91yqF3KLiZI/iLRcfcYlTVpkVyWsfGtWEIorZs0eX+/zYx7um7EJ2h7tFORI/1FxA2maR4td5vpgCwOLJAQ== + "@pixi/graphics@7.2.4": version "7.2.4" resolved "https://registry.npmmirror.com/@pixi/graphics/-/graphics-7.2.4.tgz#8500b604c36184736926393cb0ca9b9de9afef86"