信号机代码调整

This commit is contained in:
fan 2024-01-12 11:27:25 +08:00
parent 0567dadd3e
commit 9eb1c72740
9 changed files with 122 additions and 444 deletions

View File

@ -0,0 +1,11 @@
import { SignalCode } from './SignalCode';
import { LampPost } from './LampPost';
import { Lamp } from './Lamp';
import { JlGraphic } from 'jl-graphic';
export abstract class CommonSignal extends JlGraphic{
static Type = 'signal';
signalCode: SignalCode = new SignalCode;
lampPost: LampPost = new LampPost();
lamps: Lamp[] = [];
}

View File

@ -10,10 +10,11 @@ import {
GraphicData,
GraphicState
} from 'jl-graphic';
import { SignalTemplate } from './SignalTemplate';
import { CommonSignal } from './Common';
export class SignalDraw<G extends JlGraphic,D extends GraphicData, S extends GraphicState> extends GraphicDrawAssistant<
export class SignalDraw<G extends CommonSignal ,D extends GraphicData, S extends GraphicState> extends GraphicDrawAssistant<
SignalTemplate<G, D, S>,
GraphicData
> {
@ -73,11 +74,11 @@ export class SignalGraphicHitArea implements IHitArea {
* 线
* @param signal
*/
function buildAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
function buildAbsorbablePositions<G extends JlGraphic>(signal: G): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const signals = signal.queryStore.queryByType<Signal>(Signal.Type);
const signals = signal.queryStore.queryByType<G>(CommonSignal.Type);
const canvas = signal.getCanvas();
signals.forEach((item: Signal) => {
signals.forEach((item: G) => {
if (item.id === signal.id) {
return;
}
@ -99,11 +100,11 @@ function buildAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
* 线
* @param signal
*/
function buildCodeAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
function buildCodeAbsorbablePositions<G extends CommonSignal>(signal: G): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const signals = signal.queryStore.queryByType<Signal>(Signal.Type);
const signals = signal.queryStore.queryByType<G>(CommonSignal.Type);
const canvas = signal.getCanvas();
signals.forEach((item: Signal) => {
signals.forEach((item: G) => {
if (item.id === signal.id) {
return;
}
@ -122,7 +123,7 @@ function buildCodeAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
return aps;
}
export class SignalInteraction<G extends JlGraphic> extends GraphicInteractionPlugin<G> {
export class SignalInteraction<G extends CommonSignal> extends GraphicInteractionPlugin<G> {
static Name = 'signal_transform';
constructor(app: IDrawApp) {
super(SignalInteraction.Name, app);
@ -132,7 +133,7 @@ export class SignalInteraction<G extends JlGraphic> extends GraphicInteractionPl
}
filter(...grahpics: JlGraphic[]): G[] | undefined {
return grahpics
.filter((g) => g.type === Signal.Type)
.filter((g) => g.type === CommonSignal.Type)
.map((g) => g as G);
}
bind(g: G): void {
@ -140,8 +141,9 @@ export class SignalInteraction<G extends JlGraphic> extends GraphicInteractionPl
g.cursor = 'pointer';
g.scalable = true;
g.rotatable = true;
g.lampMainBody.hitArea = new SignalGraphicHitArea(g);
g.hitArea = new SignalGraphicHitArea(g);
g.on('transformstart', this.transformstart, this);
// const signalCode = g.signalCode as SignalCode;
g.signalCode.on('transformstart', this.codetransformstart, this);
g.signalCode.draggable = true;
g.signalCode.selectable = true;
@ -164,16 +166,16 @@ export class SignalInteraction<G extends JlGraphic> extends GraphicInteractionPl
}
transformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const signal = target.getGraphic() as Signal;
const signal = target.getGraphic() as G;
signal.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(signal),
absorbablePositions: buildAbsorbablePositions<G>(signal),
});
}
codetransformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const signal = target.getGraphic() as Signal;
const signal = target.getGraphic() as G;
signal.getGraphicApp().setOptions({
absorbablePositions: buildCodeAbsorbablePositions(signal),
absorbablePositions: buildCodeAbsorbablePositions<G>(signal),
});
}
}

View File

@ -1,7 +1,8 @@
import { JlGraphicTemplate, JlGraphic, GraphicData, GraphicState } from 'jl-graphic';
import { JlGraphicTemplate, GraphicData, GraphicState } from 'jl-graphic';
import { CommonSignal } from './Common';
import { Signal } from './th/Signal';
export class SignalTemplate<G extends JlGraphic,D extends GraphicData, S extends GraphicState> extends JlGraphicTemplate<G> {
export class SignalTemplate<G extends CommonSignal,D extends GraphicData, S extends GraphicState> extends JlGraphicTemplate<G> {
graphic: G;
constructor(
dataTemplate: D,

View File

@ -1,16 +1,13 @@
import { Graphics, Point } from 'pixi.js';
import {
GraphicData,
JlGraphic,
GraphicRelationParam,
GraphicState,
JlGraphicTemplate
JlGraphicTemplate,
calculateMirrorPoint
} from 'jl-graphic';
import { LampMainBody } from './LampMainBody';
// import {
// drawArrow,
// } from '../common/CommonGraphics';
import { SignalCode } from '../common/SignalCode';
import { CommonSignal } from '../Common';
import { Lamp } from '../Lamp';
/** 信号机类型 */
export enum Model {
@ -134,19 +131,10 @@ export const signalConsts = {
logicModeDistance: 5,
lampLineWidth: 1,
};
export class Signal extends JlGraphic {
static Type = 'signal';
signalCode: SignalCode = new SignalCode();
humanControl: Graphics = new Graphics();
fleetMode: Graphics = new Graphics();
lampMainBody: LampMainBody = new LampMainBody();
blockedMode: Graphics = new Graphics();
export class Signal extends CommonSignal {
constructor() {
super(Signal.Type);
// this.addChild(this.humanControl);
// this.addChild(this.fleetMode);
this.addChild(this.lampMainBody);
this.addChild(this.lampPost);
this.addChild(this.signalCode);
}
@ -167,10 +155,47 @@ export class Signal extends JlGraphic {
return this.getStates<ISignalState>();
}
paint(): void {
get lampNumber(): number {
if (
this.datas.mt === Model.HL ||
this.datas.mt === Model.AB
) {
return 2;
} else {
return 3;
}
}
// paint(): void {
// const mirror = this.datas.mirror;
// this.lampMainBody.paint(this.datas.mt, mirror);
// this.signalCode.paint(this.datas);
// const codeTransform = this.datas?.childTransforms?.find(
// (item) => item.name === 'signalCode'
// );
// if (codeTransform) {
// const position = codeTransform?.transform.position;
// const rotation = codeTransform?.transform?.rotation;
// this.signalCode.position.set(position?.x, position?.y);
// this.signalCode.rotation = rotation || 0;
// } else {
// this.signalCode.position.set(0, signalConsts.codeOffset);
// }
// }
doRepaint(): void {
// this.paint();
//移除除灯柱、code外元素
this.removeChildren(2);
const mirror = this.datas.mirror;
this.lampMainBody.paint(this.datas.mt, mirror);
this.signalCode.paint(this.datas);
// 信号机编号
this.signalCode.paint({
code: this.datas.code,
fontSize: signalConsts.codeFontSize,
codeColor: SignalColorEnum.defaultCodeColor
});
const codeTransform = this.datas?.childTransforms?.find(
(item) => item.name === 'signalCode'
);
@ -182,10 +207,38 @@ export class Signal extends JlGraphic {
} else {
this.signalCode.position.set(0, signalConsts.codeOffset);
}
// 信号机灯柱
let lpp = new Point(signalConsts.levelLampPostLength, 0);
if (mirror) {
lpp = calculateMirrorPoint(new Point(0, 0), lpp);
}
this.lampPost.paint({
lpp: lpp,
lampPostColor: SignalColorEnum.lampLineColor,
postLineWidth: signalConsts.postLineWidth,
verticalLampPostLength: signalConsts.verticalLampPostLength
});
// 信号机圆灯
this.lamps = [];
for (let i = 0; i < this.lampNumber; i++) {
const lamp = new Lamp();
this.addChild(lamp);
const radiusX =
(1 + i * 2) * signalConsts.lampRadius +
signalConsts.levelLampPostLength;
let lrp = new Point(radiusX, 0);
if (mirror) {
lrp = calculateMirrorPoint(new Point(0, 0), lrp);
}
lamp.paint({
radiusX: lrp.x,
radiusY: lrp.y,
lampLineColor: SignalColorEnum.lampLineColor,
lampLineWidth: signalConsts.lampLineWidth,
lampRadius: signalConsts.lampRadius
});
this.lamps.push(lamp);
}
doRepaint(): void {
this.paint();
}
chagneState() {

View File

@ -1,181 +0,0 @@
import { DisplayObject, FederatedPointerEvent, IHitArea, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicDrawAssistant,
GraphicInteractionPlugin,
GraphicTransformEvent,
IDrawApp,
JlGraphic,
} from 'jl-graphic';
import { ISignalData, Signal, SignalTemplate } from './Signal';
export interface ISignalDrawOptions {
newData: () => ISignalData;
}
export class SignalDraw extends GraphicDrawAssistant<
SignalTemplate,
ISignalData
> {
_signal: Signal | null = null;
constructor(app: IDrawApp, template: SignalTemplate) {
super(
app,
template,
'svguse: ../../drawIcon.svg#icon-signal',
'信号机Signal'
);
SignalInteraction.init(app);
}
public get signal(): Signal {
if (!this._signal) {
this._signal = this.graphicTemplate.new();
this._signal.loadData(this.graphicTemplate.datas);
this.container.addChild(this._signal);
}
return this._signal;
}
onLeftUp(e: FederatedPointerEvent): void {
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true);
}
redraw(p: Point): void {
this.signal.paint();
this.container.position.set(p.x, p.y);
}
prepareData(data: ISignalData): boolean {
data.transform = this.container.saveTransform();
return true;
}
}
export class SignalGraphicHitArea implements IHitArea {
signal: Signal;
constructor(signal: Signal) {
this.signal = signal;
}
contains(x: number, y: number): boolean {
const bound = this.signal.getLocalBounds();
const maxX = bound.x + bound.width;
const minX = bound.x;
const maxY = bound.y + bound.height;
const minY = bound.y;
return maxX >= x && x >= minX && maxY >= y && y >= minY;
}
}
/**
* 线
* @param signal
*/
function buildAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const signals = signal.queryStore.queryByType<Signal>(Signal.Type);
const canvas = signal.getCanvas();
signals.forEach((item) => {
if (item.id === signal.id) {
return;
}
const ala = new AbsorbableLine(
new Point(item.x, 0),
new Point(item.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, item.y),
new Point(canvas.width, item.y)
);
aps.push(ala);
aps.push(alb);
});
return aps;
}
/**
* 线
* @param signal
*/
function buildCodeAbsorbablePositions(signal: Signal): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const signals = signal.queryStore.queryByType<Signal>(Signal.Type);
const canvas = signal.getCanvas();
signals.forEach((item) => {
if (item.id === signal.id) {
return;
}
const codePoint = item.signalCode.getPositionOnCanvas();
const ala = new AbsorbableLine(
new Point(codePoint.x, 0),
new Point(codePoint.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, codePoint.y),
new Point(canvas.width, codePoint.y)
);
aps.push(ala);
aps.push(alb);
});
return aps;
}
export class SignalInteraction extends GraphicInteractionPlugin<Signal> {
static Name = 'signal_transform';
constructor(app: IDrawApp) {
super(SignalInteraction.Name, app);
}
static init(app: IDrawApp) {
return new SignalInteraction(app);
}
filter(...grahpics: JlGraphic[]): Signal[] | undefined {
return grahpics
.filter((g) => g.type === Signal.Type)
.map((g) => g as Signal);
}
bind(g: Signal): void {
g.eventMode = 'static';
g.cursor = 'pointer';
g.scalable = true;
g.rotatable = true;
g.lampMainBody.hitArea = new SignalGraphicHitArea(g);
g.on('transformstart', this.transformstart, this);
g.signalCode.on('transformstart', this.codetransformstart, this);
g.signalCode.draggable = true;
g.signalCode.selectable = true;
g.signalCode.rotatable = true;
g.signalCode.transformSave = true;
g.signalCode.eventMode = 'static';
}
unbind(g: Signal): void {
g.eventMode = 'none';
g.scalable = false;
g.rotatable = false;
g.off('transformstart', this.transformstart, this);
g.signalCode.off('transformstart', this.codetransformstart, this);
g.signalCode.draggable = false;
g.signalCode.selectable = false;
g.signalCode.rotatable = false;
g.signalCode.transformSave = false;
g.signalCode.eventMode = 'none';
}
transformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const signal = target.getGraphic() as Signal;
signal.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(signal),
});
}
codetransformstart(e: GraphicTransformEvent) {
const target = e.target as DisplayObject;
const signal = target.getGraphic() as Signal;
signal.getGraphicApp().setOptions({
absorbablePositions: buildCodeAbsorbablePositions(signal),
});
}
}

View File

@ -1,71 +0,0 @@
import { Graphics } from 'pixi.js';
import { calculateMirrorPoint } from 'jl-graphic';
/**
*
* @param polygon
* @param x x坐标
* @param y y坐标
* @param length
* @param radius
* @param lineWidth 线
* @param mirror ()
*/
export function drawArrow(
polygon: Graphics,
x: number,
y: number,
length: number,
radius: number,
lineWidth: number,
mirror: boolean
) {
const trianglAcme = { x, y };
let triangleP1 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y + Math.cos(Math.PI / 6) * radius,
};
let triangleP2 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y - Math.cos(Math.PI / 6) * radius,
};
let lineP1 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y + lineWidth / 2,
};
let lineP2 = {
x: x - length,
y: y + lineWidth / 2,
};
let lineP3 = {
x: x - length,
y: y - lineWidth / 2,
};
let lineP4 = {
x: x - radius - Math.sin(Math.PI / 6),
y: y - lineWidth / 2,
};
if (mirror) {
triangleP1 = calculateMirrorPoint(trianglAcme, triangleP1);
triangleP2 = calculateMirrorPoint(trianglAcme, triangleP2);
lineP1 = calculateMirrorPoint(trianglAcme, lineP1);
lineP2 = calculateMirrorPoint(trianglAcme, lineP2);
lineP3 = calculateMirrorPoint(trianglAcme, lineP3);
lineP4 = calculateMirrorPoint(trianglAcme, lineP4);
}
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
);
}

View File

@ -1,102 +0,0 @@
import { Container } from '@pixi/display';
import { Graphics } from 'pixi.js';
import { SignalColorEnum, signalConsts } from '../bjRtss/Signal';
const lampConsts = {
lampLineWidth: 1,
lampBadColor: '0xFF0000',
badStart: 10,
badEnd: 15,
};
export class Lamp extends Container {
circleLamp: Graphics = new Graphics();
logicMode: Graphics = new Graphics();
radiusX = 0;
radiusY = 0;
constructor(hasLogic: boolean) {
super();
this.addChild(this.circleLamp);
if(hasLogic) {
this.addChild(this.logicMode);
}
}
paint(radiusX: number, radiusY: number) {
this.radiusX = radiusX;
this.radiusY = radiusY;
this.createLamp();
}
createLampBad() {
this.circleLamp.lineStyle(lampConsts.lampLineWidth, lampConsts.lampBadColor);
this.circleLamp.moveTo(this.radiusX + lampConsts.badStart, this.radiusY);
this.circleLamp.lineTo(this.radiusX + lampConsts.badEnd, this.radiusY);
this.circleLamp.moveTo(this.radiusX - lampConsts.badStart, this.radiusY);
this.circleLamp.lineTo(this.radiusX - lampConsts.badEnd, this.radiusY);
this.circleLamp.moveTo(this.radiusX, this.radiusY + lampConsts.badStart);
this.circleLamp.lineTo(this.radiusX, this.radiusY + lampConsts.badEnd);
this.circleLamp.moveTo(this.radiusX, this.radiusY - lampConsts.badStart);
this.circleLamp.lineTo(this.radiusX, this.radiusY - lampConsts.badEnd);
const xieStart = Math.sin(Math.PI / 4) * lampConsts.badStart;
const xieEnd = Math.sin(Math.PI / 4) * lampConsts.badEnd;
this.circleLamp.moveTo(this.radiusX + xieStart, this.radiusY + xieStart);
this.circleLamp.lineTo(this.radiusX + xieEnd, this.radiusY + xieEnd);
this.circleLamp.moveTo(this.radiusX + xieStart, this.radiusY - xieStart);
this.circleLamp.lineTo(this.radiusX + xieEnd, this.radiusY - xieEnd);
this.circleLamp.moveTo(this.radiusX - xieStart, this.radiusY - xieStart);
this.circleLamp.lineTo(this.radiusX - xieEnd, this.radiusY - xieEnd);
this.circleLamp.moveTo(this.radiusX - xieStart, this.radiusY + xieStart);
this.circleLamp.lineTo(this.radiusX - xieEnd, this.radiusY + xieEnd);
}
createLamp(color?: string) {
this.circleLamp.clear();
this.circleLamp.lineStyle(
signalConsts.lampLineWidth,
SignalColorEnum.lampLineColor
);
if (!color) {
this.circleLamp.beginFill('0XFFFFFF', 0);
} else {
this.circleLamp.beginFill(color, 1);
}
this.circleLamp.drawCircle(
this.radiusX,
this.radiusY,
signalConsts.lampRadius
);
this.circleLamp.endFill();
}
createLogicMode() {
this.logicMode
.clear()
.lineStyle(
signalConsts.logicModeLineWidth,
SignalColorEnum.logicModeColor
)
.moveTo(
this.radiusX - signalConsts.logicModeDistance,
this.radiusY + signalConsts.logicModeDistance
)
.lineTo(
this.radiusX + signalConsts.logicModeDistance,
this.radiusY - signalConsts.logicModeDistance
)
.moveTo(
this.radiusX - signalConsts.logicModeDistance,
this.radiusY - signalConsts.logicModeDistance
)
.lineTo(
this.radiusX + signalConsts.logicModeDistance,
this.radiusY + signalConsts.logicModeDistance
);
}
logicModeClear() {
this.logicMode.clear();
}
lampClear() {
this.circleLamp.clear();
}
}

View File

@ -1,41 +0,0 @@
import { Container, Graphics, Point } from 'pixi.js';
import { VectorText } from 'jl-graphic';
import {
ISignalData,
SignalColorEnum,
signalConsts,
} from '../bjRtss/Signal';
export class SignalCode extends Container {
blockedMode: Graphics = new Graphics();
codeGraph: VectorText = new VectorText('');
name = 'signalCode';
constructor() {
super();
this.addChild(this.blockedMode);
this.addChild(this.codeGraph);
}
paint(datas: ISignalData) {
this.codeGraph.text = datas?.code || '信号机编号';
this.codeGraph.style.fill = SignalColorEnum.defaultCodeColor;
this.codeGraph.setVectorFontSize(signalConsts.codeFontSize);
this.codeGraph.anchor.set(0.5);
this.codeGraph.position.set(0, 0);
this.blockedMode.clear();
}
createBlockedMode() {
const codeRect = this.codeGraph.getBounds();
const rectP = this.screenToLocalPoint(new Point(codeRect.x, codeRect.y));
this.blockedMode.clear();
this.blockedMode.lineStyle(
signalConsts.blockedLineWidth,
SignalColorEnum.blockedColor
);
this.blockedMode.drawRect(
rectP.x,
rectP.y,
codeRect.width,
codeRect.height
);
}
}

View File

@ -1,11 +1,12 @@
import { GraphicData, calculateMirrorPoint, JlGraphic, GraphicAnimation, GraphicState } from 'jl-graphic'
import { Graphics, Point } from 'pixi.js';
import { Point } from 'pixi.js';
import { SignalCode } from '../SignalCode';
import { FleetMode } from '../FleetMode';
import { HumanControl } from '../HumanControl';
import { Lamp } from '../Lamp';
import { LampPost } from '../LampPost';
import { KilometerSystemNoDir, IRelatedRef } from '../../../common/common'
import { KilometerSystemNoDir, IRelatedRef } from 'common/common'
import { CommonSignal } from '../Common';
/** 信号机颜色 */
export enum SignalColorEnum {
@ -97,13 +98,9 @@ export interface ISignalData extends GraphicData {
}
export class Signal extends JlGraphic {
static Type = 'signal';
signalCode: SignalCode = new SignalCode();
export class Signal extends CommonSignal {
humanControl: HumanControl = new HumanControl();
fleetMode: FleetMode = new FleetMode();
lampPost: LampPost = new LampPost();
lamps: Lamp[] = [];
deltaTime = 0;
constructor() {
@ -117,6 +114,15 @@ export class Signal extends JlGraphic {
return this.getDatas<ISignalData>();
}
get mirror(): boolean {
return this.datas.mirror;
}
set mirror(v: boolean) {
const old = this.datas.clone();
old.mirror = v;
this.updateData(old);
}
get states(): ISignalState {
return this.getStates<ISignalState>();
}