rt-graphic-component/components/packages/Train/Train.js
2024-01-05 15:36:00 +08:00

324 lines
11 KiB
JavaScript

import { Container, Graphics, Point, Color } from 'pixi.js';
import { JlGraphic, JlGraphicTemplate, GraphicIdGenerator, calculateMirrorPoint, VectorText } from 'jl-graphic';
import { getTrainConsts, EnumDiriveModel, EnumTrainType } from './TrainConfig.js';
class TrainHead extends Container {
arrow; // 列车箭头
pause; // 列车停止
train;
arrowColor;
pauseColor;
constructor(train) {
super();
this.arrow = new Graphics();
this.pause = new Graphics();
this.addChild(this.arrow);
this.addChild(this.pause);
this.train = train;
this.arrowColor = this.train.constDatas.arrowDefaultColor;
this.pauseColor = this.train.constDatas.pauseDefaultColor;
}
clear() {
this.arrow.clear();
this.pause.clear();
}
doRepaint() {
this.clear();
const trainConsts = this.train.constDatas;
const bodyWH = this.train.trainbody.getBodyWH();
const marginX = trainConsts.marginX;
const pauseW = trainConsts.pauseW;
const bodyWidth = bodyWH ? bodyWH.width : trainConsts.bodyWidth;
const bodyHeight = bodyWH ? bodyWH.height : trainConsts.bodyHeight;
let pauseTW = pauseW + marginX;
if (trainConsts.arrowPauseOnlyOne) {
pauseTW = 0;
}
let arrowPoint = [
-bodyHeight * 0.4 - marginX - pauseTW - bodyWidth / 2,
0,
-marginX - pauseTW - bodyWidth / 2,
bodyHeight / 2,
-marginX - pauseTW - bodyWidth / 2,
-bodyHeight / 2,
];
let pausePoint = [
-marginX - pauseW / 2 - bodyWidth / 2,
-bodyHeight / 2,
-marginX - pauseW / 2 - bodyWidth / 2,
bodyHeight / 2,
];
// 列车是向右或者向上
if (this.isRight()) {
const aP = [];
arrowPoint.forEach((item, index) => {
if (index % 2 == 1) {
const p = new Point(arrowPoint[index - 1], item);
const newP = calculateMirrorPoint(new Point(0, 0), p);
aP.push(newP.x, newP.y);
}
});
arrowPoint = aP;
const pP = [];
pausePoint.forEach((item, index) => {
if (index % 2 == 1) {
const p = new Point(pausePoint[index - 1], item);
const newP = calculateMirrorPoint(new Point(0, 0), p);
pP.push(newP.x, newP.y);
}
});
pausePoint = pP;
}
this.pause.lineStyle(pauseW, this.pauseColor, 1);
this.pause.moveTo(pausePoint[0], pausePoint[1]);
this.pause.lineTo(pausePoint[2], pausePoint[3]);
const arrow = this.arrow;
arrow.beginFill(this.arrowColor, 1);
arrow.drawPolygon(arrowPoint);
arrow.endFill();
}
isRight() {
let d = false;
if (this.train.isRightRoTop) {
d = true;
}
return d;
}
}
class TrainBody extends Container {
bodyRact;
codeAGraph = new VectorText(''); //识别号AA
codeBGraph = new VectorText(''); //识别号BBB
train;
codeAColor;
codeBColor;
codeAText;
codeBText;
constructor(train) {
super();
this.bodyRact = new Graphics();
this.addChild(this.bodyRact);
this.addChild(this.codeAGraph);
this.addChild(this.codeBGraph);
this.train = train;
this.codeAGraph.setVectorFontSize(this.train.constDatas.codeFontSize);
this.codeBGraph.setVectorFontSize(this.train.constDatas.codeFontSize);
this.codeAColor = this.train.constDatas.codeColor;
this.codeBColor = this.train.constDatas.codeColor;
this.codeAText = '';
this.codeBText = '';
}
clear() {
this.bodyRact.clear();
}
getBodyWH() {
const bodyAWH = this.codeAGraph.getLocalBounds();
const bodyBWH = this.codeBGraph.getLocalBounds();
return {
width: bodyAWH.width + bodyBWH.width + this.train.constDatas.bodyPadding * 2,
height: bodyAWH.height + this.train.constDatas.bodyPadding * 2,
};
}
doRepaint() {
this.clear();
const trainConsts = this.train.constDatas;
const codeAGraph = this.codeAGraph;
const codeBGraph = this.codeBGraph;
codeAGraph.text = this.codeAText;
codeBGraph.text = this.codeBText;
codeAGraph.anchor.set(0.5);
codeBGraph.anchor.set(0.5);
const styleA = {
fill: this.codeAColor,
fontSize: trainConsts.codeFontSize,
};
const styleB = {
fill: this.codeBColor,
fontSize: trainConsts.codeFontSize,
};
codeAGraph.style = styleA;
codeBGraph.style = styleB;
if (this.codeBText) {
const bodyAWH = codeAGraph.getLocalBounds();
const bodyBWH = codeBGraph.getLocalBounds();
codeAGraph.position.set(-bodyBWH.width / 2, 0);
codeBGraph.position.set(bodyAWH.width / 2, 0);
}
codeAGraph.updateOnScaled();
codeBGraph.updateOnScaled();
if (this.train.constDatas.hasBodyRact) {
const bodyRact = this.bodyRact;
const { width: bodyWidth, height: bodyHeight } = this.getBodyWH();
bodyRact.lineStyle(trainConsts.borderWidth, new Color(trainConsts.borderColor));
const bgColor = trainConsts.bodyBgColor;
bodyRact.beginFill(new Color(bgColor));
bodyRact.drawRect(-bodyWidth / 2, -bodyHeight / 2, bodyWidth, bodyHeight);
bodyRact.endFill();
}
}
}
class StatusText extends Container {
sText = new VectorText('');
train;
constructor(train) {
super();
this.train = train;
this.addChild(this.sText);
}
doRepaint(text, bodyWH) {
const trainConsts = this.train.constDatas;
let t = text;
if (trainConsts.statusTextTransform) {
t = trainConsts.statusTextTransform[text];
}
this.sText.text = t;
this.sText.anchor.set(0.5);
const c = trainConsts.statusTextColor[text] || trainConsts.statusTextColor.D;
const style = {
fill: c,
fontSize: trainConsts.textFontSize,
};
this.sText.style = style;
const { width: bodyWidth, height: bodyHeight } = bodyWH;
const { width: textHWidth, height: textHeight } = this.sText.getLocalBounds();
const num = trainConsts.statusTextList.length;
let index = trainConsts.statusTextList.findIndex((item) => {
return item == text;
});
if (index < 0) {
index = (num - 1) / 2; // 中间
}
const textMargin = (bodyWidth - textHWidth * num) / (num - 1);
this.sText.position.set(-bodyWidth / 2 + (textHWidth * (index * 2 + 1)) / 2 + textMargin * index, -bodyHeight / 2 - textHeight / 2 - trainConsts.textMarginY);
}
clear() {
this.sText.text = '';
}
}
/**
* 列车
*/
class Train extends JlGraphic {
static Type = 'Train';
trainHead;
trainbody;
statusTextMap = new Map();
isRightRoTop; // 方向是否向右或者向上
constDatas;
constructor(data) {
super(Train.Type);
this.isRightRoTop = false;
this.constDatas = getTrainConsts();
if (data) {
Object.assign(this.constDatas, data);
}
this.trainbody = new TrainBody(this);
this.trainHead = new TrainHead(this);
this.addChild(this.trainHead);
this.addChild(this.trainbody);
}
get datas() {
return this.getDatas();
}
doRepaint() {
this.trainbody.doRepaint();
this.trainHead.doRepaint();
}
// 设置列车箭头是否显示
setArrowVisible(v) {
this.trainHead.arrow.visible = v;
}
// 设置列车暂停是否显示
setPauseVisible(v) {
this.trainHead.pause.visible = v;
}
run() {
this.trainHead.arrow.visible = true;
this.trainHead.pause.visible = !this.constDatas.arrowPauseOnlyOne;
}
stop() {
this.trainHead.arrow.visible = false;
this.trainHead.pause.visible = true;
}
setCodeAText(v) {
this.trainbody.codeAText = v;
}
setCodeBText(v) {
this.trainbody.codeBText = v;
}
// 设置驾驶模式对应颜色
setDiriveModelColor(s) {
const aModelColorEnum = this.constDatas.arrowDiriveModelColorEnum;
const pModelColorEnum = this.constDatas.pauseDiriveModelColorEnum;
let aColor = aModelColorEnum.AM;
let pColor = pModelColorEnum.AM;
if (s == EnumDiriveModel.SM) {
aColor = aModelColorEnum.SM;
pColor = pModelColorEnum.SM;
}
else if (s == EnumDiriveModel.RM) {
aColor = aModelColorEnum.RM;
pColor = pModelColorEnum.RM;
}
this.trainHead.arrowColor = aColor;
this.trainHead.pauseColor = pColor;
}
// 设置列车类型对应颜色
setTrainTypeColor(s) {
const typeColorEnum = this.constDatas.typeColorEnum;
const fillAColor = typeColorEnum.schedule;
let fillBColor = typeColorEnum.schedule;
if (s == EnumTrainType.late) {
fillBColor = typeColorEnum.late;
}
else if (s == EnumTrainType.early) {
fillBColor = typeColorEnum.early;
}
else if (s == EnumTrainType.head) {
fillBColor = typeColorEnum.head;
}
else if (s == EnumTrainType.manual) {
fillBColor = typeColorEnum.manual;
}
this.trainbody.codeAColor = fillAColor;
this.trainbody.codeBColor = fillBColor;
}
// 显示列车状态文字
showStatus(s) {
if (this.statusTextMap.has(s)) {
return;
}
const bodyWH = this.trainbody.getBodyWH();
const textD = new StatusText(this);
textD.doRepaint(s, bodyWH);
this.addChild(textD);
this.statusTextMap.set(s, textD);
}
// 隐藏列车状态文字
hideStatus(s) {
if (!this.statusTextMap.has(s)) {
return;
}
const textD = this.statusTextMap.get(s);
if (textD) {
textD.clear();
this.statusTextMap.delete(s);
}
}
}
class TrainTemplate extends JlGraphicTemplate {
updataConsts;
constructor(stateTemplate, data) {
super(Train.Type, { stateTemplate });
this.updataConsts = data;
}
new() {
const train = new Train(this.updataConsts);
train.id = GraphicIdGenerator.next();
train.loadState(this.states);
return train;
}
}
export { Train, TrainTemplate };