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

This commit is contained in:
Yuan 2023-06-15 17:18:11 +08:00
commit b68eb3e4e5
40 changed files with 567 additions and 125 deletions

@ -1 +1 @@
Subproject commit 988599cd62fce00d3bde9a87f851505d97423b90
Subproject commit 8762ced5f8592db84ed19490cdb6c0322df874d8

View File

@ -121,13 +121,9 @@ function generatePathLine() {
const runLine = drawStore.selectedGraphic as RunLine;
if (runLine) {
const points = runLineModel.points;
const pointsUp: Point[] = [];
const pointsDown: Point[] = [];
points.forEach((item) => {
pointsUp.push(new Point(item.x, item.y - 10));
pointsDown.push(new Point(item.x, item.y + 10));
});
runLine.generatePathLine(pointsUp, pointsDown);
const points1: Point[] = [];
points.forEach((p) => points1.push(new Point(p.x, p.y)));
runLine.generatePathLine(points1);
}
}
</script>

View File

@ -10,9 +10,11 @@
<q-input
outlined
label="车站名称"
type="textarea"
@blur="onUpdate"
v-model="stationLineModel.code"
lazy-rules
autogrow
/>
<q-select
outlined

View File

@ -4,9 +4,11 @@
<q-input
outlined
label="车站名称"
type="textarea"
@blur="onUpdate"
v-model="stationModel.code"
lazy-rules
autogrow
/>
<q-select
outlined

View File

@ -27,10 +27,10 @@ export abstract class GraphicDataBase implements GraphicData {
this._data = data;
}
static defaultCommonInfo(): graphicData.CommonInfo {
static defaultCommonInfo(graphicType: string): graphicData.CommonInfo {
return new graphicData.CommonInfo({
id: '',
graphicType: '',
graphicType: graphicType,
transform: new graphicData.Transform({
position: new graphicData.Point({ x: 0, y: 0 }),
scale: new graphicData.Point({ x: 1, y: 1 }),

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { IIscsFanData } from 'src/graphics/iscs-fan/IscsFan';
import { IIscsFanData, IscsFan } from 'src/graphics/iscs-fan/IscsFan';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -10,7 +10,7 @@ export class IscsFanData extends GraphicDataBase implements IIscsFanData {
fan = data;
} else {
fan = new graphicData.IscsFan({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(IscsFan.Type),
});
}
super(fan);

View File

@ -1,6 +1,6 @@
import * as pb_1 from 'google-protobuf';
import { IPointData } from 'pixi.js';
import { ILinkData } from 'src/graphics/link/Link';
import { ILinkData, Link } from 'src/graphics/link/Link';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -9,7 +9,7 @@ export class LinkData extends GraphicDataBase implements ILinkData {
let link;
if (!data) {
link = new graphicData.Link({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Link.Type),
});
} else {
link = data;

View File

@ -1,6 +1,6 @@
import * as pb_1 from 'google-protobuf';
import { IPointData } from 'pixi.js';
import { IPathLineData } from 'src/graphics/pathLine/PathLine';
import { IPathLineData, PathLine } from 'src/graphics/pathLine/PathLine';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -9,7 +9,7 @@ export class PathLineData extends GraphicDataBase implements IPathLineData {
let pathLine;
if (!data) {
pathLine = new graphicData.PathLine({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(PathLine.Type),
});
} else {
pathLine = data;

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { IPlatformData } from 'src/graphics/platform/Platform';
import { IPlatformData, Platform } from 'src/graphics/platform/Platform';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -8,7 +8,7 @@ export class PlatformData extends GraphicDataBase implements IPlatformData {
let platform;
if (!data) {
platform = new graphicData.Platform({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Platform.Type),
});
} else {
platform = data;

View File

@ -1,20 +1,20 @@
import * as pb_1 from 'google-protobuf';
import { IPolygonData } from 'src/graphics/polygon/Polygon';
import { IPolygonData, Polygon } from 'src/graphics/polygon/Polygon';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
import { IPointData } from 'pixi.js';
export class PolygonData extends GraphicDataBase implements IPolygonData {
constructor(data?: graphicData.Polygon) {
let Polygon;
let polygon;
if (!data) {
Polygon = new graphicData.Polygon({
common: GraphicDataBase.defaultCommonInfo(),
polygon = new graphicData.Polygon({
common: GraphicDataBase.defaultCommonInfo(Polygon.Type),
});
} else {
Polygon = data;
polygon = data;
}
super(Polygon);
super(polygon);
}
public get data(): graphicData.Polygon {
@ -48,7 +48,6 @@ export class PolygonData extends GraphicDataBase implements IPolygonData {
);
}
clone(): PolygonData {
return new PolygonData(this.data.cloneMessage());
}

View File

@ -1,6 +1,6 @@
import * as pb_1 from 'google-protobuf';
import { IPointData } from 'pixi.js';
import { IRectData } from 'src/graphics/rect/Rect';
import { IRectData, Rect } from 'src/graphics/rect/Rect';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -9,7 +9,7 @@ export class RectData extends GraphicDataBase implements IRectData {
let rect;
if (!data) {
rect = new graphicData.Rect({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Rect.Type),
});
} else {
rect = data;

View File

@ -1,21 +1,20 @@
import * as pb_1 from 'google-protobuf';
import { IRunLineData } from 'src/graphics/runLine/RunLine';
import { IRunLineData, RunLine } from 'src/graphics/runLine/RunLine';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
import { IPointData } from 'pixi.js';
export class RunLineData extends GraphicDataBase implements IRunLineData {
constructor(data?: graphicData.RunLine) {
let RunLine;
let runLine;
if (!data) {
RunLine = new graphicData.RunLine({
common: GraphicDataBase.defaultCommonInfo(),
runLine = new graphicData.RunLine({
common: GraphicDataBase.defaultCommonInfo(RunLine.Type),
});
} else {
RunLine = data;
runLine = data;
}
RunLine.common.graphicType = 'RunLine';
super(RunLine);
super(runLine);
}
public get data(): graphicData.RunLine {
return this.getData<graphicData.RunLine>();

View File

@ -1,6 +1,6 @@
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from './GraphicDataBase';
import { ISectionData } from 'src/graphics/section/Section';
import { ISectionData, Section } from 'src/graphics/section/Section';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { IPointData } from 'pixi.js';
@ -9,7 +9,7 @@ export class SectionData extends GraphicDataBase implements ISectionData {
let section;
if (!data) {
section = new graphicData.Section({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Section.Type),
});
} else {
section = data;

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { ISignalData } from 'src/graphics/signal/Signal';
import { ISignalData, Signal } from 'src/graphics/signal/Signal';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -8,12 +8,11 @@ export class SignalData extends GraphicDataBase implements ISignalData {
let signal;
if (!data) {
signal = new graphicData.Signal({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Signal.Type),
});
} else {
signal = data;
}
signal.common.graphicType = 'signal';
super(signal);
}
public get data(): graphicData.Signal {

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { IStationData } from 'src/graphics/station/Station';
import { IStationData, Station } from 'src/graphics/station/Station';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -8,7 +8,7 @@ export class StationData extends GraphicDataBase implements IStationData {
let station;
if (!data) {
station = new graphicData.Station({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Station.Type),
});
} else {
station = data;

View File

@ -1,5 +1,8 @@
import * as pb_1 from 'google-protobuf';
import { IStationLineData } from 'src/graphics/stationLine/StationLine';
import {
IStationLineData,
StationLine,
} from 'src/graphics/stationLine/StationLine';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -11,7 +14,7 @@ export class StationLineData
let stationLine;
if (!data) {
stationLine = new graphicData.StationLine({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(StationLine.Type),
});
} else {
stationLine = data;

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { ITrainData } from 'src/graphics/train/Train';
import { ITrainData, Train } from 'src/graphics/train/Train';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -8,7 +8,7 @@ export class TrainData extends GraphicDataBase implements ITrainData {
let train;
if (!data) {
train = new graphicData.Train({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Train.Type),
});
} else {
train = data;

View File

@ -1,5 +1,5 @@
import * as pb_1 from 'google-protobuf';
import { ITrainLineData } from 'src/graphics/trainLine/TrainLine';
import { ITrainLineData, TrainLine } from 'src/graphics/trainLine/TrainLine';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { GraphicDataBase } from './GraphicDataBase';
@ -10,7 +10,7 @@ export class TrainLineData extends GraphicDataBase implements ITrainLineData {
fan = data;
} else {
fan = new graphicData.TrainLine({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(TrainLine.Type),
});
}
super(fan);

View File

@ -1,4 +1,4 @@
import { ITurnoutData } from 'src/graphics/turnout/Turnout';
import { ITurnoutData, Turnout } from 'src/graphics/turnout/Turnout';
import * as pb_1 from 'google-protobuf';
import { GraphicDataBase } from './GraphicDataBase';
import { graphicData } from 'src/protos/stationLayoutGraphics';
@ -9,7 +9,7 @@ export class TurnoutData extends GraphicDataBase implements ITurnoutData {
let turnout;
if (!data) {
turnout = new graphicData.Turnout({
common: GraphicDataBase.defaultCommonInfo(),
common: GraphicDataBase.defaultCommonInfo(Turnout.Type),
});
} else {
turnout = data;

84
src/drawApp/lineApp.ts Normal file
View File

@ -0,0 +1,84 @@
import { GraphicApp, GraphicData } from 'src/jl-graphic';
import { TrainData } from './graphics/TrainInteraction';
import { TrainTemplate } from 'src/graphics/train/Train';
import { SignalData } from './graphics/SignalInteraction';
import { SignalTemplate } from 'src/graphics/signal/Signal';
import { PlatformData } from './graphics/PlatformInteraction';
import { PlatformTemplate } from 'src/graphics/platform/Platform';
import { StationData } from './graphics/StationInteraction';
import { StationTemplate } from 'src/graphics/station/Station';
import { TurnoutData } from './graphics/TurnoutInteraction';
import { TurnoutTemplate } from 'src/graphics/turnout/Turnout';
import { SectionData } from './graphics/SectionInteraction';
import { SectionTemplate } from 'src/graphics/section/Section';
import { getDraft } from 'src/api/DraftApi';
import { graphicData } from 'src/protos/stationLayoutGraphics';
import { useLineStore } from 'src/stores/line-store';
import { toUint8Array } from 'js-base64';
let lineApp: GraphicApp | null = null;
export function getLineApp(): GraphicApp | null {
return lineApp;
}
export function destroyLineApp(): void {
if (lineApp) {
lineApp.destroy();
lineApp = null;
}
}
export function initLineApp(dom: HTMLElement): GraphicApp {
lineApp = new GraphicApp(dom);
const graphicTemplate = [
new TrainTemplate(),
new SignalTemplate(),
new SignalTemplate(),
new PlatformTemplate(),
new StationTemplate(),
new TurnoutTemplate(),
new SectionTemplate(),
];
lineApp.registerGraphicTemplates(...graphicTemplate);
return lineApp;
}
export async function loadLineDatas(app: GraphicApp) {
const lineStore = useLineStore();
const id = lineStore.lineId;
console.log(id, '***********');
if (!id) {
return;
}
const { proto: base64 } = await getDraft(id);
if (base64) {
const storage = graphicData.RtssGraphicStorage.deserialize(
toUint8Array(base64)
);
console.log('加载数据', storage);
app.updateCanvas(storage.canvas);
const datas: GraphicData[] = [];
// storage.Platforms.forEach((platform) => {
// datas.push(new PlatformData(platform));
// });
// storage.stations.forEach((station) => {
// datas.push(new StationData(station));
// });
// storage.train.forEach((train) => {
// datas.push(new TrainData(train));
// });
// storage.turnouts.forEach((turnout) => {
// datas.push(new TurnoutData(turnout));
// });
// storage.signals.forEach((signal) => {
// datas.push(new SignalData(signal));
// });
// storage.section.forEach((section) => {
// datas.push(new SectionData(section));
// });
app.loadGraphic(datas);
} else {
app.loadGraphic([]);
}
}

View File

@ -1,5 +1,7 @@
import { JlGraphic, GraphicData, JlGraphicTemplate } from 'src/jl-graphic';
import { Graphics, IPointData } from 'pixi.js';
import { RunLine } from '../runLine/RunLine';
import { getDrawApp } from 'src/drawApp';
export interface IPathLineData extends GraphicData {
get code(): string;
@ -13,7 +15,7 @@ export interface IPathLineData extends GraphicData {
export const pathLineConsts = {
pathLineWidth: 1,
pathLineColor: '0X000000',
pathLineColor: '0Xff0000',
};
export class PathLine extends JlGraphic {
@ -58,6 +60,22 @@ export class PathLine extends JlGraphic {
getEndPoint(): IPointData {
return this.datas.points[this.datas.points.length - 1];
}
onDelete(): void {
super.onDelete();
const pathLineId = this.datas.id;
const app = getDrawApp();
if (!app) return;
const runLineList = app.queryStore.queryByType(RunLine.Type) as RunLine[];
runLineList.find((runLine) => {
if (runLine.datas.downPathLineId === pathLineId) {
runLine.datas.downPathLineId = '';
return true;
} else if (runLine.datas.upPathLineId === pathLineId) {
runLine.datas.upPathLineId = '';
return true;
}
});
}
}
export class PathLineTemplate extends JlGraphicTemplate<PathLine> {

View File

@ -52,13 +52,6 @@ export class PathLineDraw extends GraphicDrawAssistant<
this.container.addChild(this.graphic);
PathLinePointsEditPlugin.init(app);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.points = [];
this.graphic.clear();

View File

@ -44,9 +44,6 @@ export class PlatformDraw extends GraphicDrawAssistant<
this.platformGraphic.draw();
this.doorGraphic.draw();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.platformGraphic.clear();

View File

@ -57,13 +57,6 @@ export class PolygonDraw extends GraphicDrawAssistant<
PolygonPointsEditPlugin.init(app);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.points = [];
this.polygonGraphic.clear();

View File

@ -24,13 +24,6 @@ export class RectDraw extends GraphicDrawAssistant<RectTemplate, IRectData> {
rectInteraction.init(app);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.rectGraphic.clear();
}

View File

@ -37,6 +37,7 @@ export const runLineConsts = {
runLineWidth: 6,
nameFontSize: 16,
nameOffsetX: 40,
pathLineDistance: 10,
};
export class RunLine extends JlGraphic {
@ -94,9 +95,164 @@ export class RunLine extends JlGraphic {
old.points = points;
this.updateData(old);
}
/**
*
* @param point1
* @param point2
* @returns
*/
getNormalVector(point1: Point, point2: Point): number[] {
const x1 = point1.x,
y1 = point1.y;
const x2 = point2.x,
y2 = point2.y;
const length = Math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2);
return [(y2 - y1) / length, (x1 - x2) / length];
}
/**
*
* @param point
* @param normal
* @param length
* @returns
*/
movePointAlongNormal(point: Point, normal: number[], length: number): Point {
const newPoint = new Point(
point.x + length * normal[0],
point.y + length * normal[1]
);
return newPoint;
}
/**
* 线(线 )
* @param line1
* @param line2
* @returns
*/
getIntersectionPoint(line1: number[], line2: number[]) {
const a1 = line1[0],
b1 = line1[1];
const a2 = line1[2],
b2 = line1[3];
const a3 = line2[0],
b3 = line2[1];
const a4 = line2[2],
b4 = line2[3];
const denominator = (a3 - a4) * (b1 - b2) - (a1 - a2) * (b3 - b4);
if (denominator === 0) {
return new Point(a1, b1);
}
const x =
((a3 - a4) * (a2 * b1 - a1 * b2) - (a1 - a2) * (a4 * b3 - a3 * b4)) /
denominator;
const y =
((b3 - b4) * (b2 * a1 - b1 * a2) - (b1 - b2) * (b4 * a3 - b3 * a4)) /
-denominator;
return new Point(x, y);
}
generatePathLine(pointsUp: Point[], pointsDown: Point[]) {
const app = this.getGraphicApp() as JlDrawApp;
generatePathLine(points: Point[]) {
const pointsUp: Point[] = [];
const pointsDown: Point[] = [];
points.forEach((p, index) => {
// 起始点终止点计算两点法向量 做平移计算,中间点做线段法向量平移就交点
if (index === 0) {
const normalVector = this.getNormalVector(p, points[index + 1]);
const resverNormalVector = [-normalVector[0], -normalVector[1]];
pointsUp.push(
this.movePointAlongNormal(
p,
normalVector,
runLineConsts.pathLineDistance
)
);
pointsDown.push(
this.movePointAlongNormal(
p,
resverNormalVector,
runLineConsts.pathLineDistance
)
);
} else if (index === points.length - 1) {
const normalVector = this.getNormalVector(points[index - 1], p);
const resverNormalVector = [-normalVector[0], -normalVector[1]];
pointsUp.push(
this.movePointAlongNormal(
p,
normalVector,
runLineConsts.pathLineDistance
)
);
pointsDown.push(
this.movePointAlongNormal(
p,
resverNormalVector,
runLineConsts.pathLineDistance
)
);
} else {
const normalVector1 = this.getNormalVector(p, points[index + 1]);
const resverNormalVector1 = [-normalVector1[0], -normalVector1[1]];
const curP1 = this.movePointAlongNormal(
p,
normalVector1,
runLineConsts.pathLineDistance
);
const nextP1 = this.movePointAlongNormal(
points[index + 1],
normalVector1,
runLineConsts.pathLineDistance
);
const resverCurP1 = this.movePointAlongNormal(
p,
resverNormalVector1,
runLineConsts.pathLineDistance
);
const resverNextP1 = this.movePointAlongNormal(
points[index + 1],
resverNormalVector1,
runLineConsts.pathLineDistance
);
const normalVector2 = this.getNormalVector(points[index - 1], p);
const resverNormalVector2 = [-normalVector2[0], -normalVector2[1]];
const curP2 = this.movePointAlongNormal(
p,
normalVector2,
runLineConsts.pathLineDistance
);
const nextP2 = this.movePointAlongNormal(
points[index - 1],
normalVector2,
runLineConsts.pathLineDistance
);
const resverCurP2 = this.movePointAlongNormal(
p,
resverNormalVector2,
runLineConsts.pathLineDistance
);
const resverNextP2 = this.movePointAlongNormal(
points[index - 1],
resverNormalVector2,
runLineConsts.pathLineDistance
);
pointsUp.push(
this.getIntersectionPoint(
[curP1.x, curP1.y, nextP1.x, nextP1.y],
[curP2.x, curP2.y, nextP2.x, nextP2.y]
)
);
pointsDown.push(
this.getIntersectionPoint(
[resverCurP1.x, resverCurP1.y, resverNextP1.x, resverNextP1.y],
[resverCurP2.x, resverCurP2.y, resverNextP2.x, resverNextP2.y]
)
);
}
});
const app = getDrawApp();
if (!app) return;
const pathLineDrawAssistant = app.getDrawAssistant(
PathLine.Type
) as PathLineDraw;

View File

@ -5,6 +5,9 @@ import {
GraphicInteractionPlugin,
linePoint,
GraphicApp,
AbsorbablePosition,
DraggablePoint,
GraphicTransformEvent,
} from 'src/jl-graphic';
import {
IRunLineData,
@ -19,6 +22,7 @@ import {
clearWayPoint,
clearWaypointsConfig,
getWaypointRangeIndex,
ILineGraphic,
} from 'src/jl-graphic/plugins/GraphicEditPlugin';
import {
FederatedPointerEvent,
@ -30,6 +34,7 @@ import {
FederatedMouseEvent,
} from 'pixi.js';
import { ContextMenu } from 'src/jl-graphic/ui/ContextMenu';
import { AbsorbableLine } from 'src/jl-graphic/graphic/AbsorbablePosition';
export interface IRunLineDrawOptions {
newData: () => IRunLineData;
@ -54,12 +59,6 @@ export class RunLineDraw extends GraphicDrawAssistant<
RunLinePointsEditPlugin.init(app);
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.points = [];
this.graphic.clear();
@ -118,6 +117,62 @@ export class RunLineGraphicHitArea implements IHitArea {
}
}
function buildAbsorbablePositions(
runLine: RunLine,
dpIndex: number
): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const canvas = runLine.getCanvas();
if (runLine.linePoints[dpIndex - 1]) {
const preP = runLine.localToCanvasPoint(runLine.linePoints[dpIndex - 1]);
const ala = new AbsorbableLine(
new Point(preP.x, 0),
new Point(preP.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, preP.y),
new Point(canvas.width, preP.y)
);
aps.push(ala);
aps.push(alb);
}
if (runLine.linePoints[dpIndex + 1]) {
const nextP = runLine.localToCanvasPoint(runLine.linePoints[dpIndex + 1]);
const ala = new AbsorbableLine(
new Point(nextP.x, 0),
new Point(nextP.x, canvas.height)
);
const alb = new AbsorbableLine(
new Point(0, nextP.y),
new Point(canvas.width, nextP.y)
);
aps.push(ala);
aps.push(alb);
}
return aps;
}
/**
*
* @param g
* @param dp
* @param index
*/
function onEditPointCreate(
g: ILineGraphic,
dp: DraggablePoint,
index: number
): void {
const runLine = g as RunLine;
dp.on('transformstart', (e: GraphicTransformEvent) => {
if (e.isShift()) {
runLine.getGraphicApp().setOptions({
absorbablePositions: buildAbsorbablePositions(runLine, index),
});
}
});
}
const RunLineEditMenu: ContextMenu = ContextMenu.init({
name: '运行线编辑菜单',
groups: [
@ -202,7 +257,7 @@ export class RunLinePointsEditPlugin extends GraphicInteractionPlugin<RunLine> {
PolylineEditPlugin.Name
);
if (!lep) {
lep = new PolylineEditPlugin(runLine);
lep = new PolylineEditPlugin(runLine, { onEditPointCreate });
runLine.addAssistantAppend(lep);
}
lep.showAll();

View File

@ -6,7 +6,6 @@ import {
JlGraphic,
} from 'src/jl-graphic';
import { ISignalData, Signal, SignalTemplate } from './Signal';
import { SignalData } from 'src/drawApp/graphics/SignalInteraction';
export interface ISignalDrawOptions {
newData: () => ISignalData;
@ -33,19 +32,12 @@ export class SignalDraw extends GraphicDrawAssistant<
public get signal(): Signal {
if (!this._signal) {
this._signal = this.graphicTemplate.new();
this.signal.loadData(new SignalData());
this.signal.loadData(this.createGraphicData());
this.container.addChild(this.signal);
}
return this._signal;
}
bind(): void {
super.bind();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
//this.codeGraph.clear();
}
@ -88,7 +80,7 @@ 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);
@ -103,7 +95,7 @@ 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

@ -33,13 +33,9 @@ export class StationDraw extends GraphicDrawAssistant<
bind(): void {
super.bind();
const data = { graphicType: 'station' } as GraphicData;
this.codeGraph.loadData(data);
this.codeGraph.loadData(this.createGraphicData());
this.codeGraph.doRepaint();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
//this.codeGraph.destroy();

View File

@ -19,13 +19,13 @@ export interface IStationLineData extends GraphicData {
const stationConsts = {
radius: 5,
borderWidth: 1,
borderColor: '0xff0000',
fillColor: '0xff0000',
borderColor: '0xffffff',
fillColor: '0xffffff',
transferRadius: 3.5,
transferWidth: 0.2,
transferColor: '0x0fe81f',
transferWidth: 0.4,
transferColor: '0xff0000',
codeColor: '0xF48815',
codeFontSize: 22,
codeFontSize: 10,
codeOffsetY: 20,
};
//子元素--圆点

View File

@ -1,5 +1,7 @@
import { FederatedPointerEvent, Point } from 'pixi.js';
import {
AbsorbableLine,
AbsorbablePosition,
GraphicData,
GraphicDrawAssistant,
GraphicInteractionPlugin,
@ -12,6 +14,7 @@ import {
StationLine,
StationLineTemplate,
} from './StationLine';
import { RunLine } from '../runLine/RunLine';
export interface IStationLineDrawOptions {
newData: () => IStationLineData;
@ -37,13 +40,9 @@ export class StationLineDraw extends GraphicDrawAssistant<
bind(): void {
super.bind();
const data = { graphicType: 'stationLine' } as GraphicData;
this.codeGraph.loadData(data);
this.codeGraph.loadData(this.createGraphicData());
this.codeGraph.doRepaint();
}
unbind(): void {
super.unbind();
}
clearCache(): void {
//this.codeGraph.destroy();
@ -64,8 +63,26 @@ export class StationLineDraw extends GraphicDrawAssistant<
}
}
/**
*
* @param polygon
* @returns
*/
function buildAbsorbablePositions(Station: StationLine): AbsorbablePosition[] {
const aps: AbsorbablePosition[] = [];
const runLines = Station.queryStore.queryByType<RunLine>(RunLine.Type);
runLines.forEach((runLine) => {
const points = runLine.datas.points;
for (let i = 0; i < points.length - 1; i++) {
aps.push(new AbsorbableLine(points[i], points[i + 1]));
}
});
return aps;
}
export class stationLineInteraction extends GraphicInteractionPlugin<StationLine> {
static Name = 'stationLine_transform';
static stationLine: StationLine;
constructor(app: JlDrawApp) {
super(stationLineInteraction.Name, app);
}
@ -78,6 +95,7 @@ export class stationLineInteraction extends GraphicInteractionPlugin<StationLine
.map((g) => g as StationLine);
}
bind(g: StationLine): void {
stationLineInteraction.stationLine = g;
g.eventMode = 'static';
g.cursor = 'pointer';
g.scalable = true;
@ -87,6 +105,7 @@ export class stationLineInteraction extends GraphicInteractionPlugin<StationLine
g.codeGraph.draggable = true;
g.codeGraph.selectable = true;
g.codeGraph.transformSave = true;
g.on('selected', this.onSelected, this);
}
unbind(g: StationLine): void {
g.eventMode = 'none';
@ -97,4 +116,11 @@ export class stationLineInteraction extends GraphicInteractionPlugin<StationLine
g.codeGraph.selectable = false;
g.codeGraph.transformSave = false;
}
onSelected(): void {
this.app.setOptions({
absorbablePositions: buildAbsorbablePositions(
stationLineInteraction.stationLine
),
});
}
}

View File

@ -49,10 +49,6 @@ export class TrainDraw extends GraphicDrawAssistant<TrainTemplate, ITrainData> {
this.headLeft.doRepaint(bodyWH);
}
unbind(): void {
super.unbind();
}
clearCache(): void {
this.headLeft.clear();
this.trainbody.clear();

View File

@ -19,7 +19,7 @@ export class TrainLine extends JlGraphic {
this.train = new Sprite();
this.train.texture = this.trainTextures;
this.train.anchor.set(0.5);
this.train.scale.set(0.1, 0.1);
this.train.scale.set(0.02, 0.02);
this.addChild(this.train);
}
doRepaint(): void {

View File

@ -194,18 +194,17 @@ export class CommonMouseTool extends AppInteractionPlugin {
const graphic = this.leftDownTarget.getGraphic();
if (graphic) {
const app = this.app;
console.log(this.leftDownTarget.isGraphic());
// 图形选中
if (!e.ctrlKey && !graphic.selected && graphic.selectable) {
app.updateSelected(graphic);
graphic.childEdit = false;
this.graphicSelect = true;
} else if (
!e.ctrlKey &&
graphic.selected &&
graphic.childEdit &&
this.leftDownTarget.isGraphicChild()
) {
if (this.leftDownTarget.selectable) {
} else if (!e.ctrlKey && graphic.selected && graphic.childEdit) {
if (
this.leftDownTarget.isGraphicChild() &&
this.leftDownTarget.selectable
) {
graphic.setChildSelected(this.leftDownTarget);
} else {
graphic.exitChildEdit();

View File

@ -255,9 +255,10 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
targets.forEach((target) => {
if (target.shiftStartPoint) {
target.shiftLastPoint = target.position.clone();
const { dx, dy } = e.toTargetShiftLen(target.parent);
target.position.set(
target.shiftStartPoint.x + e.dsx,
target.shiftStartPoint.y + e.dsy
target.shiftStartPoint.x + dx,
target.shiftStartPoint.y + dy
);
}
});
@ -460,6 +461,14 @@ export class TransformPoints extends Container {
this.addChild(this.lScalePoint);
this.obj.on('transformstart', this.onObjTransformStart, this);
this.obj.on('transformend', this.onObjTransformEnd, this);
if (this.obj.children && this.obj.children.length > 0) {
recursiveChildren(this.obj as Container, (child) => {
child.on('transformstart', this.onObjTransformStart, this);
child.on('transformend', this.onObjTransformEnd, this);
});
}
this.obj.on('repaint', this.onGraphicRepaint, this);
this.children.forEach((dp) => {
dp.on('transformstart', this.onScaleDragStart, this);
@ -529,7 +538,8 @@ export class TransformPoints extends Container {
// 旋转角度计算逻辑取锚点y负方向一点作为旋转点求旋转点和锚点所形成的直线与x轴角度此角度+90°即为最终旋转角度再将旋转角度限制到(-180,180]之间
let angle = angleToAxisx(this.rotatePivot, de.target.position);
angle = Math.floor(angle / this.angleStep) * this.angleStep;
angle = (angle + 90) % 360;
const parentAngle = this.obj.parent.worldAngle;
angle = (angle + 90 - parentAngle) % 360;
if (angle > 180) {
angle = angle - 360;
}
@ -789,6 +799,12 @@ export class BoundsGraphic extends Graphics {
this.visible = false;
this.obj.on('transformstart', this.onObjTransformStart, this);
this.obj.on('transformend', this.onObjTransformEnd, this);
if (this.obj.children && this.obj.children.length > 0) {
recursiveChildren(this.obj as Container, (child) => {
child.on('transformstart', this.onObjTransformStart, this);
child.on('transformend', this.onObjTransformEnd, this);
});
}
this.obj.on('repaint', this.onGraphicRepaint, this);
graphic.addAssistantAppend(this);
}

View File

@ -99,7 +99,7 @@ export class AppDragEvent {
type: 'start' | 'move' | 'end';
target: DisplayObject;
original: FederatedPointerEvent;
start: Point;
start: Point; // 画布坐标
constructor(
app: GraphicApp,
type: 'start' | 'move' | 'end',
@ -146,6 +146,9 @@ export class AppDragEvent {
return this.original.pointerType === 'touch';
}
/**
* ()
*/
public get end(): Point {
return this.app.toCanvasCoordinates(this.original.global);
}
@ -167,6 +170,15 @@ export class AppDragEvent {
public get dsy(): number {
return this.end.y - this.start.y;
}
/**
*
*/
toTargetShiftLen(target: DisplayObject): { dx: number; dy: number } {
const sl = target.canvasToLocalPoint(this.start);
const el = target.canvasToLocalPoint(this.end);
return { dx: el.x - sl.x, dy: el.y - sl.y };
}
}
/**

View File

@ -0,0 +1,58 @@
<template>
<q-layout view="hHh LpR fFf">
<q-header reveal class="bg-primary text-white"></q-header>
<q-page-container>
<div id="line-app-container"></div>
</q-page-container>
</q-layout>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { useLineStore } from 'src/stores/line-store';
import { useRoute } from 'vue-router';
import { loadLineDatas, getLineApp } from 'src/drawApp/lineApp';
const lineStore = useLineStore();
const canvasWidth = ref(0);
const canvasHeight = ref(0);
const headerHeight = ref(0);
const leftWidth = ref(0);
const rightWidth = ref(0);
const leftDrawerOpen = ref(false);
const rightDrawerOpen = ref(false);
function onResize() {
const clientWidth = document.body.clientWidth;
const clientHeight = document.body.clientHeight;
canvasWidth.value =
clientWidth -
(leftDrawerOpen.value ? leftWidth.value : 0) -
(rightDrawerOpen.value ? rightWidth.value : 0);
canvasHeight.value = clientHeight - headerHeight.value;
const dom = document.getElementById('line-app-container');
if (dom) {
dom.style.width = canvasWidth.value + 'px';
dom.style.height = canvasHeight.value + 'px';
}
const drawApp = getLineApp();
if (drawApp) {
drawApp.onDomResize(canvasWidth.value, canvasHeight.value);
}
}
onMounted(() => {
const dom = document.getElementById('draw-app-container');
if (dom) {
const route = useRoute();
lineStore.setLineId(+route.params.id as number);
const lineApp = lineStore.initLineApp(dom);
console.log('1111111111');
loadLineDatas(lineApp);
onResize();
} else {
lineStore.setLineId(null);
}
});
</script>

View File

@ -1,5 +1,6 @@
<template>
<div class="q-pa-md">
<!-- <q-btn @click="goMap">测试</q-btn> -->
<q-table
ref="tableRef"
title="发布图"
@ -44,6 +45,8 @@
import { ref, reactive, onMounted, computed } from 'vue';
import { useQuasar, type QTableColumn, QForm } from 'quasar';
import { pageQuery, deletePublish } from '../api/PublishApi';
import { useRouter } from 'vue-router';
const router = useRouter();
const $q = useQuasar();
@ -134,6 +137,10 @@ async function onRequest(props: any) {
}
}
function goMap() {
router.push('/linemap/7');
}
async function deleteData(row: any) {
operateDisabled.value = true;
$q.dialog({

View File

@ -61,6 +61,11 @@ const routes: RouteRecordRaw[] = [
name: 'painting',
component: () => import('layouts/DrawLayout.vue'),
},
{
path: '/linemap/:id',
name: 'linemap',
component: () => import('layouts/LineLayout.vue'),
},
// Always leave this as last one,
// but you can also remove it

46
src/stores/line-store.ts Normal file
View File

@ -0,0 +1,46 @@
import { defineStore } from 'pinia';
import { JlCanvas, JlGraphic, GraphicApp } from 'src/jl-graphic';
import { initLineApp, getLineApp, destroyLineApp } from 'src/drawApp/lineApp';
export const useLineStore = defineStore('line', {
state: () => ({
selectedGraphics: null as JlGraphic[] | null,
lineId: null as number | null,
}),
getters: {
selectedGraphicType: (state) => {
if (state.selectedGraphics) {
if (state.selectedGraphics.length === 1) {
return state.selectedGraphics[0].type;
}
}
},
},
actions: {
getLineApp(): GraphicApp {
const app = getLineApp();
if (app == null) {
throw new Error('未初始化app');
}
return app;
},
getJlCanvas(): JlCanvas {
return this.getLineApp().canvas;
},
initLineApp(dom: HTMLElement) {
const app = initLineApp(dom);
app.on('graphicselectedchange', () => {
this.selectedGraphics = app.selectedGraphics;
});
this.selectedGraphics = [];
return app;
},
destroy() {
this.selectedGraphics = null;
destroyLineApp();
},
setLineId(id: number | null) {
this.lineId = id;
},
},
});