import { Point } from 'pixi.js'; import { GraphicDrawAssistant, GraphicInteractionPlugin, AbsorbableLine } from 'jl-graphic'; import { Signal } from './Signal.js'; class SignalDraw extends GraphicDrawAssistant { _signal = null; constructor(app, template) { super(app, template, 'svguse: ../../drawIcon.svg#icon-signal', '信号机Signal'); SignalInteraction.init(app); } get signal() { if (!this._signal) { this._signal = this.graphicTemplate.new(); this._signal.loadData(this.graphicTemplate.datas); this.container.addChild(this._signal); } return this._signal; } onLeftUp(e) { this.container.position.copyFrom(this.toCanvasCoordinates(e.global)); this.createAndStore(true); } redraw(p) { this.signal.paint(); this.container.position.set(p.x, p.y); } prepareData(data) { data.transform = this.container.saveTransform(); return true; } } class SignalGraphicHitArea { signal; constructor(signal) { this.signal = signal; } contains(x, y) { const bound = this.signal.getLocalBounds(); const maxX = bound.x + bound.width; const minX = bound.x; const maxY = bound.y + bound.height; const minY = bound.y; return maxX >= x && x >= minX && maxY >= y && y >= minY; } } /** * 构建吸附线 * @param signal */ function buildAbsorbablePositions(signal) { const aps = []; const signals = signal.queryStore.queryByType(Signal.Type); const canvas = signal.getCanvas(); signals.forEach((item) => { if (item.id === signal.id) { return; } const ala = new AbsorbableLine(new Point(item.x, 0), new Point(item.x, canvas.height)); const alb = new AbsorbableLine(new Point(0, item.y), new Point(canvas.width, item.y)); aps.push(ala); aps.push(alb); }); return aps; } /** * 信号机名称构建吸附线 * @param signal */ function buildCodeAbsorbablePositions(signal) { const aps = []; const signals = signal.queryStore.queryByType(Signal.Type); const canvas = signal.getCanvas(); signals.forEach((item) => { if (item.id === signal.id) { return; } const codePoint = item.signalCode.getPositionOnCanvas(); const ala = new AbsorbableLine(new Point(codePoint.x, 0), new Point(codePoint.x, canvas.height)); const alb = new AbsorbableLine(new Point(0, codePoint.y), new Point(canvas.width, codePoint.y)); aps.push(ala); aps.push(alb); }); return aps; } class SignalInteraction extends GraphicInteractionPlugin { static Name = 'signal_transform'; constructor(app) { super(SignalInteraction.Name, app); } static init(app) { return new SignalInteraction(app); } filter(...grahpics) { return grahpics .filter((g) => g.type === Signal.Type) .map((g) => g); } bind(g) { g.eventMode = 'static'; g.cursor = 'pointer'; g.scalable = true; g.rotatable = true; g.lampMainBody.hitArea = new SignalGraphicHitArea(g); g.on('transformstart', this.transformstart, this); g.signalCode.on('transformstart', this.codetransformstart, this); g.signalCode.draggable = true; g.signalCode.selectable = true; g.signalCode.rotatable = true; g.signalCode.transformSave = true; g.signalCode.eventMode = 'static'; } unbind(g) { g.eventMode = 'none'; g.scalable = false; g.rotatable = false; g.off('transformstart', this.transformstart, this); g.signalCode.off('transformstart', this.codetransformstart, this); g.signalCode.draggable = false; g.signalCode.selectable = false; g.signalCode.rotatable = false; g.signalCode.transformSave = false; g.signalCode.eventMode = 'none'; } transformstart(e) { const target = e.target; const signal = target.getGraphic(); signal.getGraphicApp().setOptions({ absorbablePositions: buildAbsorbablePositions(signal), }); } codetransformstart(e) { const target = e.target; const signal = target.getGraphic(); signal.getGraphicApp().setOptions({ absorbablePositions: buildCodeAbsorbablePositions(signal), }); } } export { SignalDraw, SignalGraphicHitArea, SignalInteraction };