Merge branch 'master' of https://git.code.tencent.com/xian-ncc-da/xian-ncc-da-client
This commit is contained in:
commit
8be7941e5f
@ -51,6 +51,9 @@
|
||||
<station-property
|
||||
v-if="drawStore.selectedGraphicType === Station.Type"
|
||||
></station-property>
|
||||
<station-line-property
|
||||
v-if="drawStore.selectedGraphicType === StationLine.Type"
|
||||
></station-line-property>
|
||||
<train-property
|
||||
v-if="drawStore.selectedGraphicType === Train.Type"
|
||||
></train-property>
|
||||
@ -83,6 +86,7 @@ import LinkProperty from './properties/LinkProperty.vue';
|
||||
import RectProperty from './properties/RectProperty.vue';
|
||||
import PlatformProperty from './properties/PlatformProperty.vue';
|
||||
import StationProperty from './properties/StationProperty.vue';
|
||||
import StationLineProperty from './properties/StationLineProperty.vue';
|
||||
import TrainProperty from './properties/TrainProperty.vue';
|
||||
import IscsFanProperty from './properties/IscsFanProperty.vue';
|
||||
import SignalProperty from './properties/SignalProperty.vue';
|
||||
@ -92,6 +96,7 @@ import { Link } from 'src/graphics/link/Link';
|
||||
import { Rect } from 'src/graphics/rect/Rect';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { StationLine } from 'src/graphics/stationLine/StationLine';
|
||||
import { Train } from 'src/graphics/train/Train';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
|
||||
|
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input outlined readonly v-model="stationModel.id" label="id" hint="" />
|
||||
<q-input outlined readonly v-model="rectModel.id" label="id" hint="" />
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="stationModel.lineWidth"
|
||||
v-model.number="rectModel.lineWidth"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="线宽"
|
||||
@ -13,7 +13,7 @@
|
||||
|
||||
<q-input
|
||||
outlined
|
||||
v-model="stationModel.lineColor"
|
||||
v-model="rectModel.lineColor"
|
||||
@blur="onUpdate"
|
||||
label="线色"
|
||||
lazy-rules
|
||||
@ -23,10 +23,10 @@
|
||||
<q-icon name="colorize" class="cursor-pointer">
|
||||
<q-popup-proxy cover transition-show="scale" transition-hide="scale">
|
||||
<q-color
|
||||
v-model="stationModel.lineColor"
|
||||
v-model="rectModel.lineColor"
|
||||
@change="
|
||||
(val) => {
|
||||
stationModel.lineColor = val;
|
||||
rectModel.lineColor = val;
|
||||
onUpdate();
|
||||
}
|
||||
"
|
||||
@ -35,6 +35,33 @@
|
||||
</q-icon>
|
||||
</template>
|
||||
</q-input>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="rectModel.width"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="宽度"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val > 0) || '宽度必须大于0']"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="rectModel.height"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="高度"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val > 0) || '宽度必须大于0']"
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
v-model.number="rectModel.radius"
|
||||
type="number"
|
||||
@blur="onUpdate"
|
||||
label="圆角半径"
|
||||
lazy-rules
|
||||
:rules="[(val) => (val && val > 0) || '圆角半径必须大于0']"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
@ -45,30 +72,29 @@ import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const stationModel = reactive(new RectData());
|
||||
const rectModel = reactive(new RectData());
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == Rect.Type) {
|
||||
stationModel.copyFrom(val.saveData() as RectData);
|
||||
rectModel.copyFrom(val.saveData() as RectData);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const station = drawStore.selectedGraphic as Rect;
|
||||
|
||||
if (station) {
|
||||
stationModel.copyFrom(station.saveData());
|
||||
const Rect = drawStore.selectedGraphic as Rect;
|
||||
if (Rect) {
|
||||
rectModel.copyFrom(Rect.saveData());
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
const station = drawStore.selectedGraphic as Rect;
|
||||
if (station) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(station, stationModel);
|
||||
const Rect = drawStore.selectedGraphic as Rect;
|
||||
if (Rect) {
|
||||
drawStore.getDrawApp().updateGraphicAndRecord(Rect, rectModel);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
80
src/components/draw-app/properties/StationLineProperty.vue
Normal file
80
src/components/draw-app/properties/StationLineProperty.vue
Normal file
@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<q-form>
|
||||
<q-input
|
||||
outlined
|
||||
readonly
|
||||
v-model="stationLineModel.id"
|
||||
label="id"
|
||||
hint=""
|
||||
/>
|
||||
<q-input
|
||||
outlined
|
||||
label="车站名称"
|
||||
@blur="onUpdate"
|
||||
v-model="stationLineModel.code"
|
||||
lazy-rules
|
||||
/>
|
||||
<q-select
|
||||
outlined
|
||||
@blur="onUpdate"
|
||||
v-model="hasTransfer"
|
||||
:options="optionsCircle"
|
||||
label="是否有换乘"
|
||||
/>
|
||||
</q-form>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { StationLineData } from 'src/drawApp/graphics/StationLineInteraction';
|
||||
import { StationLine } from 'src/graphics/stationLine/StationLine';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { onMounted, reactive, ref, watch } from 'vue';
|
||||
|
||||
const drawStore = useDrawStore();
|
||||
const stationLineModel = reactive(new StationLineData());
|
||||
const hasTransfer = ref('是');
|
||||
const optionsCircle = ['是', '否'];
|
||||
enum showSelect {
|
||||
是 = 'true',
|
||||
否 = 'false',
|
||||
}
|
||||
enum showSelectData {
|
||||
true = '是',
|
||||
false = '否',
|
||||
}
|
||||
|
||||
drawStore.$subscribe;
|
||||
watch(
|
||||
() => drawStore.selectedGraphic,
|
||||
(val) => {
|
||||
if (val && val.type == StationLine.Type) {
|
||||
stationLineModel.copyFrom(val.saveData() as StationLineData);
|
||||
hasTransfer.value = (showSelectData as never)[
|
||||
stationLineModel.hasTransfer + ''
|
||||
];
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
onMounted(() => {
|
||||
const stationLine = drawStore.selectedGraphic as StationLine;
|
||||
if (stationLine) {
|
||||
stationLineModel.copyFrom(stationLine.saveData());
|
||||
hasTransfer.value = (showSelectData as never)[
|
||||
stationLineModel.hasTransfer + ''
|
||||
];
|
||||
}
|
||||
});
|
||||
|
||||
function onUpdate() {
|
||||
stationLineModel.hasTransfer = JSON.parse(
|
||||
(showSelect as never)[hasTransfer.value]
|
||||
);
|
||||
const stationLine = drawStore.selectedGraphic as StationLine;
|
||||
if (stationLine) {
|
||||
drawStore
|
||||
.getDrawApp()
|
||||
.updateGraphicAndRecord(stationLine, stationLineModel);
|
||||
}
|
||||
}
|
||||
</script>
|
@ -7,3 +7,7 @@ export function saveJwtToken(token: string) {
|
||||
export function getJwtToken(): string | null {
|
||||
return sessionStorage.getItem(JwtTokenKey);
|
||||
}
|
||||
|
||||
export function clearJwtToken(): void {
|
||||
sessionStorage.removeItem(JwtTokenKey);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
function getHost(): string {
|
||||
// return '192.168.3.7:9081';
|
||||
// return '192.168.3.47:9081';
|
||||
return '192.168.3.233:9081';
|
||||
}
|
||||
|
||||
|
@ -57,13 +57,11 @@ export class RectData extends GraphicDataBase implements IRectData {
|
||||
set height(v: number) {
|
||||
this.data.height = v;
|
||||
}
|
||||
get points(): IPointData[] {
|
||||
return this.data.points;
|
||||
get radius(): number {
|
||||
return this.data.radius;
|
||||
}
|
||||
set points(points: IPointData[]) {
|
||||
this.data.points = points.map(
|
||||
(p) => new graphicData.Point({ x: p.x, y: p.y })
|
||||
);
|
||||
set radius(v: number) {
|
||||
this.data.radius = v;
|
||||
}
|
||||
clone(): RectData {
|
||||
return new RectData(this.data.cloneMessage());
|
||||
|
45
src/drawApp/graphics/SectionInteraction.ts
Normal file
45
src/drawApp/graphics/SectionInteraction.ts
Normal file
@ -0,0 +1,45 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
import { ISectionData } from 'src/graphics/section/Section';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { IPointData } from 'pixi.js';
|
||||
|
||||
export class SectionData extends GraphicDataBase implements ISectionData {
|
||||
constructor(data?: graphicData.Section) {
|
||||
let section;
|
||||
if (!data) {
|
||||
section = new graphicData.Section({
|
||||
common: GraphicDataBase.defaultCommonInfo(),
|
||||
});
|
||||
} else {
|
||||
section = data;
|
||||
}
|
||||
super(section);
|
||||
}
|
||||
public get data(): graphicData.Section {
|
||||
return this.getData<graphicData.Section>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get points(): IPointData[] {
|
||||
return this.data.points;
|
||||
}
|
||||
set points(points: IPointData[]) {
|
||||
this.data.points = points.map(
|
||||
(p) => new graphicData.Point({ x: p.x, y: p.y })
|
||||
);
|
||||
}
|
||||
clone(): SectionData {
|
||||
return new SectionData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: SectionData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: SectionData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
46
src/drawApp/graphics/StationLineInteraction.ts
Normal file
46
src/drawApp/graphics/StationLineInteraction.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import * as pb_1 from 'google-protobuf';
|
||||
import { IStationLineData } from 'src/graphics/stationLine/StationLine';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { GraphicDataBase } from './GraphicDataBase';
|
||||
|
||||
export class StationLineData
|
||||
extends GraphicDataBase
|
||||
implements IStationLineData
|
||||
{
|
||||
constructor(data?: graphicData.StationLine) {
|
||||
let stationLine;
|
||||
if (!data) {
|
||||
stationLine = new graphicData.StationLine({
|
||||
common: GraphicDataBase.defaultCommonInfo(),
|
||||
});
|
||||
} else {
|
||||
stationLine = data;
|
||||
}
|
||||
super(stationLine);
|
||||
}
|
||||
|
||||
public get data(): graphicData.StationLine {
|
||||
return this.getData<graphicData.StationLine>();
|
||||
}
|
||||
get code(): string {
|
||||
return this.data.code;
|
||||
}
|
||||
set code(v: string) {
|
||||
this.data.code = v;
|
||||
}
|
||||
get hasTransfer(): boolean {
|
||||
return this.data.hasTransfer;
|
||||
}
|
||||
set hasTransfer(v: boolean) {
|
||||
this.data.hasTransfer = v;
|
||||
}
|
||||
clone(): StationLineData {
|
||||
return new StationLineData(this.data.cloneMessage());
|
||||
}
|
||||
copyFrom(data: StationLineData): void {
|
||||
pb_1.Message.copyInto(data.data, this.data);
|
||||
}
|
||||
eq(other: StationLineData): boolean {
|
||||
return pb_1.Message.equals(this.data, other.data);
|
||||
}
|
||||
}
|
@ -3,13 +3,7 @@ import { IPointData, Point } from 'pixi.js';
|
||||
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan';
|
||||
import { Link } from 'src/graphics/link/Link';
|
||||
import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant';
|
||||
import { Rect } from 'src/graphics/rect/Rect';
|
||||
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 { Signal } from 'src/graphics/signal/Signal';
|
||||
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
|
||||
@ -25,12 +19,21 @@ import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
import { MenuItemOptions } from 'src/jl-graphic/ui/Menu';
|
||||
import { IscsFanData } from './graphics/IscsFanInteraction';
|
||||
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 { SignalData } from './graphics/SignalInteraction';
|
||||
import { graphicData } from 'src/protos/stationLayoutGraphics';
|
||||
import { Rect } from 'src/graphics/rect/Rect';
|
||||
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
|
||||
import { RectData } from './graphics/RectInteraction';
|
||||
import { Platform } from 'src/graphics/platform/Platform';
|
||||
import { PlatformData } from './graphics/PlatformInteraction';
|
||||
import { PlatformDraw } from 'src/graphics/platform/PlatformDrawAssistant';
|
||||
import { Station } from 'src/graphics/station/Station';
|
||||
import { StationDraw } from 'src/graphics/station/StationDrawAssistant';
|
||||
import { StationData } from './graphics/StationInteraction';
|
||||
import { StationLine } from 'src/graphics/stationLine/StationLine';
|
||||
import { StationLineDraw } from 'src/graphics/stationLine/StationLineDrawAssistant';
|
||||
import { StationLineData } from './graphics/StationLineInteraction';
|
||||
import { Turnout } from 'src/graphics/turnout/Turnout';
|
||||
import { TurnoutDraw } from 'src/graphics/turnout/TurnoutDrawAssistant';
|
||||
import { TurnoutData } from './graphics/TurnoutInteraction';
|
||||
@ -40,6 +43,9 @@ import { RunLineData } from './graphics/RunLineInteraction';
|
||||
import { saveDraft, getDraft } from 'src/api/DraftApi';
|
||||
import { useDrawStore } from 'src/stores/draw-store';
|
||||
import { successNotify, errorNotify } from '../utils/CommonNotify';
|
||||
import { Section } from 'src/graphics/section/Section';
|
||||
import { SectionDraw } from 'src/graphics/section/SectionDrawAssistant';
|
||||
import { SectionData } from './graphics/SectionInteraction';
|
||||
|
||||
export function fromStoragePoint(p: graphicData.Point): Point {
|
||||
return new Point(p.x, p.y);
|
||||
@ -117,6 +123,9 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
| SignalDraw
|
||||
| TurnoutDraw
|
||||
| RunLineDraw
|
||||
| SectionDraw
|
||||
| StationLineDraw
|
||||
| RectDraw
|
||||
)[] = [];
|
||||
if (draftType === 'Line') {
|
||||
drawAssistants = [
|
||||
@ -138,61 +147,28 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
|
||||
// new TrainDraw(app, () => {
|
||||
// return new TrainData();
|
||||
// }),
|
||||
new SectionDraw(app, () => new SectionData()),
|
||||
];
|
||||
} else {
|
||||
drawAssistants = [
|
||||
new StationLineDraw(app, () => {
|
||||
return new StationLineData();
|
||||
}),
|
||||
new RectDraw(app, () => {
|
||||
return new RectData();
|
||||
}),
|
||||
];
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyP',
|
||||
value: 'KeyI',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Platform.Type).resume();
|
||||
app.interactionPlugin(StationLine.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyT',
|
||||
onPress: () => {
|
||||
console.log(app.interactionPlugin(Turnout.Type));
|
||||
app.interactionPlugin(Turnout.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyO',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Station.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyH',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(Signal.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
app.addKeyboardListener(
|
||||
new KeyListener({
|
||||
value: 'KeyR',
|
||||
onPress: () => {
|
||||
app.interactionPlugin(RunLine.Type).resume();
|
||||
},
|
||||
})
|
||||
);
|
||||
// app.addKeyboardListener(
|
||||
// new KeyListener({
|
||||
// value: 'KeyR',
|
||||
// onPress: () => {
|
||||
// app.interactionPlugin(Train.Type).resume();
|
||||
// },
|
||||
// })
|
||||
// );
|
||||
}
|
||||
|
||||
app.setOptions({
|
||||
drawAssistants: drawAssistants,
|
||||
});
|
||||
app.setOptions({ drawAssistants: drawAssistants });
|
||||
|
||||
// 画布右键菜单
|
||||
app.registerMenu(DefaultCanvasMenu);
|
||||
@ -255,7 +231,7 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
storage.links.push((linkData as LinkData).data);
|
||||
} else if (Rect.Type === g.type) {
|
||||
const rectData = (g as Rect).saveData();
|
||||
storage.Rects.push((rectData as RectData).data);
|
||||
storage.rects.push((rectData as RectData).data);
|
||||
} else if (IscsFan.Type === g.type) {
|
||||
const IscsFanData = (g as IscsFan).saveData();
|
||||
storage.iscsFans.push((IscsFanData as IscsFanData).data);
|
||||
@ -277,6 +253,12 @@ export function saveDrawDatas(app: JlDrawApp) {
|
||||
} else if (RunLine.Type === g.type) {
|
||||
const runLineData = (g as RunLine).saveData();
|
||||
storage.runLines.push((runLineData as RunLineData).data);
|
||||
} else if (Section.Type === g.type) {
|
||||
const sectionData = (g as Section).saveData();
|
||||
storage.section.push((sectionData as SectionData).data);
|
||||
} else if (StationLine.Type === g.type) {
|
||||
const stationLineData = (g as StationLine).saveData();
|
||||
storage.stationLines.push((stationLineData as StationLineData).data);
|
||||
}
|
||||
});
|
||||
const base64 = fromUint8Array(storage.serialize());
|
||||
@ -305,7 +287,7 @@ export async function loadDrawDatas(app: GraphicApp) {
|
||||
storage.links.forEach((link) => {
|
||||
datas.push(new LinkData(link));
|
||||
});
|
||||
storage.Rects.forEach((rect) => {
|
||||
storage.rects.forEach((rect) => {
|
||||
datas.push(new RectData(rect));
|
||||
});
|
||||
storage.iscsFans.forEach((fan) => {
|
||||
@ -329,6 +311,12 @@ export async function loadDrawDatas(app: GraphicApp) {
|
||||
storage.runLines.forEach((runLine) => {
|
||||
datas.push(new RunLineData(runLine));
|
||||
});
|
||||
storage.section.forEach((section) => {
|
||||
datas.push(new SectionData(section));
|
||||
});
|
||||
storage.stationLines.forEach((stationLine) => {
|
||||
datas.push(new StationLineData(stationLine));
|
||||
});
|
||||
app.loadGraphic(datas);
|
||||
} else {
|
||||
app.loadGraphic([]);
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { Color, Graphics, IPointData, Point } from 'pixi.js';
|
||||
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'src/jl-graphic';
|
||||
import { Color, Graphics, IPointData, Point, Rectangle } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
getRectangleCenter,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
export interface IRectData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
@ -14,8 +19,8 @@ export interface IRectData extends GraphicData {
|
||||
set width(v: number);
|
||||
get height(): number; // 高度
|
||||
set height(v: number);
|
||||
get points(): IPointData[]; // 线坐标点
|
||||
set points(points: IPointData[]);
|
||||
get radius(): number; // 圆角半径
|
||||
set radius(v: number);
|
||||
clone(): IRectData;
|
||||
copyFrom(data: IRectData): void;
|
||||
eq(other: IRectData): boolean;
|
||||
@ -24,16 +29,13 @@ export interface IRectData extends GraphicData {
|
||||
const rectConsts = {
|
||||
lineWidth: 2,
|
||||
lineColor: '0xff0000',
|
||||
width: 60,
|
||||
height: 20,
|
||||
};
|
||||
|
||||
export class Rect extends JlGraphic {
|
||||
static Type = 'Rect';
|
||||
rectGraphic: Graphics;
|
||||
rectGraphic: Graphics = new Graphics();
|
||||
constructor() {
|
||||
super(Rect.Type);
|
||||
this.rectGraphic = new Graphics();
|
||||
this.addChild(this.rectGraphic);
|
||||
}
|
||||
|
||||
@ -41,44 +43,53 @@ export class Rect extends JlGraphic {
|
||||
return this.getDatas<IRectData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const width = this.datas.width;
|
||||
const height = this.datas.height;
|
||||
if (this.linePoints.length == 0) {
|
||||
const r1 = new Point(this.datas.point.x, this.datas.point.y);
|
||||
const r2 = new Point(r1.x + width, r1.y);
|
||||
const r3 = new Point(r1.x + width, r1.y + height);
|
||||
const r4 = new Point(r1.x, r1.y + height);
|
||||
this.datas.points = [r1, r2, r3, r4, r1];
|
||||
}
|
||||
const rectGraphic = this.rectGraphic;
|
||||
rectGraphic.clear();
|
||||
rectGraphic.lineStyle(
|
||||
this.datas.lineWidth,
|
||||
new Color(this.datas.lineColor)
|
||||
);
|
||||
rectGraphic.drawPolygon(this.datas.points);
|
||||
const radius = this.datas?.radius || 0;
|
||||
rectGraphic.drawRoundedRect(
|
||||
0,
|
||||
0,
|
||||
this.datas.width,
|
||||
this.datas.height,
|
||||
radius
|
||||
);
|
||||
rectGraphic.pivot = getRectangleCenter(
|
||||
new Rectangle(0, 0, this.datas.width, this.datas.height)
|
||||
);
|
||||
const transformPos = this.datas.transform.position;
|
||||
if (transformPos.x == 0 && transformPos.y == 0) {
|
||||
this.position.set(
|
||||
this.datas.point.x + this.datas.width / 2,
|
||||
this.datas.point.y + this.datas.height / 2
|
||||
);
|
||||
} else {
|
||||
this.position.set(
|
||||
this.datas.transform.position.x,
|
||||
this.datas.transform.position.y
|
||||
);
|
||||
}
|
||||
}
|
||||
get linePoints(): IPointData[] {
|
||||
return this.datas.points;
|
||||
}
|
||||
set linePoints(points: IPointData[]) {
|
||||
const old = this.datas.clone();
|
||||
old.points = points;
|
||||
this.updateData(old);
|
||||
rectPoints(): IPointData[] {
|
||||
const r1 = new Point(this.datas.point.x, this.datas.point.y);
|
||||
const r2 = new Point(r1.x + this.datas.width, r1.y);
|
||||
const r3 = new Point(r1.x + this.datas.width, r1.y + this.datas.height);
|
||||
const r4 = new Point(r1.x, r1.y + this.datas.height);
|
||||
const rectPoints = [r1, r2, r3, r4, r1];
|
||||
return rectPoints;
|
||||
}
|
||||
}
|
||||
|
||||
export class RectTemplate extends JlGraphicTemplate<Rect> {
|
||||
lineWidth: number;
|
||||
lineColor: string;
|
||||
width: number;
|
||||
height: number;
|
||||
constructor() {
|
||||
super(Rect.Type);
|
||||
this.lineWidth = rectConsts.lineWidth;
|
||||
this.lineColor = rectConsts.lineColor;
|
||||
this.width = rectConsts.width;
|
||||
this.height = rectConsts.height;
|
||||
}
|
||||
new(): Rect {
|
||||
return new Rect();
|
||||
|
@ -1,38 +1,13 @@
|
||||
import { FederatedPointerEvent, Graphics, Point, IHitArea } from 'pixi.js';
|
||||
import {
|
||||
FederatedPointerEvent,
|
||||
Graphics,
|
||||
Point,
|
||||
IHitArea,
|
||||
DisplayObject,
|
||||
FederatedMouseEvent,
|
||||
} from 'pixi.js';
|
||||
import {
|
||||
DraggablePoint,
|
||||
GraphicApp,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
linePoint,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import AbsorbablePoint, {
|
||||
AbsorbablePosition,
|
||||
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
||||
import {
|
||||
ILineGraphic,
|
||||
PolylineEditPlugin,
|
||||
addWaySegmentingConfig,
|
||||
addPolygonSegmentingPoint,
|
||||
clearWayPoint,
|
||||
clearWaypointsConfig,
|
||||
getWayLineIndex,
|
||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
|
||||
|
||||
import { IRectData, Rect, RectTemplate } from './Rect';
|
||||
import { Link } from '../link/Link';
|
||||
|
||||
export interface IRectDrawOptions {
|
||||
newData: () => IRectData;
|
||||
@ -46,7 +21,7 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
|
||||
constructor(app: JlDrawApp, createData: () => IRectData) {
|
||||
super(app, new RectTemplate(), createData, 'sym_o_square', '矩形Rect');
|
||||
this.container.addChild(this.rectGraphic);
|
||||
RectPointsEditPlugin.init(app);
|
||||
rectInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
@ -90,10 +65,6 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
|
||||
return [x, y, w, h];
|
||||
}
|
||||
prepareData(data: IRectData): boolean {
|
||||
if (this.point1 == null) {
|
||||
console.log('Rect绘制因点不够取消绘制');
|
||||
return false;
|
||||
}
|
||||
const p1 = this.point1 as Point;
|
||||
const p2 = this.point2 as Point;
|
||||
const [x, y, width, height] = this.normalize(p1, p2);
|
||||
@ -115,147 +86,42 @@ export class RectGraphicHitArea implements IHitArea {
|
||||
}
|
||||
contains(x: number, y: number): boolean {
|
||||
let contains = false;
|
||||
const datas = this.rect.datas;
|
||||
const tolerance = datas.lineWidth;
|
||||
const p1 = new Point(0, 0);
|
||||
const p2 = new Point(p1.x + datas.width, p1.y);
|
||||
const p3 = new Point(p1.x + datas.width, p1.y + datas.height);
|
||||
const p4 = new Point(p1.x, p1.y + datas.height);
|
||||
const p = new Point(x, y);
|
||||
const rectData = this.rect.datas;
|
||||
//contains = pointPolygon(p, rectData.points, rectData.lineWidth);是否包含多边形内部
|
||||
const tolerance = rectData.lineWidth;
|
||||
for (let i = 0; i < rectData.points.length - 1; i++) {
|
||||
const p1 = rectData.points[i];
|
||||
const p2 = rectData.points[i + 1];
|
||||
contains = contains || linePoint(p1, p2, p, tolerance);
|
||||
if (contains) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
contains = contains || linePoint(p1, p2, p, tolerance);
|
||||
contains = contains || linePoint(p2, p3, p, tolerance);
|
||||
contains = contains || linePoint(p3, p4, p, tolerance);
|
||||
contains = contains || linePoint(p4, p1, p, tolerance);
|
||||
return contains;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建吸附位置
|
||||
* @param rect
|
||||
* @returns
|
||||
*/
|
||||
function buildAbsorbablePositions(rect: Rect): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
const rects = rect.queryStore.queryByType<Rect>(Rect.Type);
|
||||
const links = rect.queryStore.queryByType<Link>(Link.Type);
|
||||
|
||||
links.forEach((other) => {
|
||||
const apa = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(other.getStartPoint())
|
||||
);
|
||||
const apb = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(other.getEndPoint())
|
||||
);
|
||||
aps.push(apa, apb);
|
||||
});
|
||||
|
||||
rects.forEach((other) => {
|
||||
if (other.id == rect.id) {
|
||||
return;
|
||||
}
|
||||
other.linePoints.forEach((point) => {
|
||||
const absorbablePoint = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(point)
|
||||
);
|
||||
aps.push(absorbablePoint);
|
||||
});
|
||||
});
|
||||
|
||||
return aps;
|
||||
}
|
||||
|
||||
/**
|
||||
* 端点拖拽添加吸附位置
|
||||
* @param g
|
||||
* @param dp
|
||||
* @param index
|
||||
*/
|
||||
function onEditPointCreate(g: ILineGraphic, dp: DraggablePoint): void {
|
||||
const rect = g as Rect;
|
||||
// 端点
|
||||
dp.on('transformstart', (e: GraphicTransformEvent) => {
|
||||
if (e.isShift()) {
|
||||
rect.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(rect),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const RectEditMenu: ContextMenu = ContextMenu.init({
|
||||
name: '矩形编辑菜单',
|
||||
groups: [
|
||||
{
|
||||
items: [addWaySegmentingConfig, clearWaypointsConfig],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
/**
|
||||
* rect路径编辑
|
||||
*/
|
||||
export class RectPointsEditPlugin extends GraphicInteractionPlugin<Rect> {
|
||||
static Name = 'RectPointsDrag';
|
||||
constructor(app: GraphicApp) {
|
||||
super(RectPointsEditPlugin.Name, app);
|
||||
app.registerMenu(RectEditMenu);
|
||||
export class rectInteraction extends GraphicInteractionPlugin<Rect> {
|
||||
static Name = 'platform_transform';
|
||||
constructor(app: JlDrawApp) {
|
||||
super(rectInteraction.Name, app);
|
||||
}
|
||||
static init(app: GraphicApp): RectPointsEditPlugin {
|
||||
return new RectPointsEditPlugin(app);
|
||||
static init(app: JlDrawApp) {
|
||||
return new rectInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Rect[] | undefined {
|
||||
return grahpics.filter((g) => g.type == Rect.Type) as Rect[];
|
||||
return grahpics.filter((g) => g.type === Rect.Type).map((g) => g as Rect);
|
||||
}
|
||||
bind(g: Rect): void {
|
||||
g.rectGraphic.eventMode = 'static';
|
||||
g.rectGraphic.cursor = 'pointer';
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.rectGraphic.hitArea = new RectGraphicHitArea(g);
|
||||
g.on('_rightclick', this.onContextMenu, this);
|
||||
g.on('selected', this.onSelected, this);
|
||||
g.on('unselected', this.onUnselected, this);
|
||||
}
|
||||
unbind(g: Rect): void {
|
||||
g.off('_rightclick', this.onContextMenu, this);
|
||||
g.off('selected', this.onSelected, this);
|
||||
g.off('unselected', this.onUnselected, this);
|
||||
}
|
||||
|
||||
onContextMenu(e: FederatedMouseEvent) {
|
||||
const target = e.target as DisplayObject;
|
||||
const rect = target.getGraphic() as Rect;
|
||||
this.app.updateSelected(rect);
|
||||
addWaySegmentingConfig.handler = () => {
|
||||
const linePoints = rect.linePoints;
|
||||
const p = rect.screenToLocalPoint(e.global);
|
||||
const { start, end } = getWayLineIndex(linePoints, p);
|
||||
addPolygonSegmentingPoint(rect, start, end);
|
||||
};
|
||||
clearWaypointsConfig.handler = () => {
|
||||
clearWayPoint(rect, false);
|
||||
};
|
||||
RectEditMenu.open(e.global);
|
||||
}
|
||||
|
||||
onSelected(g: DisplayObject): void {
|
||||
const rect = g as Rect;
|
||||
let lep = rect.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (!lep) {
|
||||
lep = new PolylineEditPlugin(rect, { onEditPointCreate });
|
||||
rect.addAssistantAppend(lep);
|
||||
}
|
||||
lep.showAll();
|
||||
}
|
||||
onUnselected(g: DisplayObject): void {
|
||||
const rect = g as Rect;
|
||||
const lep = rect.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (lep) {
|
||||
lep.hideAll();
|
||||
}
|
||||
g.eventMode = 'none';
|
||||
g.scalable = false;
|
||||
g.rotatable = false;
|
||||
}
|
||||
}
|
||||
|
76
src/graphics/section/Section.ts
Normal file
76
src/graphics/section/Section.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import { Graphics, IPointData } from 'pixi.js';
|
||||
import { GraphicData, JlGraphic, JlGraphicTemplate } from 'src/jl-graphic';
|
||||
import { ILineGraphic } from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import { Link } from '../link/Link';
|
||||
|
||||
export interface ISectionData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
get points(): IPointData[]; // 线坐标点
|
||||
set points(points: IPointData[]);
|
||||
clone(): ISectionData;
|
||||
copyFrom(data: ISectionData): void;
|
||||
eq(other: ISectionData): boolean;
|
||||
}
|
||||
export const SectionConsts = {
|
||||
lineColor: '#5578b6',
|
||||
lineWidth: 5,
|
||||
};
|
||||
|
||||
export class Section extends JlGraphic implements ILineGraphic {
|
||||
static Type = 'Section';
|
||||
lineGraphic: Graphics;
|
||||
|
||||
constructor() {
|
||||
super(Section.Type);
|
||||
this.lineGraphic = new Graphics();
|
||||
this.addChild(this.lineGraphic);
|
||||
}
|
||||
|
||||
doRepaint() {
|
||||
if (this.datas.points.length < 2) {
|
||||
throw new Error('Link坐标数据异常');
|
||||
}
|
||||
this.lineGraphic.clear();
|
||||
this.lineGraphic.lineStyle(
|
||||
SectionConsts.lineWidth,
|
||||
SectionConsts.lineColor
|
||||
);
|
||||
|
||||
this.datas.points.forEach((p, i) => {
|
||||
if (i !== 0) {
|
||||
this.lineGraphic.lineTo(p.x, p.y);
|
||||
} else {
|
||||
this.lineGraphic.moveTo(p.x, p.y);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getStartPoint() {
|
||||
return this.datas.points[0];
|
||||
}
|
||||
getEndPoint(): IPointData {
|
||||
return this.datas.points[this.datas.points.length - 1];
|
||||
}
|
||||
|
||||
get datas(): ISectionData {
|
||||
return this.getDatas<ISectionData>();
|
||||
}
|
||||
get linePoints(): IPointData[] {
|
||||
return this.datas.points;
|
||||
}
|
||||
set linePoints(points: IPointData[]) {
|
||||
const old = this.datas.clone();
|
||||
old.points = points;
|
||||
this.updateData(old);
|
||||
}
|
||||
}
|
||||
|
||||
export class SectionTemplate extends JlGraphicTemplate<Section> {
|
||||
constructor() {
|
||||
super(Section.Type);
|
||||
}
|
||||
new() {
|
||||
return new Section();
|
||||
}
|
||||
}
|
193
src/graphics/section/SectionDrawAssistant.ts
Normal file
193
src/graphics/section/SectionDrawAssistant.ts
Normal file
@ -0,0 +1,193 @@
|
||||
import {
|
||||
DraggablePoint,
|
||||
GraphicApp,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
GraphicTransformEvent,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
linePoint,
|
||||
} from 'src/jl-graphic';
|
||||
import {
|
||||
ISectionData,
|
||||
Section,
|
||||
SectionConsts,
|
||||
SectionTemplate,
|
||||
} from './Section';
|
||||
import {
|
||||
DisplayObject,
|
||||
FederatedMouseEvent,
|
||||
Graphics,
|
||||
IHitArea,
|
||||
Point,
|
||||
} from 'pixi.js';
|
||||
import {
|
||||
ILineGraphic,
|
||||
PolylineEditPlugin,
|
||||
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import AbsorbablePoint, {
|
||||
AbsorbablePosition,
|
||||
} from 'src/jl-graphic/graphic/AbsorbablePosition';
|
||||
import { Turnout } from '../turnout/Turnout';
|
||||
|
||||
export class SectionDraw extends GraphicDrawAssistant<
|
||||
SectionTemplate,
|
||||
ISectionData
|
||||
> {
|
||||
points: Point[] = [];
|
||||
graphic = new Graphics();
|
||||
|
||||
constructor(app: JlDrawApp, createData: () => ISectionData) {
|
||||
super(
|
||||
app,
|
||||
new SectionTemplate(),
|
||||
createData,
|
||||
'sym_o_timeline',
|
||||
'区段Section'
|
||||
);
|
||||
this.container.addChild(this.graphic);
|
||||
|
||||
SectionPointEditPlugin.init(app);
|
||||
}
|
||||
|
||||
onLeftDown(e: FederatedMouseEvent): void {
|
||||
const { x, y } = this.toCanvasCoordinates(e.global);
|
||||
const p = new Point(x, y);
|
||||
// this.points.pop();
|
||||
this.points.push(p);
|
||||
}
|
||||
onRightClick(): void {
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(cp: Point): void {
|
||||
if (this.points.length < 1) return;
|
||||
this.graphic.clear();
|
||||
this.graphic.lineStyle(SectionConsts.lineWidth, SectionConsts.lineColor);
|
||||
// this.points.push(cp);
|
||||
this.points.forEach((p, i) => {
|
||||
if (i !== 0) {
|
||||
this.graphic.lineTo(p.x, p.y);
|
||||
} else {
|
||||
this.graphic.moveTo(p.x, p.y);
|
||||
}
|
||||
});
|
||||
this.graphic.lineTo(cp.x, cp.y);
|
||||
}
|
||||
prepareData(data: ISectionData): boolean {
|
||||
data.points = this.points;
|
||||
|
||||
return true;
|
||||
}
|
||||
clearCache(): void {
|
||||
this.points = [];
|
||||
this.graphic.clear();
|
||||
}
|
||||
}
|
||||
|
||||
class SectionGraphicHitArea implements IHitArea {
|
||||
section: Section;
|
||||
constructor(section: Section) {
|
||||
this.section = section;
|
||||
}
|
||||
contains(x: number, y: number): boolean {
|
||||
for (let i = 1; i < this.section.datas.points.length; i++) {
|
||||
const p1 = this.section.datas.points[i - 1];
|
||||
const p2 = this.section.datas.points[i];
|
||||
if (linePoint(p1, p2, { x, y }, SectionConsts.lineWidth)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function buildAbsorbablePositions(section: Section): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
|
||||
const sections = section.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((other) => {
|
||||
if (other.id == section.id) {
|
||||
return;
|
||||
}
|
||||
const apa = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(other.getStartPoint())
|
||||
);
|
||||
const apb = new AbsorbablePoint(
|
||||
other.localToCanvasPoint(other.getEndPoint())
|
||||
);
|
||||
aps.push(apa, apb);
|
||||
});
|
||||
|
||||
const turnouts = section.queryStore.queryByType<Turnout>(Turnout.Type);
|
||||
turnouts.forEach((turnout) => {
|
||||
turnout.localToCanvasPoints(...turnout.getPortPoints()).forEach((p) => {
|
||||
aps.push(new AbsorbablePoint(p));
|
||||
});
|
||||
});
|
||||
|
||||
return aps;
|
||||
}
|
||||
|
||||
function onEditPointCreate(
|
||||
g: ILineGraphic,
|
||||
dp: DraggablePoint,
|
||||
index: number
|
||||
): void {
|
||||
const section = g as Section;
|
||||
if (index === 0 || index == section.datas.points.length - 1) {
|
||||
// 端点
|
||||
dp.on('transformstart', (e: GraphicTransformEvent) => {
|
||||
if (e.isShift()) {
|
||||
section.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(section),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export class SectionPointEditPlugin extends GraphicInteractionPlugin<Section> {
|
||||
static Name = 'SectionPointDrag';
|
||||
constructor(app: GraphicApp) {
|
||||
super(SectionPointEditPlugin.Name, app);
|
||||
}
|
||||
static init(app: GraphicApp) {
|
||||
return new SectionPointEditPlugin(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): Section[] | undefined {
|
||||
return grahpics.filter((g) => g.type == Section.Type) as Section[];
|
||||
}
|
||||
bind(g: Section): void {
|
||||
g.lineGraphic.eventMode = 'static';
|
||||
g.lineGraphic.cursor = 'pointer';
|
||||
g.lineGraphic.hitArea = new SectionGraphicHitArea(g);
|
||||
g.on('selected', this.onSelected, this);
|
||||
g.on('unselected', this.onUnselected, this);
|
||||
}
|
||||
unbind(g: Section): void {
|
||||
g.off('selected', this.onSelected, this);
|
||||
g.off('unselected', this.onUnselected, this);
|
||||
}
|
||||
|
||||
onSelected(g: DisplayObject): void {
|
||||
const section = g as Section;
|
||||
let lep = section.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (!lep) {
|
||||
lep = new PolylineEditPlugin(section, { onEditPointCreate });
|
||||
section.addAssistantAppend(lep);
|
||||
}
|
||||
lep.showAll();
|
||||
}
|
||||
onUnselected(g: DisplayObject): void {
|
||||
const section = g as Section;
|
||||
const lep = section.getAssistantAppend<PolylineEditPlugin>(
|
||||
PolylineEditPlugin.Name
|
||||
);
|
||||
if (lep) {
|
||||
lep.hideAll();
|
||||
}
|
||||
}
|
||||
}
|
140
src/graphics/stationLine/StationLine.ts
Normal file
140
src/graphics/stationLine/StationLine.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import { Color, Container, Graphics, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
JlGraphic,
|
||||
JlGraphicTemplate,
|
||||
VectorText,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
export interface IStationLineData extends GraphicData {
|
||||
get code(): string; // 编号
|
||||
set code(v: string);
|
||||
get hasTransfer(): boolean;
|
||||
set hasTransfer(v: boolean);
|
||||
clone(): IStationLineData;
|
||||
copyFrom(data: IStationLineData): void;
|
||||
eq(other: IStationLineData): boolean;
|
||||
}
|
||||
|
||||
const stationConsts = {
|
||||
radius: 5,
|
||||
borderWidth: 1,
|
||||
borderColor: '0xff0000',
|
||||
fillColor: '0xff0000',
|
||||
circleOffsetY: -20,
|
||||
transferRadius: 3.5,
|
||||
transferWidth: 0.2,
|
||||
transferColor: '0x0fe81f',
|
||||
codeColor: '0xF48815',
|
||||
codeFontSize: 22,
|
||||
lineWidth: 3,
|
||||
};
|
||||
//子元素--圆点
|
||||
class circleGraphic extends Container {
|
||||
circle: Graphics = new Graphics();
|
||||
arcUp: Graphics = new Graphics();
|
||||
arcDown: Graphics = new Graphics();
|
||||
arrowUp: Graphics = new Graphics();
|
||||
arrowDown: Graphics = new Graphics();
|
||||
constructor() {
|
||||
super();
|
||||
this.addChild(this.circle);
|
||||
this.addChild(this.arcUp);
|
||||
this.addChild(this.arcDown);
|
||||
this.addChild(this.arrowUp);
|
||||
this.addChild(this.arrowDown);
|
||||
}
|
||||
draw(datas: IStationLineData): void {
|
||||
const circle = this.circle;
|
||||
circle.clear();
|
||||
circle.lineStyle(
|
||||
stationConsts.borderWidth,
|
||||
new Color(stationConsts.borderColor)
|
||||
);
|
||||
circle.beginFill(stationConsts.fillColor, 1);
|
||||
circle.drawCircle(0, 0, stationConsts.radius);
|
||||
circle.endFill;
|
||||
circle.position.set(0, stationConsts.circleOffsetY);
|
||||
const arcGraphicUp = this.arcUp;
|
||||
const arcGraphicDown = this.arcDown;
|
||||
const arrowUpGraphic = this.arrowUp;
|
||||
const arrowDownGraphic = this.arrowDown;
|
||||
arcGraphicUp.clear();
|
||||
arcGraphicDown.clear();
|
||||
arrowUpGraphic.clear();
|
||||
arrowDownGraphic.clear();
|
||||
if (datas.hasTransfer) {
|
||||
this.drawTransfer(arcGraphicUp, arrowUpGraphic);
|
||||
this.drawTransfer(arcGraphicDown, arrowDownGraphic);
|
||||
arcGraphicDown.rotation = Math.PI;
|
||||
arrowDownGraphic.rotation = Math.PI - (Math.PI * 1) / 25;
|
||||
arrowDownGraphic.position.set(
|
||||
stationConsts.transferRadius,
|
||||
stationConsts.circleOffsetY
|
||||
);
|
||||
}
|
||||
}
|
||||
drawTransfer(transferGraphic: Graphics, arrowGraphic: Graphics): void {
|
||||
transferGraphic.lineStyle(
|
||||
stationConsts.transferWidth,
|
||||
new Color(stationConsts.transferColor)
|
||||
);
|
||||
transferGraphic.arc(
|
||||
0,
|
||||
0,
|
||||
stationConsts.transferRadius,
|
||||
Math.PI / 10,
|
||||
Math.PI,
|
||||
false
|
||||
);
|
||||
transferGraphic.position.set(0, stationConsts.circleOffsetY);
|
||||
arrowGraphic.lineStyle(
|
||||
stationConsts.transferWidth,
|
||||
new Color(stationConsts.transferColor)
|
||||
);
|
||||
arrowGraphic.moveTo(0, 0);
|
||||
arrowGraphic.lineTo(1, 1);
|
||||
arrowGraphic.moveTo(0, 0);
|
||||
arrowGraphic.lineTo(-1, 1);
|
||||
arrowGraphic.position.set(
|
||||
-stationConsts.transferRadius,
|
||||
stationConsts.circleOffsetY
|
||||
);
|
||||
arrowGraphic.pivot = new Point(0, 0);
|
||||
arrowGraphic.rotation = -(Math.PI * 1) / 25;
|
||||
}
|
||||
}
|
||||
export class StationLine extends JlGraphic {
|
||||
static Type = 'stationLine';
|
||||
codeGraph: VectorText = new VectorText(''); //车站名
|
||||
circleGraphic: circleGraphic = new circleGraphic();
|
||||
constructor() {
|
||||
super(StationLine.Type);
|
||||
this.addChild(this.codeGraph);
|
||||
this.addChild(this.circleGraphic);
|
||||
this.circleGraphic.name = 'circle';
|
||||
}
|
||||
|
||||
get datas(): IStationLineData {
|
||||
return this.getDatas<IStationLineData>();
|
||||
}
|
||||
doRepaint(): void {
|
||||
const codeGraph = this.codeGraph;
|
||||
codeGraph.text = this.datas?.code || '车站StationLine';
|
||||
codeGraph.style.fill = stationConsts.codeColor;
|
||||
codeGraph.setVectorFontSize(stationConsts.codeFontSize);
|
||||
codeGraph.anchor.set(0.5);
|
||||
this.circleGraphic.draw(this.datas);
|
||||
}
|
||||
}
|
||||
|
||||
export class StationLineTemplate extends JlGraphicTemplate<StationLine> {
|
||||
hasTransfer: boolean;
|
||||
constructor() {
|
||||
super(StationLine.Type);
|
||||
this.hasTransfer = true;
|
||||
}
|
||||
new(): StationLine {
|
||||
return new StationLine();
|
||||
}
|
||||
}
|
100
src/graphics/stationLine/StationLineDrawAssistant.ts
Normal file
100
src/graphics/stationLine/StationLineDrawAssistant.ts
Normal file
@ -0,0 +1,100 @@
|
||||
import { FederatedPointerEvent, Point } from 'pixi.js';
|
||||
import {
|
||||
GraphicData,
|
||||
GraphicDrawAssistant,
|
||||
GraphicInteractionPlugin,
|
||||
JlDrawApp,
|
||||
JlGraphic,
|
||||
} from 'src/jl-graphic';
|
||||
|
||||
import {
|
||||
IStationLineData,
|
||||
StationLine,
|
||||
StationLineTemplate,
|
||||
} from './StationLine';
|
||||
|
||||
export interface IStationLineDrawOptions {
|
||||
newData: () => IStationLineData;
|
||||
}
|
||||
|
||||
export class StationLineDraw extends GraphicDrawAssistant<
|
||||
StationLineTemplate,
|
||||
IStationLineData
|
||||
> {
|
||||
codeGraph: StationLine;
|
||||
constructor(app: JlDrawApp, createData: () => IStationLineData) {
|
||||
super(
|
||||
app,
|
||||
new StationLineTemplate(),
|
||||
createData,
|
||||
'svguse:/drawIcon.svg#icon-station',
|
||||
'车站StationLine'
|
||||
);
|
||||
this.codeGraph = this.graphicTemplate.new();
|
||||
this.container.addChild(this.codeGraph);
|
||||
stationLineInteraction.init(app);
|
||||
}
|
||||
|
||||
bind(): void {
|
||||
super.bind();
|
||||
const data = { graphicType: 'stationLine' } as GraphicData;
|
||||
this.codeGraph.loadData(data);
|
||||
this.codeGraph.doRepaint();
|
||||
}
|
||||
unbind(): void {
|
||||
super.unbind();
|
||||
}
|
||||
|
||||
clearCache(): void {
|
||||
//this.codeGraph.destroy();
|
||||
}
|
||||
onLeftDown(e: FederatedPointerEvent): void {
|
||||
this.container.position.copyFrom(this.toCanvasCoordinates(e.global));
|
||||
this.createAndStore(true);
|
||||
}
|
||||
|
||||
redraw(p: Point): void {
|
||||
this.container.position.copyFrom(p);
|
||||
}
|
||||
prepareData(data: IStationLineData): boolean {
|
||||
const template = this.graphicTemplate;
|
||||
data.transform = this.container.saveTransform();
|
||||
data.hasTransfer = template.hasTransfer;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export class stationLineInteraction extends GraphicInteractionPlugin<StationLine> {
|
||||
static Name = 'stationLine_transform';
|
||||
constructor(app: JlDrawApp) {
|
||||
super(stationLineInteraction.Name, app);
|
||||
}
|
||||
static init(app: JlDrawApp) {
|
||||
return new stationLineInteraction(app);
|
||||
}
|
||||
filter(...grahpics: JlGraphic[]): StationLine[] | undefined {
|
||||
return grahpics
|
||||
.filter((g) => g.type === StationLine.Type)
|
||||
.map((g) => g as StationLine);
|
||||
}
|
||||
bind(g: StationLine): void {
|
||||
g.eventMode = 'static';
|
||||
g.cursor = 'pointer';
|
||||
g.scalable = true;
|
||||
g.rotatable = true;
|
||||
g.circleGraphic.eventMode = 'static';
|
||||
g.circleGraphic.cursor = 'pointer';
|
||||
g.circleGraphic.draggable = true;
|
||||
g.circleGraphic.selectable = true;
|
||||
g.circleGraphic.transformSave = true;
|
||||
}
|
||||
unbind(g: StationLine): 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;
|
||||
}
|
||||
}
|
@ -104,6 +104,10 @@ export class Turnout extends JlGraphic {
|
||||
return this.getStates<ITurnoutState>();
|
||||
}
|
||||
|
||||
getPortPoints() {
|
||||
return [this.datas.pointA, this.datas.pointB, this.datas.pointC];
|
||||
}
|
||||
|
||||
doRepaint(): void {
|
||||
const { pointA, pointB, pointC } = this.datas;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
import {
|
||||
AbsorbablePosition,
|
||||
DraggablePoint,
|
||||
GraphicApp,
|
||||
GraphicDrawAssistant,
|
||||
@ -25,6 +26,8 @@ import {
|
||||
} from 'pixi.js';
|
||||
import { GraphicEditPlugin } from 'src/jl-graphic/plugins/GraphicEditPlugin';
|
||||
import Vector2 from 'src/jl-graphic/math/Vector2';
|
||||
import { Section } from '../section/Section';
|
||||
import AbsorbablePoint from 'src/jl-graphic/graphic/AbsorbablePosition';
|
||||
|
||||
export class TurnoutDraw extends GraphicDrawAssistant<
|
||||
TurnoutTemplate,
|
||||
@ -94,6 +97,41 @@ export class TurnoutHitArea implements IHitArea {
|
||||
}
|
||||
}
|
||||
|
||||
function buildAbsorbablePositions(turnout: Turnout): AbsorbablePosition[] {
|
||||
const aps: AbsorbablePosition[] = [];
|
||||
|
||||
const sections = turnout.queryStore.queryByType<Section>(Section.Type);
|
||||
sections.forEach((section) => {
|
||||
const ps = new AbsorbablePoint(
|
||||
section.localToCanvasPoint(section.getStartPoint())
|
||||
);
|
||||
const pe = new AbsorbablePoint(
|
||||
section.localToCanvasPoint(section.getEndPoint())
|
||||
);
|
||||
aps.push(ps, pe);
|
||||
});
|
||||
|
||||
const turnouts = turnout.queryStore.queryByType<Turnout>(Turnout.Type);
|
||||
turnouts.forEach((otherTurnout) => {
|
||||
if (turnout.id === otherTurnout.id) return;
|
||||
otherTurnout.getPortPoints().forEach((portPoint) => {
|
||||
aps.push(new AbsorbablePoint(otherTurnout.localToCanvasPoint(portPoint)));
|
||||
});
|
||||
});
|
||||
|
||||
return aps;
|
||||
}
|
||||
|
||||
function onEditPointCreate(turnout: Turnout, dp: DraggablePoint) {
|
||||
dp.on('transformstart', (e: GraphicTransformEvent) => {
|
||||
if (e.isShift()) {
|
||||
turnout.getGraphicApp().setOptions({
|
||||
absorbablePositions: buildAbsorbablePositions(turnout),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Turnout> {
|
||||
static Name = 'TurnoutPointsDrag';
|
||||
static init(app: JlDrawApp) {
|
||||
@ -130,7 +168,7 @@ export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Tur
|
||||
TurnoutEditPlugin.Name
|
||||
);
|
||||
if (!tep) {
|
||||
tep = new TurnoutEditPlugin(turnout);
|
||||
tep = new TurnoutEditPlugin(turnout, { onEditPointCreate });
|
||||
turnout.addAssistantAppend(tep);
|
||||
}
|
||||
tep.reset();
|
||||
@ -152,14 +190,22 @@ export class TurnoutPointsInteractionPlugin extends GraphicInteractionPlugin<Tur
|
||||
}
|
||||
}
|
||||
|
||||
type onTurnoutEditPointCreate = (turnout: Turnout, dp: DraggablePoint) => void;
|
||||
|
||||
export interface ITurnoutEditOptions {
|
||||
onEditPointCreate?: onTurnoutEditPointCreate;
|
||||
}
|
||||
|
||||
export class TurnoutEditPlugin extends GraphicEditPlugin<Turnout> {
|
||||
static Name = 'TurnoutEdit';
|
||||
options: ITurnoutEditOptions;
|
||||
editPoints: DraggablePoint[] = [];
|
||||
labels: VectorText[] = [];
|
||||
|
||||
constructor(graphic: Turnout) {
|
||||
constructor(graphic: Turnout, options?: ITurnoutEditOptions) {
|
||||
super(graphic);
|
||||
this.name = TurnoutEditPlugin.Name;
|
||||
this.options = Object.assign({}, options);
|
||||
this.initEditPoints();
|
||||
}
|
||||
reset(): void {
|
||||
@ -208,6 +254,9 @@ export class TurnoutEditPlugin extends GraphicEditPlugin<Turnout> {
|
||||
|
||||
this.graphic.repaint();
|
||||
});
|
||||
if (this.options.onEditPointCreate) {
|
||||
this.options.onEditPointCreate(this.graphic, dp);
|
||||
}
|
||||
this.editPoints.push(dp);
|
||||
});
|
||||
this.addChild(...this.editPoints);
|
||||
|
@ -55,7 +55,7 @@
|
||||
import { useQuasar } from 'quasar';
|
||||
import { ApiError } from 'src/boot/axios';
|
||||
import { login } from 'src/api/UserApi';
|
||||
import { saveJwtToken } from 'src/configs/TokenManage';
|
||||
import { clearJwtToken, saveJwtToken } from 'src/configs/TokenManage';
|
||||
import { reactive } from 'vue';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
@ -69,6 +69,7 @@ const loginInfo = reactive({
|
||||
|
||||
async function doLogin() {
|
||||
try {
|
||||
clearJwtToken();
|
||||
const token = await login(loginInfo);
|
||||
saveJwtToken(token);
|
||||
router.push({ name: 'home' });
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user