rt-graphic-component/components/Signal/bjRtss/SignalDrawAssistant.js
2024-01-02 14:36:14 +08:00

141 lines
4.4 KiB
JavaScript

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 };