rt-graphic-component/components/packages/Turnout/THTurnout.js
joylink_zhaoerwei f87f2178fb 道岔测试
2024-01-19 13:52:29 +08:00

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 };