From 64ab0b7d00a32429df916182e39d1fededf9cddc Mon Sep 17 00:00:00 2001
From: dong <58670809@qq.com>
Date: Mon, 5 Jun 2023 14:24:25 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=88=97=E8=BD=A6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/components/draw-app/DrawProperties.vue | 8 +
.../draw-app/properties/TrainProperty.vue | 198 +++++++++++
.../draw-app/templates/TrainTemplate.vue | 69 ++++
.../protos/draw_data_storage.proto | 15 +
src/examples/app/graphics/TrainInteraction.ts | 92 +++++
src/examples/app/index.ts | 20 ++
src/examples/app/protos/draw_data_storage.ts | 328 +++++++++++++++++-
src/graphics/train/Train.ts | 185 ++++++++++
src/graphics/train/TrainDrawAssistant.ts | 141 ++++++++
9 files changed, 1055 insertions(+), 1 deletion(-)
create mode 100644 src/components/draw-app/properties/TrainProperty.vue
create mode 100644 src/components/draw-app/templates/TrainTemplate.vue
create mode 100644 src/examples/app/graphics/TrainInteraction.ts
create mode 100644 src/graphics/train/Train.ts
create mode 100644 src/graphics/train/TrainDrawAssistant.ts
diff --git a/src/components/draw-app/DrawProperties.vue b/src/components/draw-app/DrawProperties.vue
index 7fe95d0..df4f5f9 100644
--- a/src/components/draw-app/DrawProperties.vue
+++ b/src/components/draw-app/DrawProperties.vue
@@ -16,6 +16,9 @@
+
+
+
@@ -42,6 +45,9 @@
+
@@ -59,10 +65,12 @@ import CanvasProperty from './properties/CanvasProperty.vue';
import LinkProperty from './properties/LinkProperty.vue';
import PlatformProperty from './properties/PlatformProperty.vue';
import StationProperty from './properties/StationProperty.vue';
+import TrainProperty from './properties/TrainProperty.vue';
import IscsFanProperty from './properties/IscsFanProperty.vue';
import { Link } from 'src/graphics/link/Link';
import { Platform } from 'src/graphics/platform/Platform';
import { Station } from 'src/graphics/station/Station';
+import { Train } from 'src/graphics/train/Train';
import { useDrawStore } from 'src/stores/draw-store';
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
diff --git a/src/components/draw-app/properties/TrainProperty.vue b/src/components/draw-app/properties/TrainProperty.vue
new file mode 100644
index 0000000..9e6360c
--- /dev/null
+++ b/src/components/draw-app/properties/TrainProperty.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+ {
+ trainModel.codeColor = val;
+ onUpdate();
+ }
+ "
+ />
+
+
+
+
+
+
+
+
+ {
+ trainModel.headColor = val;
+ onUpdate();
+ }
+ "
+ />
+
+
+
+
+
+
+
+
+
+
+
+ {
+ trainModel.borderColor = val;
+ onUpdate();
+ }
+ "
+ />
+
+
+
+
+
+
+
+
+ {
+ trainModel.bodyColor = val;
+ onUpdate();
+ }
+ "
+ />
+
+
+
+
+
+
+
+
+
diff --git a/src/components/draw-app/templates/TrainTemplate.vue b/src/components/draw-app/templates/TrainTemplate.vue
new file mode 100644
index 0000000..84c3cd2
--- /dev/null
+++ b/src/components/draw-app/templates/TrainTemplate.vue
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+ {
+ template.headColor = val;
+ onUpdate();
+ }
+ "
+ />
+
+
+
+
+
+
+
+
diff --git a/src/examples/app/app_message/protos/draw_data_storage.proto b/src/examples/app/app_message/protos/draw_data_storage.proto
index 6b9cc35..e129790 100644
--- a/src/examples/app/app_message/protos/draw_data_storage.proto
+++ b/src/examples/app/app_message/protos/draw_data_storage.proto
@@ -9,6 +9,7 @@ message RtssGraphicStorage {
repeated Platform Platforms = 4;
repeated Station stations = 5;
repeated Rect Rects = 6;
+ repeated Train train = 7;
}
message Canvas {
@@ -100,6 +101,20 @@ message Station {
}
+message Train {
+ CommonInfo common = 1;
+ string code = 2;
+ string codeColor = 3; // 车号颜色
+ int32 codeFontSize = 4; // 车号字体大小
+ Point point = 5; // 位置坐标
+ string trainDirection = 6; // 行驶方向
+ bool hasBorder = 7; // 是否有边框
+ int32 borderWidth = 8; // 边框线宽
+ string borderColor = 9; // 边框颜色
+ string headColor = 10; // 箭头颜色
+ string bodyColor = 11; // 背景色
+}
+
message IscsFan {
CommonInfo common = 1;
string code = 2;
diff --git a/src/examples/app/graphics/TrainInteraction.ts b/src/examples/app/graphics/TrainInteraction.ts
new file mode 100644
index 0000000..db770cc
--- /dev/null
+++ b/src/examples/app/graphics/TrainInteraction.ts
@@ -0,0 +1,92 @@
+import * as pb_1 from 'google-protobuf';
+import { IPointData } from 'pixi.js';
+import { ITrainData } from 'src/graphics/train/Train';
+import { graphicData } from '../protos/draw_data_storage';
+import { GraphicDataBase } from './GraphicDataBase';
+
+export class TrainData extends GraphicDataBase implements ITrainData {
+ constructor(data?: graphicData.Train) {
+ let train;
+ if (!data) {
+ train = new graphicData.Train({
+ common: GraphicDataBase.defaultCommonInfo(),
+ });
+ } else {
+ train = data;
+ }
+ super(train);
+ }
+
+ public get data(): graphicData.Train {
+ return this.getData();
+ }
+ get code(): string {
+ return this.data.code;
+ }
+ 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;
+ }
+ set trainDirection(v: string) {
+ this.data.trainDirection = v;
+ }
+ get hasBorder(): boolean {
+ return this.data.hasBorder;
+ }
+ 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());
+ }
+ copyFrom(data: TrainData): void {
+ pb_1.Message.copyInto(data.data, this.data);
+ }
+ eq(other: TrainData): boolean {
+ return pb_1.Message.equals(this.data, other.data);
+ }
+}
diff --git a/src/examples/app/index.ts b/src/examples/app/index.ts
index da432d6..148f480 100644
--- a/src/examples/app/index.ts
+++ b/src/examples/app/index.ts
@@ -9,7 +9,9 @@ import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
import { Platform } from 'src/graphics/platform/Platform';
import { PlatformDraw } from 'src/graphics/platform/PlatformDrawAssistant';
import { Station } from 'src/graphics/station/Station';
+import { Train } from 'src/graphics/train/Train';
import { StationDraw } from 'src/graphics/station/StationDrawAssistant';
+import { TrainDraw } from 'src/graphics/train/TrainDrawAssistant';
import {
CombinationKey,
GraphicApp,
@@ -25,6 +27,7 @@ import { LinkData } from './graphics/LinkInteraction';
import { RectData } from './graphics/RectInteraction';
import { PlatformData } from './graphics/PlatformInteraction';
import { StationData } from './graphics/StationInteraction';
+import { TrainData } from './graphics/TrainInteraction';
import { graphicData } from './protos/draw_data_storage';
export function fromStoragePoint(p: graphicData.Point): Point {
@@ -112,6 +115,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
new StationDraw(app, () => {
return new StationData();
}),
+ new TrainDraw(app, () => {
+ return new TrainData();
+ }),
],
});
@@ -173,6 +179,14 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
},
})
);
+ app.addKeyboardListener(
+ new KeyListener({
+ value: 'KeyT',
+ onPress: () => {
+ app.interactionPlugin(Train.Type).resume();
+ },
+ })
+ );
app.addKeyboardListener(
new KeyListener({
value: '1',
@@ -223,6 +237,9 @@ export function saveDrawDatas(app: JlDrawApp) {
} else if (Station.Type === g.type) {
const stationData = (g as Station).saveData();
storage.stations.push((stationData as StationData).data);
+ } else if (Train.Type === g.type) {
+ const trainData = (g as Train).saveData();
+ storage.train.push((trainData as TrainData).data);
}
});
const base64 = fromUint8Array(storage.serialize());
@@ -256,6 +273,9 @@ export function loadDrawDatas(app: GraphicApp) {
storage.stations.forEach((station) => {
datas.push(new StationData(station));
});
+ storage.train.forEach((train) => {
+ datas.push(new TrainData(train));
+ });
app.loadGraphic(datas);
} else {
app.loadGraphic([]);
diff --git a/src/examples/app/protos/draw_data_storage.ts b/src/examples/app/protos/draw_data_storage.ts
index 7f01476..e600536 100644
--- a/src/examples/app/protos/draw_data_storage.ts
+++ b/src/examples/app/protos/draw_data_storage.ts
@@ -14,9 +14,10 @@ export namespace graphicData {
Platforms?: Platform[];
stations?: Station[];
Rects?: Rect[];
+ train?: Train[];
}) {
super();
- pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6], this.#one_of_decls);
+ pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [2, 3, 4, 5, 6, 7], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("canvas" in data && data.canvas != undefined) {
this.canvas = data.canvas;
@@ -36,6 +37,9 @@ export namespace graphicData {
if ("Rects" in data && data.Rects != undefined) {
this.Rects = data.Rects;
}
+ if ("train" in data && data.train != undefined) {
+ this.train = data.train;
+ }
}
}
get canvas() {
@@ -77,6 +81,12 @@ export namespace graphicData {
set Rects(value: Rect[]) {
pb_1.Message.setRepeatedWrapperField(this, 6, value);
}
+ get train() {
+ return pb_1.Message.getRepeatedWrapperField(this, Train, 7) as Train[];
+ }
+ set train(value: Train[]) {
+ pb_1.Message.setRepeatedWrapperField(this, 7, value);
+ }
static fromObject(data: {
canvas?: ReturnType;
links?: ReturnType[];
@@ -84,6 +94,7 @@ export namespace graphicData {
Platforms?: ReturnType[];
stations?: ReturnType[];
Rects?: ReturnType[];
+ train?: ReturnType[];
}): RtssGraphicStorage {
const message = new RtssGraphicStorage({});
if (data.canvas != null) {
@@ -104,6 +115,9 @@ export namespace graphicData {
if (data.Rects != null) {
message.Rects = data.Rects.map(item => Rect.fromObject(item));
}
+ if (data.train != null) {
+ message.train = data.train.map(item => Train.fromObject(item));
+ }
return message;
}
toObject() {
@@ -114,6 +128,7 @@ export namespace graphicData {
Platforms?: ReturnType[];
stations?: ReturnType[];
Rects?: ReturnType[];
+ train?: ReturnType[];
} = {};
if (this.canvas != null) {
data.canvas = this.canvas.toObject();
@@ -133,6 +148,9 @@ export namespace graphicData {
if (this.Rects != null) {
data.Rects = this.Rects.map((item: Rect) => item.toObject());
}
+ if (this.train != null) {
+ data.train = this.train.map((item: Train) => item.toObject());
+ }
return data;
}
serialize(): Uint8Array;
@@ -151,6 +169,8 @@ export namespace graphicData {
writer.writeRepeatedMessage(5, this.stations, (item: Station) => item.serialize(writer));
if (this.Rects.length)
writer.writeRepeatedMessage(6, this.Rects, (item: Rect) => item.serialize(writer));
+ if (this.train.length)
+ writer.writeRepeatedMessage(7, this.train, (item: Train) => item.serialize(writer));
if (!w)
return writer.getResultBuffer();
}
@@ -178,6 +198,9 @@ export namespace graphicData {
case 6:
reader.readMessage(message.Rects, () => pb_1.Message.addToRepeatedWrapperField(message, 6, Rect.deserialize(reader), Rect));
break;
+ case 7:
+ reader.readMessage(message.train, () => pb_1.Message.addToRepeatedWrapperField(message, 7, Train.deserialize(reader), Train));
+ break;
default: reader.skipField();
}
}
@@ -1706,6 +1729,309 @@ export namespace graphicData {
return Station.deserialize(bytes);
}
}
+ export class Train extends pb_1.Message {
+ #one_of_decls: number[][] = [];
+ constructor(data?: any[] | {
+ common?: CommonInfo;
+ code?: string;
+ codeColor?: string;
+ codeFontSize?: number;
+ point?: Point;
+ trainDirection?: string;
+ hasBorder?: boolean;
+ borderWidth?: number;
+ borderColor?: string;
+ headColor?: string;
+ bodyColor?: string;
+ }) {
+ super();
+ pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
+ if (!Array.isArray(data) && typeof data == "object") {
+ if ("common" in data && data.common != undefined) {
+ this.common = data.common;
+ }
+ if ("code" in data && data.code != undefined) {
+ this.code = data.code;
+ }
+ if ("codeColor" in data && data.codeColor != undefined) {
+ this.codeColor = data.codeColor;
+ }
+ if ("codeFontSize" in data && data.codeFontSize != undefined) {
+ this.codeFontSize = data.codeFontSize;
+ }
+ if ("point" in data && data.point != undefined) {
+ this.point = data.point;
+ }
+ if ("trainDirection" in data && data.trainDirection != undefined) {
+ this.trainDirection = data.trainDirection;
+ }
+ if ("hasBorder" in data && data.hasBorder != undefined) {
+ this.hasBorder = data.hasBorder;
+ }
+ if ("borderWidth" in data && data.borderWidth != undefined) {
+ this.borderWidth = data.borderWidth;
+ }
+ if ("borderColor" in data && data.borderColor != undefined) {
+ this.borderColor = data.borderColor;
+ }
+ if ("headColor" in data && data.headColor != undefined) {
+ this.headColor = data.headColor;
+ }
+ if ("bodyColor" in data && data.bodyColor != undefined) {
+ this.bodyColor = data.bodyColor;
+ }
+ }
+ }
+ get common() {
+ return pb_1.Message.getWrapperField(this, CommonInfo, 1) as CommonInfo;
+ }
+ set common(value: CommonInfo) {
+ pb_1.Message.setWrapperField(this, 1, value);
+ }
+ get has_common() {
+ return pb_1.Message.getField(this, 1) != null;
+ }
+ get code() {
+ return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
+ }
+ set code(value: string) {
+ pb_1.Message.setField(this, 2, value);
+ }
+ get codeColor() {
+ return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
+ }
+ set codeColor(value: string) {
+ pb_1.Message.setField(this, 3, value);
+ }
+ get codeFontSize() {
+ return pb_1.Message.getFieldWithDefault(this, 4, 0) as number;
+ }
+ set codeFontSize(value: number) {
+ pb_1.Message.setField(this, 4, value);
+ }
+ get point() {
+ return pb_1.Message.getWrapperField(this, Point, 5) as Point;
+ }
+ set point(value: Point) {
+ pb_1.Message.setWrapperField(this, 5, value);
+ }
+ get has_point() {
+ return pb_1.Message.getField(this, 5) != null;
+ }
+ get trainDirection() {
+ return pb_1.Message.getFieldWithDefault(this, 6, "") as string;
+ }
+ set trainDirection(value: string) {
+ pb_1.Message.setField(this, 6, value);
+ }
+ get hasBorder() {
+ return pb_1.Message.getFieldWithDefault(this, 7, false) as boolean;
+ }
+ set hasBorder(value: boolean) {
+ pb_1.Message.setField(this, 7, value);
+ }
+ get borderWidth() {
+ return pb_1.Message.getFieldWithDefault(this, 8, 0) as number;
+ }
+ set borderWidth(value: number) {
+ pb_1.Message.setField(this, 8, value);
+ }
+ get borderColor() {
+ return pb_1.Message.getFieldWithDefault(this, 9, "") as string;
+ }
+ set borderColor(value: string) {
+ pb_1.Message.setField(this, 9, value);
+ }
+ get headColor() {
+ return pb_1.Message.getFieldWithDefault(this, 10, "") as string;
+ }
+ set headColor(value: string) {
+ pb_1.Message.setField(this, 10, value);
+ }
+ get bodyColor() {
+ return pb_1.Message.getFieldWithDefault(this, 11, "") as string;
+ }
+ set bodyColor(value: string) {
+ pb_1.Message.setField(this, 11, value);
+ }
+ static fromObject(data: {
+ common?: ReturnType;
+ code?: string;
+ codeColor?: string;
+ codeFontSize?: number;
+ point?: ReturnType;
+ trainDirection?: string;
+ hasBorder?: boolean;
+ borderWidth?: number;
+ borderColor?: string;
+ headColor?: string;
+ bodyColor?: string;
+ }): Train {
+ const message = new Train({});
+ if (data.common != null) {
+ message.common = CommonInfo.fromObject(data.common);
+ }
+ if (data.code != null) {
+ message.code = data.code;
+ }
+ if (data.codeColor != null) {
+ message.codeColor = data.codeColor;
+ }
+ if (data.codeFontSize != null) {
+ message.codeFontSize = data.codeFontSize;
+ }
+ if (data.point != null) {
+ message.point = Point.fromObject(data.point);
+ }
+ if (data.trainDirection != null) {
+ message.trainDirection = data.trainDirection;
+ }
+ if (data.hasBorder != null) {
+ message.hasBorder = data.hasBorder;
+ }
+ if (data.borderWidth != null) {
+ message.borderWidth = data.borderWidth;
+ }
+ if (data.borderColor != null) {
+ message.borderColor = data.borderColor;
+ }
+ if (data.headColor != null) {
+ message.headColor = data.headColor;
+ }
+ if (data.bodyColor != null) {
+ message.bodyColor = data.bodyColor;
+ }
+ return message;
+ }
+ toObject() {
+ const data: {
+ common?: ReturnType;
+ code?: string;
+ codeColor?: string;
+ codeFontSize?: number;
+ point?: ReturnType;
+ trainDirection?: string;
+ hasBorder?: boolean;
+ borderWidth?: number;
+ borderColor?: string;
+ headColor?: string;
+ bodyColor?: string;
+ } = {};
+ if (this.common != null) {
+ data.common = this.common.toObject();
+ }
+ if (this.code != null) {
+ data.code = this.code;
+ }
+ if (this.codeColor != null) {
+ data.codeColor = this.codeColor;
+ }
+ if (this.codeFontSize != null) {
+ data.codeFontSize = this.codeFontSize;
+ }
+ if (this.point != null) {
+ data.point = this.point.toObject();
+ }
+ if (this.trainDirection != null) {
+ data.trainDirection = this.trainDirection;
+ }
+ if (this.hasBorder != null) {
+ data.hasBorder = this.hasBorder;
+ }
+ if (this.borderWidth != null) {
+ data.borderWidth = this.borderWidth;
+ }
+ if (this.borderColor != null) {
+ data.borderColor = this.borderColor;
+ }
+ if (this.headColor != null) {
+ data.headColor = this.headColor;
+ }
+ if (this.bodyColor != null) {
+ data.bodyColor = this.bodyColor;
+ }
+ return data;
+ }
+ serialize(): Uint8Array;
+ serialize(w: pb_1.BinaryWriter): void;
+ serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
+ const writer = w || new pb_1.BinaryWriter();
+ if (this.has_common)
+ writer.writeMessage(1, this.common, () => this.common.serialize(writer));
+ if (this.code.length)
+ writer.writeString(2, this.code);
+ if (this.codeColor.length)
+ writer.writeString(3, this.codeColor);
+ if (this.codeFontSize != 0)
+ writer.writeInt32(4, this.codeFontSize);
+ if (this.has_point)
+ writer.writeMessage(5, this.point, () => this.point.serialize(writer));
+ if (this.trainDirection.length)
+ writer.writeString(6, this.trainDirection);
+ if (this.hasBorder != false)
+ writer.writeBool(7, this.hasBorder);
+ if (this.borderWidth != 0)
+ writer.writeInt32(8, this.borderWidth);
+ if (this.borderColor.length)
+ writer.writeString(9, this.borderColor);
+ if (this.headColor.length)
+ writer.writeString(10, this.headColor);
+ if (this.bodyColor.length)
+ writer.writeString(11, this.bodyColor);
+ if (!w)
+ return writer.getResultBuffer();
+ }
+ static deserialize(bytes: Uint8Array | pb_1.BinaryReader): Train {
+ const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new Train();
+ while (reader.nextField()) {
+ if (reader.isEndGroup())
+ break;
+ switch (reader.getFieldNumber()) {
+ case 1:
+ reader.readMessage(message.common, () => message.common = CommonInfo.deserialize(reader));
+ break;
+ case 2:
+ message.code = reader.readString();
+ break;
+ case 3:
+ message.codeColor = reader.readString();
+ break;
+ case 4:
+ message.codeFontSize = reader.readInt32();
+ break;
+ case 5:
+ reader.readMessage(message.point, () => message.point = Point.deserialize(reader));
+ break;
+ case 6:
+ message.trainDirection = reader.readString();
+ break;
+ case 7:
+ message.hasBorder = reader.readBool();
+ break;
+ case 8:
+ message.borderWidth = reader.readInt32();
+ break;
+ case 9:
+ message.borderColor = reader.readString();
+ break;
+ case 10:
+ message.headColor = reader.readString();
+ break;
+ case 11:
+ message.bodyColor = reader.readString();
+ break;
+ default: reader.skipField();
+ }
+ }
+ return message;
+ }
+ serializeBinary(): Uint8Array {
+ return this.serialize();
+ }
+ static deserializeBinary(bytes: Uint8Array): Train {
+ return Train.deserialize(bytes);
+ }
+ }
export class IscsFan extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
diff --git a/src/graphics/train/Train.ts b/src/graphics/train/Train.ts
new file mode 100644
index 0000000..217ac3c
--- /dev/null
+++ b/src/graphics/train/Train.ts
@@ -0,0 +1,185 @@
+import { Color, Graphics, IPointData } from 'pixi.js';
+import {
+ GraphicData,
+ JlGraphic,
+ JlGraphicTemplate,
+ VectorText,
+} from 'src/jlgraphic';
+
+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;
+}
+
+// 列车颜色
+export enum TrainColorEnum {
+ headColor = '0x00FF00', // 箭头颜色
+ bodyColor = '0xA388B1', // 背景色
+ codeColor = '0xffffff', // 车号颜色
+ borderColor = '0xA3E198', // 边框的颜色
+}
+
+export const trainConsts = {
+ 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);
+ }
+
+ get datas(): ITrainData {
+ return this.getDatas();
+ }
+ 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();
+ const marginX = trainConsts.marginX;
+ const pauseW = trainConsts.pauseW;
+ const arrowLeft = this.arrowLeft;
+ arrowLeft.beginFill(this.datas.headColor, 1);
+ arrowLeft.drawPolygon([
+ -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) {
+ codeRact.visible = true;
+ codeRact.lineStyle(
+ this.datas.borderWidth,
+ new Color(this.datas.borderColor)
+ );
+ codeRact.beginFill(new Color(this.datas.bodyColor));
+ codeRact.drawRect(codeX, codeY, codeWidth, codeHeight);
+ codeRact.endFill();
+ } else {
+ codeRact.visible = false;
+ }
+ // 运行方向控制箭头停止显隐
+ if (this.datas.trainDirection == 'right') {
+ this.arrowLeft.visible = false;
+ this.arrowRight.visible = true;
+ this.pauseLeft.visible = false;
+ this.pauseRight.visible = true;
+ } else {
+ this.arrowLeft.visible = true;
+ this.arrowRight.visible = false;
+ this.pauseLeft.visible = true;
+ this.pauseRight.visible = false;
+ }
+ }
+}
+
+export class TrainTemplate extends JlGraphicTemplate {
+ 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();
+ }
+}
diff --git a/src/graphics/train/TrainDrawAssistant.ts b/src/graphics/train/TrainDrawAssistant.ts
new file mode 100644
index 0000000..bb4d479
--- /dev/null
+++ b/src/graphics/train/TrainDrawAssistant.ts
@@ -0,0 +1,141 @@
+import { Color, FederatedPointerEvent, Graphics, Point } from 'pixi.js';
+import {
+ GraphicDrawAssistant,
+ GraphicInteractionPlugin,
+ JlDrawApp,
+ JlGraphic,
+ VectorText,
+} from 'src/jlgraphic';
+
+import { ITrainData, Train, TrainTemplate, trainConsts } from './Train';
+
+export interface ITrainDrawOptions {
+ newData: () => ITrainData;
+}
+
+export class TrainDraw extends GraphicDrawAssistant {
+ point: Point = new Point(0, 0);
+ arrowLeft: Graphics = new Graphics();
+ pauseLeft: Graphics = new Graphics();
+ codeRact: Graphics = new Graphics();
+
+ constructor(app: JlDrawApp, createData: () => ITrainData) {
+ super(app, new TrainTemplate(), createData, Train.Type, '列车Train');
+ this.container.addChild(this.arrowLeft);
+ this.container.addChild(this.pauseLeft);
+ this.container.addChild(this.codeRact);
+ this.graphicTemplate.hasBorder = true;
+ trainInteraction.init(app);
+ }
+
+ bind(): void {
+ super.bind();
+ }
+ unbind(): void {
+ super.unbind();
+ }
+
+ clearCache(): void {
+ this.arrowLeft.clear();
+ this.pauseLeft.clear();
+ this.codeRact.clear();
+ }
+ onRightClick(): void {
+ this.createAndStore(true);
+ }
+ onLeftDown(e: FederatedPointerEvent): void {
+ const { x, y } = this.toCanvasCoordinates(e.global);
+ const p = new Point(x, y);
+ this.point = p;
+ this.createAndStore(true);
+ }
+
+ 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
+ );
+ }
+ 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;
+ return true;
+ }
+}
+
+export class trainInteraction extends GraphicInteractionPlugin {
+ static Name = 'train_transform';
+ constructor(app: JlDrawApp) {
+ super(trainInteraction.Name, app);
+ }
+ static init(app: JlDrawApp) {
+ return new trainInteraction(app);
+ }
+ filter(...grahpics: JlGraphic[]): Train[] | undefined {
+ return grahpics.filter((g) => g.type === Train.Type).map((g) => g as Train);
+ }
+ bind(g: Train): void {
+ g.eventMode = 'static';
+ g.cursor = 'pointer';
+ g.scalable = true;
+ g.rotatable = true;
+ }
+ unbind(g: Train): void {
+ g.eventMode = 'none';
+ g.scalable = false;
+ g.rotatable = false;
+ }
+}