/* * 信号机 */ import Line from 'zrender/src/graphic/shape/Line'; import Text from 'zrender/src/graphic/Text'; import Polygon from 'zrender/src/graphic/shape/Polygon'; import Polyline from 'zrender/src/graphic/shape/Polyline'; import Circle from 'zrender/src/graphic/shape/Circle'; import Arc from 'zrender/src/graphic/shape/Arc'; import Rect from 'zrender/src/graphic/shape/Rect'; import Group from 'zrender/src/container/Group'; import { arrows, triangular } from './libs/ShapePoints'; class Lamp extends Group { constructor(model) { super(); this.model = model; this.zlevel = model.zlevel; this.z = 10; this._create(); } _create() { const model = this.model; this.lamp = new Arc({ name: model.index, zlevel: this.zlevel + 1, z: this.z, shape: { cx: model.position.x, cy: model.position.y, r: model.style.signalR }, style: { lineWidth: 0.4, fill: model.style.backgroundColor, stroke: model.style.signalLampStandardColor } }); // let shapeDate = null; // if (model.highType === '01') { // // 矮柱 // if (model.drict != 1) { // // 左侧 // shapeDate = { // x: model.origin.x + model.drict * model.lampCount * 2 * model.style.signalR - 2.5, // y: model.origin.y + model.drict * model.style.signalR - 1, // width: model.style.signalR * 2 * model.lampCount + 2, // height: model.style.signalR * 2 + 2 // }; // } else { // shapeDate = { // x: model.origin.x - model.drict + 1.5, // y: model.origin.y - model.drict * model.style.signalR - 1, // width: model.style.signalR * 2 * model.lampCount + 2, // height: model.style.signalR * 2 + 2 // }; // } // } else { // // 高柱 // if (model.drict != 1) { // // 左侧 // shapeDate = { // x: model.origin.x + model.drict * model.lampCount * 2 * model.style.signalR - 2.5 - 3, // y: model.origin.y + model.drict * model.style.signalR - 1, // width: model.style.signalR * 2 * model.lampCount + 2, // height: model.style.signalR * 2 + 2 // }; // } else { // shapeDate = { // x: model.origin.x - model.drict + 1.5 + 3, // y: model.origin.y - model.drict * model.style.signalR - 1, // width: model.style.signalR * 2 * model.lampCount + 2, // height: model.style.signalR * 2 + 2 // }; // } // } this.lstop = new Line({ zlevel: this.zlevel + 1, z: this.z, origin: model.origin, rotation: -Math.PI / 180 * model.rotate, shape: { x1: model.position.x + (model.style.signalR + 1) * Math.cos(Math.PI / 4), y1: model.position.y + (model.style.signalR + 1) * Math.sin(Math.PI / 4), x2: model.position.x - (model.style.signalR + 1) * Math.cos(Math.PI / 4), y2: model.position.y - (model.style.signalR + 1) * Math.sin(Math.PI / 4) }, style: { lineWidth: 1.5, stroke: model.style.backgroundColor } }); this.rstop = new Line({ zlevel: this.zlevel + 1, z: this.z, origin: model.origin, rotation: -Math.PI / 180 * model.rotate, shape: { x1: model.position.x + (model.style.signalR + 1) * Math.cos(Math.PI / 4), y1: model.position.y + (model.style.signalR + 1) * (Math.sin(Math.PI / 4) - Math.sqrt(2)), x2: model.position.x - (model.style.signalR + 1) * Math.cos(Math.PI / 4), y2: model.position.y - (model.style.signalR + 1) * (Math.sin(Math.PI / 4) - Math.sqrt(2)) }, style: { lineWidth: 1.5, stroke: model.style.backgroundColor } }); this.add(this.lamp); } setColor(color) { if (color) { this.lamp.setStyle('fill', color); } } // 两条交叉黑线 setStop(has) { if (has) { this.add(this.lstop); this.add(this.rstop); } else { this.remove(this.lstop); this.remove(this.rstop); } } } // 自动进路箭头 class AutoSig extends Group { constructor(model) { super(); this.model = model; this.zlevel = model.zlevel; this.z = 10; this._create(); } _create() { const model = this.model; let rotation = Math.PI; if (model.drict != 1) { // 右侧 rotation = 0; } // 箭头 const x = model.position.x + model.drict * (model.lampCount * model.style.signalR + model.style.signalLampStandardWidth) * 2; const y = model.position.y - model.style.signalLampStandardWidth; this.arrowsControl = new Polygon({ zlevel: this.zlevel, rotation: rotation, origin: [x, y], shape: { points: arrows(x, y, model.style.stationControlDistance / 8, model.style.signalR * 0.8) }, style: { stroke: model.style.sidelineColor, lineWidth: 0.6, fill: model.style.signalLampGreenColor } }); this.add(this.arrowsControl); } // 停止动画 animationRecover() { this.arrowsControl.stopAnimation(false); } // 箭头颜色 setColor(color) { if (color) { this.arrowsControl.setStyle('fill', color); } } // 箭头闪烁 arrowsAnimation() { const fill = this.arrowsControl.style.fill; const style = this.model.style; this.arrowsControl.animate('style', true) .when(1000, { fill: style.backgroundColor, stroke: style.backgroundColor }) .when(2000, { fill: fill, stroke: style.sidelineColor }) .when(3000, { fill: style.backgroundColor, stroke: style.backgroundColor }) .when(4000, { fill: fill, stroke: style.sidelineColor }) .start(); } } // 运行方向三角 class JSigDrict extends Group { constructor(model) { super(); this.model = model; this.zlevel = model.zlevel; this.z = 10; this._create(); } _create() { // 箭头 const model = this.model; this.sigDrict = new Polygon({ zlevel: this.zlevel, z: this.z, shape: { // points: triangular(model.position.x, model.position.y + model.drict * model.style.signalLampStandardWidth, model.drict, model.style.signalR), points: triangular(model.position.x, model.position.y, model.drict, model.style.signalR) }, style: { stroke: model.style.backgroundColor, lineWidth: 0.5, fill: model.style.signalLampYellowColor } }); this.add(this.sigDrict); } } // 信号灯 几灯、高柱等 class JSiglamp extends Group { constructor(model) { super(); this.model = model; this.zlevel = model.zlevel; this.z = 10; this.lamps = new Group(); this.poles = new Group(); this._subType = 'SignalLamp'; this._val = '3'; /** 信号机*/ this._create(); } _create() { const model = this.model; this.text = new Text({ zlevel: this.zlevel, z: this.z, position: [0, 0], style: { x: model.position.x + model.namePosition.x, y: model.position.y + model.posit * (model.style.signalR + model.namePosition.y), text: model.name, textAlign: 'middle', textVerticalAlign: model.posit === 1 ? 'top' : 'bottom', textFont: 'bold ' + (model.style.textFontSize + 1) + 'px ' + model.style.textFontFormat, textFill: model.style.signalTextGreen } }); this.ver = new Polyline({ zlevel: this.zlevel, z: this.z - 2, shape: { points: [ [model.position.x, model.position.y + model.style.signalR * 1.2], [model.position.x, model.position.y - model.style.signalR * 1.2] ] }, style: { lineWidth: model.style.signalLampStandardWidth, stroke: model.style.signalLampStandardColor } }); this.hor = new Polyline({ zlevel: this.zlevel, z: this.z - 1, shape: { points: [ [model.position.x, model.position.y], [model.position.x + model.drict * model.style.signalR * 1.2, model.position.y] ] }, style: { lineWidth: model.style.signalLampStandardWidth, stroke: model.style.signalLampStandardColor } }); this.add(this.lamps); this.add(this.poles); this.setShowName(model.isShowName); this.setShowHighSigType(model.highType); // 旋转 if (model.rotate) { this.transformRotation(this.ver); this.transformRotation(this.hor); } } // border显示 setBorderVisible(isVisible) { if (isVisible) { this.textBorder.show(); this.lampsBorder.show(); } else { this.textBorder.hide(); this.lampsBorder.hide(); } } // 设置显示信号灯名称 setShowName(isShow) { if (isShow) this.add(this.text); else this.remove(this.text); } // 显示信号灯名称颜色 setNameColor(color) { this.text.setStyle({ textFill: color }); } setShowHighSigType(type) { const model = this.model; this.lamps.removeAll(); this.poles.removeAll(); this.poles.add(this.ver); if (type === '01') this.poles.remove(this.hor); else this.poles.add(this.hor); const highPosition = this.getEndPosition(model.highType); for (let i = 0; i < model.lampCount; i++) { const lamp = new Lamp({ style: model.style, zlevel: this.zlevel, lampCount: model.lampCount, position: { x: highPosition.x + i * model.drict * model.style.signalR * 2, y: highPosition.y }, index: i + 1, origin: { x: model.position.x, y: model.position.y }, rotate: model.rotate, drict: model.drict, highType: model.highType }); this.lamps.add(lamp); } this.delay = new Text({ zlevel: this.zlevel, style: { x: model.position.x - model.drict * (model.style.signalLampStandardWidth), y: model.position.y, text: this.model.delayCount || 0, textAlign: model.drict > 0 ? 'right' : 'left', textVerticalAlign: 'middle', textFont: 'bold ' + (model.style.textFontSize + 1) + 'px ' + model.style.textFontFormat, textFill: model.style.signalTextRed } }); this.add(this.delay); this.sigDriction = new JSigDrict({ style: model.style, zlevel: this.zlevel, position: { x: highPosition.x + model.drict * (model.lampCount * model.style.signalR * 2 + model.style.signalR - 1), y: model.position.y }, drict: model.drict, origin: { x: model.position.x, y: model.position.y }, rotate: model.rotate }); this.autoSig = new AutoSig({ style: model.style, zlevel: this.zlevel, position: { x: highPosition.x, y: highPosition.y }, lampCount: model.lampCount, drict: model.drict, origin: { x: model.position.x, y: model.position.y }, rotate: model.rotate }); // 旋转 if (model.rotate) { this.transformRotation(this.sigDriction); this.transformRotation(this.autoSig); this.transformRotation(this.lamps); this.transformRotation(this.delay); } const rect = this.lamps.getBoundingRect(); rect.union(this.hor.getBoundingRect()); this.lampsBorder = new Rect({ zlevel: this.zlevel, z: this.z - 3, silent: true, shape: rect, style: { lineDash: [3, 3], stroke: model.style.borderColor, fill: model.style.transparentColor } }); this.textBorder = new Rect({ zlevel: this.zlevel, z: this.z - 1, silent: true, shape: this.text.getBoundingRect(), style: { lineDash: [3, 3], stroke: model.style.borderColor, fill: model.style.borderContextBackgroundColor } }); this.add(this.lampsBorder); this.add(this.textBorder); } // 整体旋转信号灯 transformRotation(item) { if (this.model.rotate) { const origin = [this.model.position.x, this.model.position.y]; const rotation = -Math.PI / 180 * Number(this.model.rotate); item.origin = origin; item.rotation = rotation; item.dirty(); } } setColorByIndex(index, color) { for (let i = 0; i < this.model.lampCount; i++) { if (this.lamps.childAt(i).model.index === index) { this.lamps.childAt(i).setColor(color); return; } } } setStopByIndex(index, has) { for (let i = 0; i < this.model.lampCount; i++) { if (this.lamps.childAt(i).model.index === index) { this.lamps.childAt(i).setStop(has); return; } } } setDelayUnlockAnimation() { this.delay.show(); } setAutoFlickerAnimation() { this.autoSig.arrowsAnimation(); } setRecover() { this.delay.hide(); this.autoSig.animationRecover(); this.setNameColor(this.model.style.signalTextGreen); } setColorSig(color) { this.autoSig.setColor(color); } getEndPosition(type) { if (type === '01') { return { x: this.model.position.x + this.model.drict * this.model.style.signalR * 3 / 2, y: this.model.position.y }; } else { return { x: this.hor.shape.points[1][0] + this.model.drict * this.model.style.signalR, y: this.hor.shape.points[1][1] }; } } setShowSigDrict(showSigDrict) { if (showSigDrict) this.add(this.sigDriction); else this.remove(this.sigDriction); } setAutoSig(isShow) { if (isShow) this.add(this.autoSig); else this.remove(this.autoSig); } getShapeTipPoint() { if (this.lamps) { var distance = this.model.style.signalR; this.lamps.dirty(); const rect = this.lamps.getBoundingRect(); return { x: rect.x + Math.cos(Number(this.model.rotate)) * rect.width / 2 || (this.model.position.x), y: rect.y + Math.cos(Number(this.model.rotate)) * rect.height / 2 - distance || (this.model.position.y - distance) }; } return null; } } /** 按钮*/ class SigButton extends Group { constructor(model) { super(); this.model = model; this.zlevel = model.zlevel; this._subType = 'SignalButton'; this.z = 10; this._create(); } _create() { const model = this.model; this.sigNormalButtom = new Rect({ zlevel: this.zlevel, z: this.z, _subType: this._subType, _val: '1', shape: { x: model.position.x - model.style.signalR, y: 0, width: model.style.signalR * 2, height: model.style.signalR * 2 }, style: { lineWidth: 0.2, stroke: model.style.signalButtonDashColor, fill: model.style.signalButtonColor } }); this.sigNormalButtomDown = new Polyline({ zlevel: this.zlevel, z: this.z + 1, silent: true, shape: { points: [] }, style: { lineWidth: 0.8, stroke: model.style.backgroundColor } }); this.sigReentryButton = new Circle({ zlevel: this.zlevel, z: this.z, _subType: this._subType, _val: '2', // 折返按钮 shape: { cx: model.position.x, cy: 0, r: model.style.signalR }, style: { lineWidth: 0.2, stroke: model.style.signalButtonDashColor, fill: model.style.signalButtonColor } }); this.sigReentryButtonDown = new Arc({ zlevel: this.zlevel, z: this.z + 1, silent: true, shape: { cx: 0, cy: 0, r: 0, startAngle: Math.PI * 8 / 5, endAngle: Math.PI * 4 / 5, clockwise: false }, style: { lineWidth: 0.8, stroke: model.style.backgroundColor } }); this.add(this.sigNormalButtom); this.add(this.sigReentryButton); this.setSigDrict(); } setSigDrict() { const padding = 1; const model = this.model; const r = model.style.signalR * 0.8; if (model.drict === 1) { this.sigNormalButtom.attrKV('shape', { y: model.position.y - 1 / 2 * r }); this.sigReentryButton.attrKV('shape', { cy: model.position.y - 5 / 2 * r }); } else { this.sigReentryButton.attrKV('shape', { cy: model.position.y + 5 / 2 * r }); this.sigNormalButtom.attrKV('shape', { y: model.position.y - 3 / 2 * r }); } this.sigNormalButtomDown.attrKV('shape', { points: [ [model.position.x - padding + r, this.sigNormalButtom.shape.y + padding], [model.position.x + padding - r, this.sigNormalButtom.shape.y + padding], [model.position.x + padding - r, this.sigNormalButtom.shape.y + padding * 2 + r] ] }); this.sigReentryButtonDown.attrKV('shape', { cx: this.sigReentryButton.shape.cx, cy: this.sigReentryButton.shape.cy, r: this.sigReentryButton.shape.r - padding }); } colorRecover() { this.sigNormalButtom.setStyle('fill', this.model.style.signalButtonColor); this.sigReentryButton.setStyle('fill', this.model.style.signalButtonColor); } animationRecover() { this.sigNormalButtom.stopAnimation(true); this.sigReentryButton.stopAnimation(true); } recover() { this.colorRecover(); this.animationRecover(); } setButtonStatus(buttonStatus) { switch (buttonStatus) { case '00': case '01': this.remove(this.sigNormalButtomDown); this.remove(this.sigReentryButtonDown); this.recover(); break; case '02': this.add(this.sigNormalButtomDown); break; case '03': this.add(this.sigReentryButtonDown); break; case '04': this.remove(this.sigNormalButtomDown); this.sigNormalButtom.animateStyle(true) .when(1000, { fill: this.model.style.signalButtonLightenColor }) .when(2000, { fill: this.model.style.backgroundColor }) .start(); break; case '05': this.remove(this.sigReentryButtonDown); this.sigReentryButton.animateStyle(true) .when(1000, { fill: this.model.style.signalButtonLightenColor }) .when(2000, { fill: this.model.style.backgroundColor }) .start(); break; } } getShapeTipPoint(val) { var view = null; switch (val) { case '1': { view = this.sigNormalButtom; break; } case '2': { view = this.sigReentryButton; break; } default: { break; } } if (view) { var distance = 2; var rect = view.getBoundingRect(); return { x: rect.x + rect.width / 2, y: rect.y - distance }; } return null; } } export default class Signal extends Group { constructor({ _code, _type, zlevel, model, state }, style) { super(); this._code = _code; this._type = _type; this.zlevel = zlevel; this.model = model; this.state = state; this.style = style; this.selected = false; this.lampCount = parseInt(model.lampPositionType); this._create(); // this.on('mousedown', this.mouseclick); // this.on('mouseout', this.mouseleave); // this.on('mouseover', this.mouseenter); } _create() { const model = this.model; const state = this.state; const style = this.style; const drict = model.directionType === '01' ? -1 : 1; const posit = model.positionType === '01' ? -1 : 1; // 信号灯文字说明 this.siglamp = new JSiglamp({ style: style, zlevel: this.zlevel, position: { x: model.position.x, y: model.position.y + posit * style.signalDistance }, drict: drict, posit: posit, name: model.name, namePosition: model.namePosition, isShowName: model.nameShow, highType: model.lampPostType, lampCount: parseInt(model.lampPositionType), showSigDrict: this.showSigDrict, pop: true, rotate: model.rotate }); // 信号灯按钮 this.sigButton = new SigButton({ style: style, zlevel: this.zlevel, position: { x: model.buttonPosition.x, y: model.buttonPosition.y - posit * style.signalDistance }, drict: posit, pop: false }); this.add(this.siglamp); this.mouseStateRecover(); this.setState(state); } setButtonStatus(model) { if (model.buttonShow) { this.add(this.sigButton); } else { this.remove(this.sigButton); } if (this.sigButton) { this.sigButton.setButtonStatus(model.buttonStatus); } } setShowSigDrict(isShow) { this.siglamp.setShowSigDrict(isShow); } setAutoSig(isShow) { this.siglamp.setAutoSig(isShow); } setShowHighSigType(hightp) { if (this.siglamp) { this.highType = hightp; this.siglamp.setShowHighSigType(hightp); } } isPop(e) { for (var i = 0; i < this.childCount(); i++) { const rect = this.childAt(i).getBoundingRect(); if (rect.contain(e.offsetX, e.offsetY) && this.childAt(i).pop) { return true; } } } // 关闭 close() { if (this.lampCount === 1) { if (this.model.useType === '05') { /** 单灯 调车信号机*/ this.siglamp.setColorByIndex(1, this.style.signalLampBlueColor); } else { /** 单灯 出站信号机 */ /** 单灯 阻挡信号机*/ /** 单灯 阻挡兼调车信号 */ /** 单灯 列兼调信号机 */ this.siglamp.setColorByIndex(1, this.style.signalTextRed); } } } // 开放 open() { if (this.lampCount === 1) { /** 单灯 出站信号机*/ /** 单灯 阻隔信号机*/ this.siglamp.setColorByIndex(1, this.style.signalLampGreenColor); } } // 列车进路 trainRoute() { if (this.lampCount === 1) { /** 单灯 列兼调信号*/ this.siglamp.setColorByIndex(1, this.style.signalLampYellowColor); } } // 调车进路 shuntRoute() { if (this.lampCount === 1) { /** 单灯 列兼调信号*/ /** 单灯 阻挡兼调车信号*/ this.siglamp.setColorByIndex(1, this.style.signalLampWhiteColor); } } // 引导 guid() { } // 封锁 block() { this.siglamp.setColorByIndex(1, this.style.signalTextRed); this.siglamp.setNameColor(this.style.sectionBlockTextColor); } // 功能封锁 functionBlock() { } // 信号保护区段监视状态显示 signalblock() { } // 故障 fault() { } // 物理点灯 logicalLight() { for (var i = 0; i < this.lampCount; i++) { this.siglamp.setStopByIndex(i + 1, false); } } // 逻辑点灯 physicsLight() { for (var i = 0; i < this.lampCount; i++) { this.siglamp.setStopByIndex(i + 1, true); } } // 设置自动进路模式状态类型 setAutoRouteOpen() { if (this.model.linkageAutoRouteShow) { this.siglamp.setAutoSig(true); } else { this.siglamp.setAutoSig(false); } this.siglamp.setRecover(); this.siglamp.setColorSig(this.style.signalLampGreenColor); } // 信号机进路自动触发模式状态类型 setAutoAccessOpen() { if (this.model.atsAutoTriggerShow) { this.siglamp.setAutoSig(true); } else { this.siglamp.setAutoSig(false); } this.siglamp.setRecover(); this.siglamp.setColorSig(this.style.signalLampYellowColor); } // 设置自动信号模式状态类型 setAutoSignalOpen() { this.siglamp.setShowSigDrict(true); } // 隐藏自动信号和自动进路 setAutoClose() { this.siglamp.setColorSig(this.style.backgroundColor); this.siglamp.setAutoSig(false); this.siglamp.setShowSigDrict(false); } // 自动信号和自动进路开始动画 setAutoFlicker() { this.siglamp.setAutoFlickerAnimation(); } // 设置延时解锁 setDelayUnlock() { this.siglamp.setDelayUnlockAnimation(); } // 恢复状态 recover() { this.siglamp.setRecover(); } setState(state) { this.recover(); /** 设置状态 (点灯类型)*/ switch (state.status) { case '01': this.close(); break; // 关闭 case '02': this.open(); break; // 开放 case '03': this.guid(); break; // 引导 case '04': this.block(); break; // 封锁 case '05': this.fault(); break; // 故障 case '06': this.block(); break; // 功能封锁 case '07': this.signalblock(); break; // 信号保护区段检测 } /** 进路性质类型*/ switch (state.natureType) { case '01': this.trainRoute(); break; // 列车进路 case '02': this.shuntRoute(); break; // 调车进路 } /** 设置点灯类型*/ switch (state.lightType) { case '01': this.logicalLight(); break; // 设置逻辑点灯 case '02': this.physicsLight(); break; // 设置物理点灯 } /** 设置自动类型*/ switch (state.autoType) { case '01': this.setAutoClose(); break; // 隐藏 隐藏自动信号和自动进路 case '02': this.setAutoSignalOpen(); break; // 显示 设置自动信号模式状态类型 case '03': this.setAutoRouteOpen(); break; // 显示 设置自动进路模式状态类型 case '04': this.setAutoAccessOpen(); break; // 显示 信号机进路自动触发模式状态类型 } /** 延时解锁*/ state.delayType = '02'; switch (state.delayType) { case '01': break; // 未延时解锁 case '02': break; // 人工闭塞延时解锁 case '03': break; // 自动闭塞延时解锁 } /** 信号机进路办理,先停止动画,再判断当前颜色是否闪烁*/ if (state.routeSetting && (state.autoType == '03' || state.autoType == '04')) { this.setAutoFlicker(); } } getShapeTipPoint(val) { if (val === '1' || val === '2') { return this.sigButton.getShapeTipPoint(val); } else { return this.siglamp.getShapeTipPoint(val); } } mouseStateVisible() { this.siglamp.setBorderVisible(true); this.siglamp.setNameColor('#000'); } mouseStateRecover() { this.siglamp.setBorderVisible(false); this.siglamp.setNameColor(this.style.signalTextGreen); } mouseclick(e) { if ([3].includes(e.which)) { this.selected = !this.selected; if (this.selected) { this.mouseStateVisible(); } } } mouseenter() { if (!this.selected) { this.mouseStateVisible(); } } mouseleave() { if (!this.selected) { this.mouseStateRecover(); } } }