diff --git a/graphic-pixi b/graphic-pixi index 988599c..8762ced 160000 --- a/graphic-pixi +++ b/graphic-pixi @@ -1 +1 @@ -Subproject commit 988599cd62fce00d3bde9a87f851505d97423b90 +Subproject commit 8762ced5f8592db84ed19490cdb6c0322df874d8 diff --git a/src/components/draw-app/properties/RunLineProperty.vue b/src/components/draw-app/properties/RunLineProperty.vue index e33f4f9..a97d6ab 100644 --- a/src/components/draw-app/properties/RunLineProperty.vue +++ b/src/components/draw-app/properties/RunLineProperty.vue @@ -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); } } diff --git a/src/components/draw-app/properties/StationLineProperty.vue b/src/components/draw-app/properties/StationLineProperty.vue index b23ed30..951e567 100644 --- a/src/components/draw-app/properties/StationLineProperty.vue +++ b/src/components/draw-app/properties/StationLineProperty.vue @@ -10,9 +10,11 @@ (); diff --git a/src/drawApp/graphics/SectionInteraction.ts b/src/drawApp/graphics/SectionInteraction.ts index 88f898a..9fc817e 100644 --- a/src/drawApp/graphics/SectionInteraction.ts +++ b/src/drawApp/graphics/SectionInteraction.ts @@ -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; diff --git a/src/drawApp/graphics/SignalInteraction.ts b/src/drawApp/graphics/SignalInteraction.ts index 98f2853..111640c 100644 --- a/src/drawApp/graphics/SignalInteraction.ts +++ b/src/drawApp/graphics/SignalInteraction.ts @@ -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 { diff --git a/src/drawApp/graphics/StationInteraction.ts b/src/drawApp/graphics/StationInteraction.ts index 5ead4fb..0170926 100644 --- a/src/drawApp/graphics/StationInteraction.ts +++ b/src/drawApp/graphics/StationInteraction.ts @@ -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; diff --git a/src/drawApp/graphics/StationLineInteraction.ts b/src/drawApp/graphics/StationLineInteraction.ts index 03ee132..e333a3c 100644 --- a/src/drawApp/graphics/StationLineInteraction.ts +++ b/src/drawApp/graphics/StationLineInteraction.ts @@ -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; diff --git a/src/drawApp/graphics/TrainInteraction.ts b/src/drawApp/graphics/TrainInteraction.ts index a6009a9..cf44b79 100644 --- a/src/drawApp/graphics/TrainInteraction.ts +++ b/src/drawApp/graphics/TrainInteraction.ts @@ -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; diff --git a/src/drawApp/graphics/TrainLineInteraction.ts b/src/drawApp/graphics/TrainLineInteraction.ts index 44e82de..41eff75 100644 --- a/src/drawApp/graphics/TrainLineInteraction.ts +++ b/src/drawApp/graphics/TrainLineInteraction.ts @@ -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); diff --git a/src/drawApp/graphics/TurnoutInteraction.ts b/src/drawApp/graphics/TurnoutInteraction.ts index f390b41..7c13bbb 100644 --- a/src/drawApp/graphics/TurnoutInteraction.ts +++ b/src/drawApp/graphics/TurnoutInteraction.ts @@ -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; diff --git a/src/drawApp/lineApp.ts b/src/drawApp/lineApp.ts new file mode 100644 index 0000000..6cca605 --- /dev/null +++ b/src/drawApp/lineApp.ts @@ -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([]); + } +} diff --git a/src/graphics/pathLine/PathLine.ts b/src/graphics/pathLine/PathLine.ts index 2e52ce4..55d7f6f 100644 --- a/src/graphics/pathLine/PathLine.ts +++ b/src/graphics/pathLine/PathLine.ts @@ -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 { diff --git a/src/graphics/pathLine/PathLineDrawAssistant.ts b/src/graphics/pathLine/PathLineDrawAssistant.ts index eba1be1..5057746 100644 --- a/src/graphics/pathLine/PathLineDrawAssistant.ts +++ b/src/graphics/pathLine/PathLineDrawAssistant.ts @@ -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(); diff --git a/src/graphics/platform/PlatformDrawAssistant.ts b/src/graphics/platform/PlatformDrawAssistant.ts index af080cf..b9e600c 100644 --- a/src/graphics/platform/PlatformDrawAssistant.ts +++ b/src/graphics/platform/PlatformDrawAssistant.ts @@ -44,9 +44,6 @@ export class PlatformDraw extends GraphicDrawAssistant< this.platformGraphic.draw(); this.doorGraphic.draw(); } - unbind(): void { - super.unbind(); - } clearCache(): void { this.platformGraphic.clear(); diff --git a/src/graphics/polygon/PolygonDrawAssistant.ts b/src/graphics/polygon/PolygonDrawAssistant.ts index 798f0d6..636b3cf 100644 --- a/src/graphics/polygon/PolygonDrawAssistant.ts +++ b/src/graphics/polygon/PolygonDrawAssistant.ts @@ -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(); diff --git a/src/graphics/rect/RectDrawAssistant.ts b/src/graphics/rect/RectDrawAssistant.ts index ab5a7ce..c7a5f83 100644 --- a/src/graphics/rect/RectDrawAssistant.ts +++ b/src/graphics/rect/RectDrawAssistant.ts @@ -24,13 +24,6 @@ export class RectDraw extends GraphicDrawAssistant { rectInteraction.init(app); } - bind(): void { - super.bind(); - } - unbind(): void { - super.unbind(); - } - clearCache(): void { this.rectGraphic.clear(); } diff --git a/src/graphics/runLine/RunLine.ts b/src/graphics/runLine/RunLine.ts index ae6d8fa..98ca1b9 100644 --- a/src/graphics/runLine/RunLine.ts +++ b/src/graphics/runLine/RunLine.ts @@ -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; diff --git a/src/graphics/runLine/RunLineDrawAssistant.ts b/src/graphics/runLine/RunLineDrawAssistant.ts index 38a9f95..a095867 100644 --- a/src/graphics/runLine/RunLineDrawAssistant.ts +++ b/src/graphics/runLine/RunLineDrawAssistant.ts @@ -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 { PolylineEditPlugin.Name ); if (!lep) { - lep = new PolylineEditPlugin(runLine); + lep = new PolylineEditPlugin(runLine, { onEditPointCreate }); runLine.addAssistantAppend(lep); } lep.showAll(); diff --git a/src/graphics/signal/SignalDrawAssistant.ts b/src/graphics/signal/SignalDrawAssistant.ts index 2e84440..0b76e8e 100644 --- a/src/graphics/signal/SignalDrawAssistant.ts +++ b/src/graphics/signal/SignalDrawAssistant.ts @@ -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 { 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 { 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'; } diff --git a/src/graphics/station/StationDrawAssistant.ts b/src/graphics/station/StationDrawAssistant.ts index d65975f..4e72fdb 100644 --- a/src/graphics/station/StationDrawAssistant.ts +++ b/src/graphics/station/StationDrawAssistant.ts @@ -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(); diff --git a/src/graphics/stationLine/StationLine.ts b/src/graphics/stationLine/StationLine.ts index 6ae0d79..9ab12e4 100644 --- a/src/graphics/stationLine/StationLine.ts +++ b/src/graphics/stationLine/StationLine.ts @@ -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, }; //子元素--圆点 diff --git a/src/graphics/stationLine/StationLineDrawAssistant.ts b/src/graphics/stationLine/StationLineDrawAssistant.ts index 30b62e5..0aad6da 100644 --- a/src/graphics/stationLine/StationLineDrawAssistant.ts +++ b/src/graphics/stationLine/StationLineDrawAssistant.ts @@ -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.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 { static Name = 'stationLine_transform'; + static stationLine: StationLine; constructor(app: JlDrawApp) { super(stationLineInteraction.Name, app); } @@ -78,6 +95,7 @@ export class stationLineInteraction extends GraphicInteractionPlugin 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 { this.headLeft.doRepaint(bodyWH); } - unbind(): void { - super.unbind(); - } - clearCache(): void { this.headLeft.clear(); this.trainbody.clear(); diff --git a/src/graphics/trainLine/TrainLine.ts b/src/graphics/trainLine/TrainLine.ts index 6d207e2..5732d4a 100644 --- a/src/graphics/trainLine/TrainLine.ts +++ b/src/graphics/trainLine/TrainLine.ts @@ -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 { diff --git a/src/jl-graphic/plugins/CommonMousePlugin.ts b/src/jl-graphic/plugins/CommonMousePlugin.ts index 5160f41..bdd8747 100644 --- a/src/jl-graphic/plugins/CommonMousePlugin.ts +++ b/src/jl-graphic/plugins/CommonMousePlugin.ts @@ -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(); diff --git a/src/jl-graphic/plugins/GraphicTransformPlugin.ts b/src/jl-graphic/plugins/GraphicTransformPlugin.ts index cbc3cbd..369d55b 100644 --- a/src/jl-graphic/plugins/GraphicTransformPlugin.ts +++ b/src/jl-graphic/plugins/GraphicTransformPlugin.ts @@ -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); } diff --git a/src/jl-graphic/plugins/InteractionPlugin.ts b/src/jl-graphic/plugins/InteractionPlugin.ts index 34a5f5e..70226d6 100644 --- a/src/jl-graphic/plugins/InteractionPlugin.ts +++ b/src/jl-graphic/plugins/InteractionPlugin.ts @@ -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 }; + } } /** diff --git a/src/layouts/LineLayout.vue b/src/layouts/LineLayout.vue new file mode 100644 index 0000000..9307193 --- /dev/null +++ b/src/layouts/LineLayout.vue @@ -0,0 +1,58 @@ + + + diff --git a/src/pages/PublishManage.vue b/src/pages/PublishManage.vue index 5367708..1102de3 100644 --- a/src/pages/PublishManage.vue +++ b/src/pages/PublishManage.vue @@ -1,5 +1,6 @@