259 lines
9.5 KiB
JavaScript
259 lines
9.5 KiB
JavaScript
import { Graphics } from 'pixi.js';
|
|
import { JlTurnout } from './common/JlTurnout.js';
|
|
import { THConsts } from './common/TurnoutConfig.js';
|
|
import { Vector2, getParallelOfPolyline, GraphicAnimation } from 'jl-graphic';
|
|
import { JlSection, SectionType } from '../Section/common/JlSection.js';
|
|
import { THStation } from '../Station/THStation.js';
|
|
|
|
const TurnoutLabelColor = {
|
|
GREEN: '#0f0',
|
|
YELLOW: '#ff0',
|
|
RED: '#f00',
|
|
WHITE: '#fff',
|
|
};
|
|
class THTurnout extends JlTurnout {
|
|
labelRect;
|
|
speedLimit;
|
|
lostIndicationSquare;
|
|
deltaTime;
|
|
constructor() {
|
|
super(THConsts);
|
|
this.name = 'turnout';
|
|
this.labelRect = new Graphics();
|
|
this.speedLimit = new Graphics();
|
|
this.lostIndicationSquare = new Graphics();
|
|
this.addChild(this.labelRect);
|
|
this.addChild(this.speedLimit);
|
|
this.deltaTime = 0;
|
|
}
|
|
get states() {
|
|
return this.getStates();
|
|
}
|
|
doRepaint() {
|
|
//线条颜色
|
|
const station = this.queryStore.queryByCodeAndType(this.states.rtuId > 9 ? '' + this.states.rtuId : '0' + this.states.rtuId, THStation.Type);
|
|
if (station?.states.ipRtuStusDown) {
|
|
this.setLineColor(THConsts.blueShowColor);
|
|
}
|
|
else if (this.states.ipSingleSwitchStusCbtcOccupied) {
|
|
this.setLineColor(THConsts.cbtcOccupiedColor);
|
|
}
|
|
else if (this.states.ipSingleSwitchStusCiOccupied) {
|
|
this.setLineColor(THConsts.ciOccupiedColor);
|
|
}
|
|
else if (this.states.ipSingleSwitchStusLocked ||
|
|
this.states.ipSingleSwitchStusFailLocked) {
|
|
this.setLineColor(THConsts.lockedColor);
|
|
}
|
|
else if (this.states.ipSingleSwitchStusAtcInvalid) {
|
|
this.setLineColor(THConsts.atcInvalidColor);
|
|
}
|
|
else if (this.states.ipSingleSwitchStusOverlap) {
|
|
this.setLineColor(THConsts.overlapColor);
|
|
}
|
|
else {
|
|
this.setLineColor(THConsts.idleColor);
|
|
}
|
|
if (this.states.ipSingleSwitchStusJammed /* ||
|
|
this.turnout.states.ipSingleSwitchStusLostIndication */) {
|
|
let x, y;
|
|
const w = 24, h = 24;
|
|
if (this.datas.pointA[0].x > this.datas.pointB[0].x) {
|
|
x = -22;
|
|
}
|
|
else {
|
|
x = -2;
|
|
}
|
|
if (this.datas.pointC[0].y > 0) {
|
|
y = -2;
|
|
}
|
|
else {
|
|
y = -20;
|
|
}
|
|
this.lostIndicationSquare.lineStyle(2, '#f00').drawRect(x, y, w, h);
|
|
const flashAnimation = this.bindFlashAnimation([this.lostIndicationSquare], 'lostIndicationFlash');
|
|
flashAnimation.resume();
|
|
return;
|
|
}
|
|
const { pointB, pointC } = this.datas;
|
|
if (this.states.ipSingleSwitchStusNormal) {
|
|
this.graphics.fork.paint(pointB[0]);
|
|
this.removeAllAnimation();
|
|
}
|
|
else if (this.states.ipSingleSwitchStusReverse) {
|
|
this.graphics.fork.paint(pointC[0]);
|
|
this.removeAllAnimation();
|
|
}
|
|
super.draw();
|
|
this.graphics.label.text = this.datas.code;
|
|
//文字颜色
|
|
if (this.states.ipSingleSwitchStusBlocked1) {
|
|
this.graphics.label.style.fill = TurnoutLabelColor.RED;
|
|
}
|
|
else if (this.states.ipSingleSwitchStusNormal) {
|
|
this.graphics.label.style.fill = TurnoutLabelColor.GREEN;
|
|
}
|
|
else if (this.states.ipSingleSwitchStusReverse) {
|
|
this.graphics.label.style.fill = TurnoutLabelColor.YELLOW;
|
|
}
|
|
else if (this.states.ipSingleSwitchStusJammed ||
|
|
this.states.ipSingleSwitchStusLostIndication) {
|
|
this.graphics.label.style.fill = TurnoutLabelColor.WHITE;
|
|
}
|
|
super.draw();
|
|
this.labelRect.clear();
|
|
this.speedLimit.clear();
|
|
this.graphics.fork.visible = true;
|
|
this.removeAnimation('flash');
|
|
//文字框
|
|
if (this.states.ipSingleSwitchStusBlocked2) {
|
|
this.labelRect.clear().lineStyle(1, '#f00');
|
|
const { width, height } = this.graphics.label.getLocalBounds();
|
|
const { x, y } = this.graphics.label.transform.position;
|
|
this.labelRect.drawRect(x - width / 2, y - height / 2, width, height);
|
|
}
|
|
if ((this.states.speedLimit && this.states.speedLimit > 0) ||
|
|
this.states.ipSingleSwitchStusTsrBmMain ||
|
|
this.states.ipSingleSwitchStusTsrBmNormal ||
|
|
this.states.ipSingleSwitchStusTsrBmReverse ||
|
|
this.states.ipSingleSwitchStusTsrCbtcMain ||
|
|
this.states.ipSingleSwitchStusTsrCbtcNormal ||
|
|
this.states.ipSingleSwitchStusTsrCbtcReverse) {
|
|
let limitConf;
|
|
if (this.states.ipSingleSwitchStusTsrBmReverse ||
|
|
this.states.ipSingleSwitchStusTsrCbtcReverse) {
|
|
limitConf = 'reverse';
|
|
}
|
|
else if (this.states.ipSingleSwitchStusTsrBmNormal ||
|
|
this.states.ipSingleSwitchStusTsrCbtcNormal) {
|
|
limitConf = 'normal';
|
|
}
|
|
else {
|
|
limitConf = 'main';
|
|
}
|
|
const points = this.getSpeedLimitLinePoints(limitConf);
|
|
this.speedLimit.lineStyle(1, '#ff0');
|
|
points.forEach((ps) => {
|
|
this.speedLimit.moveTo(ps[0].x, ps[0].y);
|
|
for (let i = 1; i < ps.length; i++) {
|
|
this.speedLimit.lineTo(ps[i].x, ps[i].y);
|
|
}
|
|
});
|
|
}
|
|
if (this.states.ipSingleSwitchStusCut) {
|
|
if (this.states.ipSingleSwitchStusNormal) {
|
|
this.bindFlashAnimation([
|
|
this.graphics.fork,
|
|
this.graphics.sections[0],
|
|
this.graphics.sections[1],
|
|
], 'flash');
|
|
}
|
|
else if (this.states.ipSingleSwitchStusReverse) {
|
|
this.bindFlashAnimation([
|
|
this.graphics.fork,
|
|
this.graphics.sections[0],
|
|
this.graphics.sections[2],
|
|
], 'flash');
|
|
}
|
|
this.animation('flash')?.resume();
|
|
}
|
|
}
|
|
setLineColor(color) {
|
|
this.graphics.sections.forEach((g) => (g.stateFillColor = color));
|
|
}
|
|
getSpeedLimitLinePoints(conf) {
|
|
const [pa, pb, pc] = [
|
|
this.datas.pointA[0],
|
|
this.datas.pointB[0],
|
|
this.datas.pointC[0],
|
|
];
|
|
const [va, vb, vc] = [
|
|
new Vector2([pa.x, pa.y]),
|
|
new Vector2([pb.x, pb.y]),
|
|
new Vector2([pc.x, pc.y]),
|
|
];
|
|
const [vab, vbc] = [vb.subtract(va), vc.subtract(vb)];
|
|
vab.x * vbc.y - vab.y * vbc.x;
|
|
const offset = 10;
|
|
if (conf === 'main') {
|
|
return [
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
], offset, 'L'),
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
], offset, 'R'),
|
|
];
|
|
}
|
|
else if (conf === 'normal') {
|
|
return [
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
...this.datas.pointB.map((p) => ({ x: p.x, y: p.y })),
|
|
], offset, 'L'),
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
...this.datas.pointB.map((p) => ({ x: p.x, y: p.y })),
|
|
], offset, 'R'),
|
|
];
|
|
}
|
|
else {
|
|
return [
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
...this.datas.pointC.map((p) => ({ x: p.x, y: p.y })),
|
|
], offset, 'L'),
|
|
getParallelOfPolyline([
|
|
...this.datas.pointA.map((p) => ({ x: p.x, y: p.y })).reverse(),
|
|
{ x: 0, y: 0 },
|
|
...this.datas.pointC.map((p) => ({ x: p.x, y: p.y })),
|
|
], offset, 'R'),
|
|
];
|
|
}
|
|
}
|
|
bindFlashAnimation(gList, name) {
|
|
const flashAnimation = GraphicAnimation.init({
|
|
name,
|
|
run: (dt) => {
|
|
this.deltaTime += dt;
|
|
if (this.deltaTime > 60) {
|
|
this.deltaTime = 0;
|
|
gList.forEach((g) => (g.visible = true));
|
|
}
|
|
else if (this.deltaTime > 30) {
|
|
gList.forEach((g) => (g.visible = false));
|
|
}
|
|
},
|
|
});
|
|
this.addAnimation(flashAnimation);
|
|
return flashAnimation;
|
|
}
|
|
buildRelation() {
|
|
super.buildCommonRelation();
|
|
this.queryStore
|
|
.queryByType(JlSection.Type)
|
|
.forEach((section) => {
|
|
if (section.datas.sectionType === SectionType.TurnoutPhysical) {
|
|
if (section.datas.children &&
|
|
section.datas.children.includes(this.datas.id)) {
|
|
this.relationManage.addRelation(this, section);
|
|
}
|
|
return;
|
|
}
|
|
});
|
|
}
|
|
saveRelations() {
|
|
super.saveCommonRelations();
|
|
}
|
|
loadRelations() {
|
|
super.loadCommonRelations();
|
|
}
|
|
}
|
|
|
|
export { THTurnout };
|