Merge branch 'master' of git.code.tencent.com:xian-ncc-da/xian-ncc-da-client

This commit is contained in:
Yuan 2023-06-09 09:36:19 +08:00
commit 8c0ed787f5
16 changed files with 288 additions and 464 deletions

View File

@ -20,7 +20,7 @@
<station-template></station-template>
</template>
<template v-if="drawStore.drawGraphicType === Train.Type">
<TrainProperty></TrainProperty>
<train-template></train-template>
</template>
</q-card-section>
</q-card>
@ -74,6 +74,7 @@ import LinkTemplate from './templates/LinkTemplate.vue';
import RectTemplate from './templates/RectTemplate.vue';
import PlatformTemplate from './templates/PlatformTemplate.vue';
import StationTemplate from './templates/StationTemplate.vue';
import TrainTemplate from './templates/TrainTemplate.vue';
import CanvasProperty from './properties/CanvasProperty.vue';
import LinkProperty from './properties/LinkProperty.vue';
import RectProperty from './properties/RectProperty.vue';

View File

@ -24,7 +24,7 @@
outlined
@blur="onUpdate"
label="x"
v-model.number="stationModel.circlePoint.x"
v-model.number="circlePosition.x"
type="number"
step="any"
class="col"
@ -33,7 +33,7 @@
outlined
@blur="onUpdate"
label="y"
v-model.number="stationModel.circlePoint.y"
v-model.number="circlePosition.y"
type="number"
step="any"
class="col"
@ -54,6 +54,7 @@ import { onMounted, reactive, ref, watch } from 'vue';
const drawStore = useDrawStore();
const stationModel = reactive(new StationData());
const hasCircle = ref('是');
let circlePosition = ref({ x: 0, y: -20 });
const optionsCircle = ['是', '否'];
enum showSelect {
= 'true',
@ -79,6 +80,9 @@ onMounted(() => {
const station = drawStore.selectedGraphic as Station;
if (station) {
stationModel.copyFrom(station.saveData());
if (stationModel.childTransforms) {
circlePosition.value = stationModel.childTransforms[0].transform.position;
}
hasCircle.value = (showSelectData as never)[stationModel.hasCircle + ''];
}
});

View File

@ -8,63 +8,6 @@
hint=""
@blur="onUpdate"
/>
<q-input
outlined
v-model="trainModel.codeColor"
@blur="onUpdate"
label="车号颜色"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '车号颜色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="trainModel.codeColor"
@change="
(val) => {
trainModel.codeColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-input
outlined
v-model="trainModel.headColor"
@blur="onUpdate"
label="箭头颜色"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '车箭头颜色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="trainModel.headColor"
@change="
(val) => {
trainModel.headColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-input
outlined
v-model.number="trainModel.codeFontSize"
type="number"
@blur="onUpdate"
label="字体大小"
lazy-rules
:rules="[(val) => (val && val > 0) || '字体大小必须大于0']"
/>
<q-select
outlined
@blur="onUpdate"
@ -72,63 +15,6 @@
:options="optionsDoor"
label="是否有边框"
/>
<q-input
outlined
v-model.number="trainModel.borderWidth"
type="number"
@blur="onUpdate"
label="边框线宽"
lazy-rules
:rules="[(val) => (val && val > 0) || '边框线宽必须大于0']"
/>
<q-input
outlined
v-model="trainModel.borderColor"
@blur="onUpdate"
label="边框颜色"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '边框颜色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="trainModel.borderColor"
@change="
(val) => {
trainModel.borderColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-input
outlined
v-model="trainModel.bodyColor"
@blur="onUpdate"
label="背景颜色"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '背景颜色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="trainModel.bodyColor"
@change="
(val) => {
trainModel.bodyColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
<q-select
outlined
@blur="onUpdate"

View File

@ -1,38 +1,19 @@
<template>
<q-form>
<q-input
<q-select
outlined
v-model.number="template.codeFontSize"
type="number"
@blur="onUpdate"
label="字体大小 *"
lazy-rules
:rules="[(val) => (val && val > 0) || '字体大小必须大于0']"
v-model="template.hasBorder"
:options="optionsDoor"
label="是否有边框"
/>
<q-input
<q-select
outlined
v-model="template.headColor"
@blur="onUpdate"
label="箭头颜色 *"
lazy-rules
:rules="[(val) => (val && val.length > 0) || '箭头颜色不能为空']"
>
<template v-slot:append>
<q-icon name="colorize" class="cursor-pointer">
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
<q-color
v-model="template.headColor"
@change="
(val) => {
template.headColor = val;
onUpdate();
}
"
/>
</q-popup-proxy>
</q-icon>
</template>
</q-input>
v-model="template.trainDirection"
:options="optionsDirection"
label="行驶方向"
/>
</q-form>
</template>
@ -43,18 +24,19 @@ import { onMounted, reactive } from 'vue';
const drawStore = useDrawStore();
const template = reactive({
codeFontSize: 22,
headColor: '#00FF00',
trainDirection: 'left',
hasBorder: true,
});
const optionsDoor = ['是', '否'];
const optionsDirection = ['向左', '向右'];
onMounted(() => {
const type = drawStore.drawGraphicType;
if (type) {
const gt = drawStore.drawGraphicTemplate;
if (gt) {
const lt = gt as TrainTemplate;
template.codeFontSize = lt.codeFontSize;
template.headColor = lt.headColor;
template.trainDirection = lt.trainDirection;
template.hasBorder = lt.hasBorder;
}
}
});
@ -62,8 +44,8 @@ onMounted(() => {
function onUpdate() {
const gt = drawStore.drawGraphicTemplate as TrainTemplate;
if (gt) {
gt.codeFontSize = template.codeFontSize;
gt.headColor = template.headColor;
gt.trainDirection = template.trainDirection;
gt.hasBorder = template.hasBorder;
}
}
</script>

View File

@ -1,5 +1,4 @@
import * as pb_1 from 'google-protobuf';
import { IPointData } from 'pixi.js';
import { IStationData } from 'src/graphics/station/Station';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -32,12 +31,6 @@ export class StationData extends GraphicDataBase implements IStationData {
set hasCircle(v: boolean) {
this.data.hasCircle = v;
}
get circlePoint(): IPointData {
return this.data.circlePoint;
}
set circlePoint(point: IPointData) {
this.data.circlePoint = new graphicData.Point({ x: point.x, y: point.y });
}
clone(): StationData {
return new StationData(this.data.cloneMessage());
}

View File

@ -1,5 +1,4 @@
import * as pb_1 from 'google-protobuf';
import { IPointData } from 'pixi.js';
import { ITrainData } from 'src/graphics/train/Train';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -26,18 +25,6 @@ export class TrainData extends GraphicDataBase implements ITrainData {
set code(v: string) {
this.data.code = v;
}
get codeColor(): string {
return this.data.codeColor;
}
set codeColor(v: string) {
this.data.codeColor = v;
}
get codeFontSize(): number {
return this.data.codeFontSize;
}
set codeFontSize(v: number) {
this.data.codeFontSize = v;
}
get trainDirection(): string {
return this.data.trainDirection;
}
@ -50,36 +37,6 @@ export class TrainData extends GraphicDataBase implements ITrainData {
set hasBorder(v: boolean) {
this.data.hasBorder = v;
}
get borderWidth(): number {
return this.data.borderWidth;
}
set borderWidth(v: number) {
this.data.borderWidth = v;
}
get borderColor(): string {
return this.data.borderColor;
}
set borderColor(v: string) {
this.data.borderColor = v;
}
get headColor(): string {
return this.data.headColor;
}
set headColor(v: string) {
this.data.headColor = v;
}
get bodyColor(): string {
return this.data.bodyColor;
}
set bodyColor(v: string) {
this.data.bodyColor = v;
}
get point(): IPointData {
return this.data.point;
}
set point(point: IPointData) {
this.data.point = new graphicData.Point({ x: point.x, y: point.y });
}
clone(): TrainData {
return new TrainData(this.data.cloneMessage());
}

View File

@ -121,6 +121,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
new TurnoutDraw(app, () => {
return new TurnoutData();
}),
// new TrainDraw(app, () => {
// return new TrainData();
// }),
],
});
@ -175,6 +178,14 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
},
})
);
// app.addKeyboardListener(
// new KeyListener({
// value: 'KeyR',
// onPress: () => {
// app.interactionPlugin(Train.Type).resume();
// },
// })
// );
app.addKeyboardListener(
new KeyListener({
value: 'KeyS',

View File

@ -38,6 +38,7 @@ export class Signal extends JlGraphic {
constructor() {
super(Signal.Type);
this.codeGraph.name = 'signalCode';
this.addChild(this.codeGraph);
this.addChild(this.humanControl);
this.addChild(this.fleetMode);
@ -74,24 +75,20 @@ export class Signal extends JlGraphic {
signal.codeGraph.setVectorFontSize(signalConsts.codeFontSize);
signal.codeGraph.anchor.set(0.5);
signal.codeGraph.style.fill = SignalColorEnum.codeColor;
signal.codeGraph.position.set(0, signalConsts.nameOffsetY);
const codeTransform = data?.childTransforms?.find(
(item) => item.name === 'signalCode'
);
if (codeTransform) {
const position = codeTransform?.transform.position;
const rotation = codeTransform?.transform?.rotation;
signal.codeGraph.position.set(position?.x, position?.y);
signal.codeGraph.rotation = rotation || 0;
} else {
signal.codeGraph.position.set(0, signalConsts.nameOffsetY);
}
}
doRepaint(): void {
// this.lampBody.paint(signalConsts.lampNum);
// this.humanControl.beginFill(SignalColorEnum.humanControlColor, 1);
// this.humanControl.drawPolygon(signalConsts.humanControlPath);
// this.humanControl.endFill();
// this.fleetMode.beginFill(SignalColorEnum.fleetModeColor, 1);
// const fleetModePath = Signal.computedFleetModePath(this.lampBody.width);
// this.fleetMode.drawPolygon(fleetModePath);
// this.fleetMode.endFill();
// this.codeGraph.text = this.datas.code || '信号机Signal';
// this.codeGraph.style.fill = SignalColorEnum.codeColor;
// this.codeGraph.setVectorFontSize(signalConsts.codeFontSize);
// this.codeGraph.anchor.set(0.5);
// this.codeGraph.style.fill = SignalColorEnum.codeColor;
// this.codeGraph.position.set(0, signalConsts.nameOffsetY);
Signal.paint(this, this.datas);
}
}

View File

@ -1,9 +1,10 @@
import { FederatedPointerEvent, Point, Graphics, Color } from 'pixi.js';
import { FederatedPointerEvent, Point, Graphics } from 'pixi.js';
import {
GraphicDrawAssistant,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
GraphicTransformEvent,
VectorText,
} from 'src/jl-graphic';
import { ISignalData, Signal, SignalTemplate } from './Signal';
@ -87,9 +88,14 @@ export class signalInteraction extends GraphicInteractionPlugin<Signal> {
g.codeGraph.draggable = true;
g.codeGraph.selectable = true;
g.codeGraph.rotatable = true;
g.codeGraph.scalable = true;
// g.codeGraph.scalable = true;
g.codeGraph.transformSave = true;
g.codeGraph.eventMode = 'static';
// g.codeGraph.on('transformend', this.onScaleDragEnd, this);
}
// onScaleDragEnd() {
// console.log('-----------------');
// }
unbind(g: Signal): void {
g.eventMode = 'none';
g.scalable = false;
@ -97,7 +103,8 @@ export class signalInteraction extends GraphicInteractionPlugin<Signal> {
g.codeGraph.draggable = false;
g.codeGraph.selectable = false;
g.codeGraph.rotatable = false;
g.codeGraph.scalable = false;
// g.codeGraph.scalable = false;
g.codeGraph.transformSave = false;
g.codeGraph.eventMode = 'none';
}
}

View File

@ -1,4 +1,4 @@
import { Color, Graphics, IPointData, Point } from 'pixi.js';
import { Color, Graphics } from 'pixi.js';
import {
GraphicData,
JlGraphic,
@ -12,14 +12,13 @@ export interface IStationData extends GraphicData {
set code(v: string);
get hasCircle(): boolean; // 是否有圆圈--线网图
set hasCircle(v: boolean);
get circlePoint(): IPointData; // 位置坐标
set circlePoint(point: IPointData);
clone(): IStationData;
copyFrom(data: IStationData): void;
eq(other: IStationData): boolean;
}
const stationConsts = {
circleOffsetY: -20,
radius: 5,
borderWidth: 1,
borderColor: '0xff0000',
@ -37,6 +36,7 @@ export class Station extends JlGraphic {
super(Station.Type);
this.addChild(this.codeGraph);
this.addChild(this.circleGraphic);
this.circleGraphic.name = 'circle';
}
get datas(): IStationData {
@ -58,7 +58,14 @@ export class Station extends JlGraphic {
circleGraphic.beginFill(stationConsts.fillColor, 1);
circleGraphic.drawCircle(0, 0, stationConsts.radius);
circleGraphic.endFill;
circleGraphic.position.set(datas.circlePoint.x, datas.circlePoint.y);
if (datas.childTransforms?.length) {
circleGraphic.position.set(
datas.childTransforms[0].transform.position.x,
datas.childTransforms[0].transform.position.y
);
} else {
circleGraphic.position.set(0, stationConsts.circleOffsetY);
}
}
}
doRepaint(): void {
@ -69,12 +76,10 @@ export class Station extends JlGraphic {
export class StationTemplate extends JlGraphicTemplate<Station> {
hasCircle: boolean;
radius: number;
circlePoint: IPointData;
constructor() {
super(Station.Type);
this.hasCircle = false;
this.hasCircle = true;
this.radius = stationConsts.radius;
this.circlePoint = new Point(0, -15);
}
new(): Station {
return new Station();

View File

@ -55,7 +55,6 @@ export class StationDraw extends GraphicDrawAssistant<
const template = this.graphicTemplate;
data.transform = this.container.saveTransform();
data.hasCircle = template.hasCircle;
data.circlePoint = template.circlePoint;
return true;
}
}
@ -78,10 +77,21 @@ export class stationInteraction extends GraphicInteractionPlugin<Station> {
g.cursor = 'pointer';
g.scalable = true;
g.rotatable = true;
if (g.datas.hasCircle) {
g.circleGraphic.eventMode = 'static';
g.circleGraphic.cursor = 'pointer';
g.circleGraphic.draggable = true;
g.circleGraphic.selectable = true;
g.circleGraphic.transformSave = true;
}
}
unbind(g: Station): void {
g.eventMode = 'none';
g.scalable = false;
g.rotatable = false;
g.circleGraphic.eventMode = 'none';
g.circleGraphic.draggable = false;
g.circleGraphic.selectable = false;
g.circleGraphic.transformSave = false;
}
}

View File

@ -1,4 +1,4 @@
import { Color, Graphics, IPointData } from 'pixi.js';
import { Color, Graphics, Container } from 'pixi.js';
import {
GraphicData,
JlGraphic,
@ -9,29 +9,20 @@ import {
export interface ITrainData extends GraphicData {
get code(): string; // 车号
set code(v: string);
get codeColor(): string; // 车号颜色
set codeColor(v: string);
get codeFontSize(): number; // 车号字体大小
set codeFontSize(v: number);
get trainDirection(): string; // 行驶方向
set trainDirection(v: string);
get hasBorder(): boolean; // 是否有边框
set hasBorder(v: boolean);
get borderWidth(): number; // 边框线宽
set borderWidth(v: number);
get borderColor(): string; // 边框颜色
set borderColor(v: string);
get headColor(): string; // 箭头颜色
set headColor(v: string);
get bodyColor(): string; // 背景色
set bodyColor(v: string);
get point(): IPointData; // 位置坐标
set point(point: IPointData);
clone(): ITrainData;
copyFrom(data: ITrainData): void;
eq(other: ITrainData): boolean;
}
interface bodyWH {
width: number; // 宽
height: number; // 高
}
// 列车颜色
export enum TrainColorEnum {
headColor = '0x00FF00', // 箭头颜色
@ -41,143 +32,177 @@ export enum TrainColorEnum {
}
export const trainConsts = {
codeWidth: 120,
codeHeight: 40,
codePadding: 5,
borderWidth: 1,
codeFontSize: 22,
marginX: 2, // 图形x轴边距
pauseW: 2, // 停止框宽度
};
export class Train extends JlGraphic {
static Type = 'Train';
arrowLeft: Graphics;
pauseLeft: Graphics;
arrowRight: Graphics;
pauseRight: Graphics;
codeRact: Graphics;
codeGraph: VectorText = new VectorText(''); //车号
constructor() {
super(Train.Type);
this.arrowLeft = new Graphics();
this.pauseLeft = new Graphics();
this.arrowRight = new Graphics();
this.pauseRight = new Graphics();
this.codeRact = new Graphics();
this.addChild(this.arrowLeft);
this.addChild(this.pauseLeft);
this.addChild(this.arrowRight);
this.addChild(this.pauseRight);
this.addChild(this.codeRact);
this.addChild(this.codeGraph);
this.codeGraph.setVectorFontSize(trainConsts.codeFontSize);
export class TrainHead extends Container {
arrow: Graphics; // 箭头
pause: Graphics; // 停止
isLeftDirection: boolean; // 是否向左
constructor(direction: string) {
super();
this.arrow = new Graphics();
this.pause = new Graphics();
this.isLeftDirection = direction == 'left';
this.addChild(this.arrow);
this.addChild(this.pause);
}
get datas(): ITrainData {
return this.getDatas<ITrainData>();
clear() {
this.arrow.clear();
this.pause.clear();
}
doRepaint(): void {
this.position.set(this.datas.point.x, this.datas.point.y);
const codeGraph = this.codeGraph;
const codeRact = this.codeRact;
if (this.datas.code == '') {
codeGraph.text = '01110111';
} else {
codeGraph.text = this.datas.code;
}
codeGraph.setVectorFontSize(this.datas.codeFontSize);
codeGraph.anchor.set(0.5);
const style = {
fill: this.datas.codeColor,
padding: 5,
};
codeGraph.style = style;
const {
x: codeX,
y: codeY,
width: codeWidth,
height: codeHeight,
} = codeGraph.getLocalBounds();
doRepaint(bodyWH?: bodyWH) {
this.clear();
const marginX = trainConsts.marginX;
const pauseW = trainConsts.pauseW;
const arrowLeft = this.arrowLeft;
arrowLeft.beginFill(this.datas.headColor, 1);
arrowLeft.drawPolygon([
const codeWidth = bodyWH ? bodyWH.width : trainConsts.codeWidth;
const codeHeight = bodyWH ? bodyWH.height : trainConsts.codeHeight;
let arrowPoint = [
-codeHeight * 0.4 - marginX - pauseW - marginX - codeWidth / 2,
0,
-marginX - pauseW - marginX - codeWidth / 2,
codeHeight / 2,
-marginX - pauseW - marginX - codeWidth / 2,
-codeHeight / 2,
]);
arrowLeft.endFill();
this.pauseLeft.beginFill(this.datas.headColor, 1);
this.pauseLeft.drawRect(0, 0, pauseW, codeHeight);
this.pauseLeft.endFill();
this.pauseLeft.position.set(
-marginX - pauseW - codeWidth / 2,
-codeHeight / 2
);
this.pauseRight.beginFill(this.datas.headColor, 1);
this.pauseRight.drawRect(0, 0, pauseW, codeHeight);
this.pauseRight.endFill();
this.pauseRight.position.set(marginX + codeWidth / 2, -codeHeight / 2);
const arrowRight = this.arrowRight;
arrowRight.beginFill(this.datas.headColor, 1);
arrowRight.drawPolygon([
codeWidth / 2 + marginX + pauseW + marginX + codeHeight * 0.4,
0,
codeWidth / 2 + marginX + pauseW + marginX,
codeHeight / 2,
codeWidth / 2 + marginX + pauseW + marginX,
-codeHeight / 2,
]);
arrowRight.endFill();
if (this.datas.hasBorder) {
];
let pausePoint = [-marginX - pauseW - codeWidth / 2, -codeHeight / 2];
if (!this.isLeftDirection) {
arrowPoint = [
codeWidth / 2 + marginX + pauseW + marginX + codeHeight * 0.4,
0,
codeWidth / 2 + marginX + pauseW + marginX,
codeHeight / 2,
codeWidth / 2 + marginX + pauseW + marginX,
-codeHeight / 2,
];
pausePoint = [marginX + codeWidth / 2, -codeHeight / 2];
}
const arrow = this.arrow;
arrow.beginFill(TrainColorEnum.headColor, 1);
arrow.drawPolygon(arrowPoint);
arrow.endFill();
this.pause.beginFill(TrainColorEnum.headColor, 1);
this.pause.drawRect(0, 0, pauseW, codeHeight);
this.pause.endFill();
this.pause.position.set(...pausePoint);
}
stop() {
this.arrow.visible = false;
}
run() {
this.arrow.visible = true;
}
}
export class TrainBody extends Container {
codeRact: Graphics;
codeGraph: VectorText = new VectorText(''); //车号
constructor() {
super();
this.codeRact = new Graphics();
this.addChild(this.codeRact);
this.addChild(this.codeGraph);
this.codeGraph.setVectorFontSize(trainConsts.codeFontSize);
}
clear() {
this.codeRact.clear();
}
getBodyWH(): bodyWH {
const bodyWH = this.codeGraph.getLocalBounds();
return {
width: bodyWH.width + trainConsts.codePadding * 2,
height: bodyWH.height + trainConsts.codePadding * 2,
};
}
doRepaint(datas?: ITrainData): void {
this.clear();
const codeGraph = this.codeGraph;
const codeRact = this.codeRact;
const code = datas?.code;
codeGraph.text = code || '01110111';
codeGraph.setVectorFontSize(trainConsts.codeFontSize);
codeGraph.anchor.set(0.5);
const style = {
fill: TrainColorEnum.codeColor,
padding: 5,
};
codeGraph.style = style;
const { width: codeWidth, height: codeHeight } = this.getBodyWH();
const hasBorder = datas ? datas.hasBorder : true;
if (hasBorder) {
codeRact.visible = true;
codeRact.lineStyle(
this.datas.borderWidth,
new Color(this.datas.borderColor)
trainConsts.borderWidth,
new Color(TrainColorEnum.borderColor)
);
codeRact.beginFill(new Color(this.datas.bodyColor));
codeRact.drawRect(codeX, codeY, codeWidth, codeHeight);
codeRact.beginFill(new Color(TrainColorEnum.bodyColor));
codeRact.drawRect(-codeWidth / 2, -codeHeight / 2, codeWidth, codeHeight);
codeRact.endFill();
} else {
codeRact.visible = false;
}
}
}
export class Train extends JlGraphic {
static Type = 'Train';
headLeft: TrainHead;
headRight: TrainHead;
trainbody: TrainBody;
constructor() {
super(Train.Type);
this.trainbody = new TrainBody();
this.headLeft = new TrainHead('left');
this.headRight = new TrainHead('right');
this.addChild(this.headLeft);
this.addChild(this.headRight);
this.addChild(this.trainbody);
}
get datas(): ITrainData {
return this.getDatas<ITrainData>();
}
doRepaint(): void {
this.trainbody.doRepaint(this.datas);
const bodyWH = this.trainbody.getBodyWH();
this.headLeft.doRepaint(bodyWH);
this.headRight.doRepaint(bodyWH);
// 运行方向控制箭头停止显隐
if (this.datas.trainDirection == 'right') {
this.arrowLeft.visible = false;
this.arrowRight.visible = true;
this.pauseLeft.visible = false;
this.pauseRight.visible = true;
this.headLeft.visible = false;
this.headRight.visible = true;
} else {
this.arrowLeft.visible = true;
this.arrowRight.visible = false;
this.pauseLeft.visible = true;
this.pauseRight.visible = false;
this.headLeft.visible = true;
this.headRight.visible = false;
}
}
stop() {
this.headLeft.stop();
this.headRight.stop();
}
run() {
this.headLeft.run();
this.headRight.run();
}
}
export class TrainTemplate extends JlGraphicTemplate<Train> {
trainDirection: string;
codeFontSize: number;
hasBorder: boolean;
borderWidth: number;
borderColor: string;
headColor: string;
codeColor: string;
bodyColor: string;
constructor() {
super(Train.Type);
this.trainDirection = 'left';
this.codeFontSize = trainConsts.codeFontSize;
this.hasBorder = true;
this.borderWidth = trainConsts.borderWidth;
this.borderColor = TrainColorEnum.borderColor;
this.headColor = TrainColorEnum.headColor;
this.codeColor = TrainColorEnum.codeColor;
this.bodyColor = TrainColorEnum.bodyColor;
}
new(): Train {
return new Train();

View File

@ -1,23 +1,27 @@
import { Color, FederatedPointerEvent, Graphics, Point } from 'pixi.js';
import { Point, FederatedPointerEvent } from 'pixi.js';
import {
GraphicDrawAssistant,
GraphicInteractionPlugin,
JlDrawApp,
JlGraphic,
VectorText,
} from 'src/jl-graphic';
import { ITrainData, Train, TrainTemplate, trainConsts } from './Train';
import {
ITrainData,
Train,
TrainTemplate,
TrainHead,
TrainBody,
} from './Train';
export interface ITrainDrawOptions {
newData: () => ITrainData;
}
export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
point: Point = new Point(0, 0);
arrowLeft: Graphics = new Graphics();
pauseLeft: Graphics = new Graphics();
codeRact: Graphics = new Graphics();
_Train: Train | null = null;
headLeft: TrainHead;
trainbody: TrainBody;
constructor(app: JlDrawApp, createData: () => ITrainData) {
super(
@ -27,94 +31,56 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
'directions_bus_filled',
'列车Train'
);
this.container.addChild(this.arrowLeft);
this.container.addChild(this.pauseLeft);
this.container.addChild(this.codeRact);
this.graphicTemplate.hasBorder = true;
this.headLeft = new TrainHead('left');
this.trainbody = new TrainBody();
this.container.addChild(this.headLeft);
this.container.addChild(this.trainbody);
trainInteraction.init(app);
}
bind(): void {
super.bind();
if (!this._Train) {
this._Train = this.graphicTemplate.new();
this.container.addChild(this._Train);
}
this.trainbody.doRepaint();
const bodyWH = this.trainbody.getBodyWH();
this.headLeft.doRepaint(bodyWH);
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.arrowLeft.clear();
this.pauseLeft.clear();
this.codeRact.clear();
this.headLeft.clear();
this.trainbody.clear();
}
onLeftDown(e: FederatedPointerEvent): void {
const { x, y } = this.toCanvasCoordinates(e.global);
const p = new Point(x, y);
this.point = p;
this.createAndStore(true);
public get Train(): Train {
if (!this._Train) {
throw new Error('列车绘制逻辑异常');
}
return this._Train;
}
redraw(p: Point): void {
const template = this.graphicTemplate;
const codeGraph = new VectorText(''); // 车号
codeGraph.setVectorFontSize(22);
codeGraph.anchor.set(0.5);
codeGraph.text = '01110111';
const style = { padding: 5 };
codeGraph.style = style;
const { width, height } = codeGraph.getLocalBounds();
codeGraph.destroy();
const marginX = trainConsts.marginX;
const pauseW = trainConsts.pauseW;
// 边框
if (template.hasBorder) {
const codeRact = this.codeRact;
codeRact.clear();
codeRact.lineStyle(template.borderWidth, new Color(template.borderColor));
codeRact.beginFill(new Color(template.bodyColor));
codeRact.drawRect(-width / 2, -height / 2, width, height);
codeRact.endFill();
codeRact.position.set(p.x, p.y);
}
// 箭头
const arrowLeft = this.arrowLeft;
arrowLeft.clear();
this.point.set(p.x, p.y);
arrowLeft.beginFill(template.headColor, 1);
arrowLeft.drawPolygon([
-height * 0.4 - marginX - pauseW - marginX - width / 2,
0,
-marginX - pauseW - marginX - width / 2,
height / 2,
-marginX - pauseW - marginX - width / 2,
-height / 2,
]);
arrowLeft.endFill();
arrowLeft.position.set(this.point.x, this.point.y);
// 停止框
const pauseLeft = this.pauseLeft;
pauseLeft.clear();
pauseLeft.beginFill(template.headColor, 1);
pauseLeft.drawRect(0, 0, pauseW, height);
pauseLeft.endFill();
pauseLeft.position.set(
this.point.x - marginX - pauseW - width / 2,
this.point.y - height / 2
);
this.container.position.set(p.x, p.y);
}
onRightClick(): void {
this.createAndStore(true);
}
onLeftDown(e: FederatedPointerEvent): void {
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
this.createAndStore(true);
}
prepareData(data: ITrainData): boolean {
const template = this.graphicTemplate;
data.code = '01110111';
data.codeColor = template.codeColor;
data.codeFontSize = template.codeFontSize;
data.hasBorder = template.hasBorder;
data.trainDirection = template.trainDirection;
data.point = this.point;
data.borderWidth = template.borderWidth;
data.borderColor = template.borderColor;
data.headColor = template.headColor;
data.bodyColor = template.bodyColor;
data.transform = this.container.saveTransform();
return true;
}
}

View File

@ -60,7 +60,7 @@
<q-card style="width: 300px">
<q-card-section>
<div class="text-h6">新建草稿图</div>
<q-form @submit="onCreate" class="q-gutter-md">
<q-form ref="myForm" class="q-gutter-md">
<q-input
outlined
label="名称"
@ -72,13 +72,14 @@
v-model="createType"
:options="typeOptions"
emit-value
map-options
label="类型"
/>
</q-form>
</q-card-section>
<q-card-actions align="right">
<q-btn color="primary" label="创建" type="submit" />
<q-btn color="primary" label="创建" type="submit" @click="onCreate" />
<q-btn label="取消" v-close-popup />
</q-card-actions>
</q-card>
@ -116,7 +117,7 @@
<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue';
import { useQuasar, type QTableColumn } from 'quasar';
import { useQuasar, type QTableColumn, QForm } from 'quasar';
import {
pageQuery,
publishDraft,
@ -210,23 +211,28 @@ async function onRequest(props: any) {
const createFormShow = ref(false);
const draftName = ref('');
async function onCreate() {
operateDisabled.value = true;
try {
await createDraft({
name: draftName.value,
type: createType.value,
});
createFormShow.value = false;
tableRef.value.requestServerInteraction(); //
} catch (error: any) {
$q.notify({
type: 'negative',
message: error.message,
});
} finally {
operateDisabled.value = false;
}
const myForm = ref<QForm | null>(null);
function onCreate() {
myForm.value?.validate().then(async (res) => {
if (res) {
operateDisabled.value = true;
try {
await createDraft({
name: draftName.value,
type: createType.value,
});
createFormShow.value = false;
tableRef.value.requestServerInteraction(); //
} catch (error: any) {
$q.notify({
type: 'negative',
message: error.message,
});
} finally {
operateDisabled.value = false;
}
}
});
}
const publishFormShow = ref(false);

View File

@ -1452,7 +1452,6 @@ export namespace graphicData {
common?: CommonInfo;
code?: string;
hasCircle?: boolean;
circlePoint?: Point;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
@ -1466,9 +1465,6 @@ export namespace graphicData {
if ("hasCircle" in data && data.hasCircle != undefined) {
this.hasCircle = data.hasCircle;
}
if ("circlePoint" in data && data.circlePoint != undefined) {
this.circlePoint = data.circlePoint;
}
}
}
get common() {
@ -1492,20 +1488,10 @@ export namespace graphicData {
set hasCircle(value: boolean) {
pb_1.Message.setField(this, 3, value);
}
get circlePoint() {
return pb_1.Message.getWrapperField(this, Point, 4) as Point;
}
set circlePoint(value: Point) {
pb_1.Message.setWrapperField(this, 4, value);
}
get has_circlePoint() {
return pb_1.Message.getField(this, 4) != null;
}
static fromObject(data: {
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
code?: string;
hasCircle?: boolean;
circlePoint?: ReturnType<typeof Point.prototype.toObject>;
}): Station {
const message = new Station({});
if (data.common != null) {
@ -1517,9 +1503,6 @@ export namespace graphicData {
if (data.hasCircle != null) {
message.hasCircle = data.hasCircle;
}
if (data.circlePoint != null) {
message.circlePoint = Point.fromObject(data.circlePoint);
}
return message;
}
toObject() {
@ -1527,7 +1510,6 @@ export namespace graphicData {
common?: ReturnType<typeof CommonInfo.prototype.toObject>;
code?: string;
hasCircle?: boolean;
circlePoint?: ReturnType<typeof Point.prototype.toObject>;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
@ -1538,9 +1520,6 @@ export namespace graphicData {
if (this.hasCircle != null) {
data.hasCircle = this.hasCircle;
}
if (this.circlePoint != null) {
data.circlePoint = this.circlePoint.toObject();
}
return data;
}
serialize(): Uint8Array;
@ -1553,8 +1532,6 @@ export namespace graphicData {
writer.writeString(2, this.code);
if (this.hasCircle != false)
writer.writeBool(3, this.hasCircle);
if (this.has_circlePoint)
writer.writeMessage(4, this.circlePoint, () => this.circlePoint.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
@ -1573,9 +1550,6 @@ export namespace graphicData {
case 3:
message.hasCircle = reader.readBool();
break;
case 4:
reader.readMessage(message.circlePoint, () => message.circlePoint = Point.deserialize(reader));
break;
default: reader.skipField();
}
}

@ -1 +1 @@
Subproject commit e7511d23961cd796ca732663c50ad6e058a06d0e
Subproject commit 89c9f023cff957ecb414d09252b306ef20b9e908