可吸附位置功能调整:所有位置都执行吸附,所有图形也都执行吸附(之前一个吸附成功就返回了)
添加过滤重复的可吸附位置对象逻辑
This commit is contained in:
parent
533ebdc9a8
commit
ecfe1421bb
@ -1,7 +1,10 @@
|
|||||||
import { FederatedMouseEvent, Point } from 'pixi.js';
|
import { FederatedMouseEvent, Point } from 'pixi.js';
|
||||||
import {
|
import {
|
||||||
|
AbsorbableLine,
|
||||||
|
AbsorbablePosition,
|
||||||
GraphicDrawAssistant,
|
GraphicDrawAssistant,
|
||||||
GraphicInteractionPlugin,
|
GraphicInteractionPlugin,
|
||||||
|
GraphicTransformEvent,
|
||||||
JlDrawApp,
|
JlDrawApp,
|
||||||
JlGraphic,
|
JlGraphic,
|
||||||
} from 'src/jlgraphic';
|
} from 'src/jlgraphic';
|
||||||
@ -68,6 +71,16 @@ export class IscsFanInteraction extends GraphicInteractionPlugin<IscsFan> {
|
|||||||
g.cursor = 'pointer';
|
g.cursor = 'pointer';
|
||||||
// g.scalable = true;
|
// g.scalable = true;
|
||||||
g.rotatable = true;
|
g.rotatable = true;
|
||||||
|
g.on('drag-start', () => {
|
||||||
|
console.log('风机拖拽');
|
||||||
|
});
|
||||||
|
g.on('transformstart', (e: GraphicTransformEvent) => {
|
||||||
|
if (e.isShift()) {
|
||||||
|
g.getGraphicApp().setOptions({
|
||||||
|
absorbablePositions: buildAbsorbablePositions(g),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
unbind(g: IscsFan): void {
|
unbind(g: IscsFan): void {
|
||||||
g.eventMode = 'none';
|
g.eventMode = 'none';
|
||||||
@ -75,3 +88,23 @@ export class IscsFanInteraction extends GraphicInteractionPlugin<IscsFan> {
|
|||||||
g.rotatable = false;
|
g.rotatable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildAbsorbablePositions(
|
||||||
|
g: IscsFan
|
||||||
|
): AbsorbablePosition[] | undefined {
|
||||||
|
const app = g.getGraphicApp();
|
||||||
|
const canvas = app.canvas;
|
||||||
|
const store = app.queryStore;
|
||||||
|
const aps: AbsorbablePosition[] = [];
|
||||||
|
store.queryByType(IscsFan.Type).forEach((fan) => {
|
||||||
|
if (fan.id === g.id) return;
|
||||||
|
const p = fan.position;
|
||||||
|
aps.push(
|
||||||
|
new AbsorbableLine(new Point(0, p.y), new Point(canvas.width, p.y))
|
||||||
|
);
|
||||||
|
aps.push(
|
||||||
|
new AbsorbableLine(new Point(p.x, 0), new Point(p.x, canvas.height))
|
||||||
|
);
|
||||||
|
});
|
||||||
|
return aps;
|
||||||
|
}
|
||||||
|
@ -288,6 +288,7 @@ export interface GraphicAppEvents extends GlobalMixins.GraphicAppEvents {
|
|||||||
drag_op_end: [event: AppDragEvent];
|
drag_op_end: [event: AppDragEvent];
|
||||||
'pre-menu-handle': [menu: MenuItemOptions];
|
'pre-menu-handle': [menu: MenuItemOptions];
|
||||||
'post-menu-handle': [menu: MenuItemOptions];
|
'post-menu-handle': [menu: MenuItemOptions];
|
||||||
|
'websocket-state-change': [app: GraphicApp, connected: boolean];
|
||||||
destroy: [app: GraphicApp];
|
destroy: [app: GraphicApp];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -888,10 +889,10 @@ export class GraphicApp extends EventEmitter<GraphicAppEvents> {
|
|||||||
this.emit('destroy', this);
|
this.emit('destroy', this);
|
||||||
if (this.wsMsgBroker) {
|
if (this.wsMsgBroker) {
|
||||||
this.wsMsgBroker.close();
|
this.wsMsgBroker.close();
|
||||||
if (!StompCli.hasAppMsgBroker()) {
|
// if (!StompCli.hasAppMsgBroker()) {
|
||||||
// 如果没有其他消息代理,关闭websocket Stomp客户端
|
// // 如果没有其他消息代理,关闭websocket Stomp客户端
|
||||||
StompCli.close();
|
// StompCli.close();
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
this.interactionPluginMap.forEach((plugin) => {
|
this.interactionPluginMap.forEach((plugin) => {
|
||||||
plugin.pause();
|
plugin.pause();
|
||||||
|
@ -11,6 +11,8 @@ import {
|
|||||||
calculateFootPointFromPointToLine,
|
calculateFootPointFromPointToLine,
|
||||||
calculateIntersectionPointOfCircleAndPoint,
|
calculateIntersectionPointOfCircleAndPoint,
|
||||||
distance,
|
distance,
|
||||||
|
distance2,
|
||||||
|
isLineContainOther,
|
||||||
linePoint,
|
linePoint,
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { VectorGraphic, VectorGraphicUtil } from './VectorGraphic';
|
import { VectorGraphic, VectorGraphicUtil } from './VectorGraphic';
|
||||||
@ -19,12 +21,25 @@ import { VectorGraphic, VectorGraphicUtil } from './VectorGraphic';
|
|||||||
* 抽象可吸附位置
|
* 抽象可吸附位置
|
||||||
*/
|
*/
|
||||||
export interface AbsorbablePosition extends Container {
|
export interface AbsorbablePosition extends Container {
|
||||||
|
/**
|
||||||
|
* 是否与另一个可吸附位置重叠(相似,但可能范围不同)
|
||||||
|
* @param other
|
||||||
|
*/
|
||||||
|
isOverlapping(other: AbsorbablePosition): boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 与另一个相似的吸附位置比较范围大小
|
||||||
|
* @param other
|
||||||
|
* @returns >0此吸附范围大,<0另一个吸附范围大,=0两个吸附范围一样大
|
||||||
|
*/
|
||||||
|
compareTo(other: AbsorbablePosition): number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 尝试吸附图形对象
|
* 尝试吸附图形对象
|
||||||
* @param objs 图形对象列表
|
* @param objs 图形对象列表
|
||||||
* @returns 如果吸附成功,返回true,否则false
|
* @returns 如果吸附成功,返回true,否则false
|
||||||
*/
|
*/
|
||||||
tryAbsorb(...objs: DisplayObject[]): boolean;
|
tryAbsorb(...objs: DisplayObject[]): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +80,22 @@ export default class AbsorbablePoint
|
|||||||
this.interactive;
|
this.interactive;
|
||||||
VectorGraphicUtil.handle(this);
|
VectorGraphicUtil.handle(this);
|
||||||
}
|
}
|
||||||
tryAbsorb(...objs: DisplayObject[]): boolean {
|
compareTo(other: AbsorbablePosition): number {
|
||||||
|
if (other instanceof AbsorbablePoint) {
|
||||||
|
return this.absorbRange - other.absorbRange;
|
||||||
|
}
|
||||||
|
throw new Error('非可吸附点');
|
||||||
|
}
|
||||||
|
isOverlapping(other: AbsorbablePosition): boolean {
|
||||||
|
if (other instanceof AbsorbablePoint) {
|
||||||
|
return (
|
||||||
|
this._point.equals(other._point) &&
|
||||||
|
this.absorbRange === other.absorbRange
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tryAbsorb(...objs: DisplayObject[]): void {
|
||||||
for (let i = 0; i < objs.length; i++) {
|
for (let i = 0; i < objs.length; i++) {
|
||||||
const obj = objs[i];
|
const obj = objs[i];
|
||||||
if (
|
if (
|
||||||
@ -73,10 +103,8 @@ export default class AbsorbablePoint
|
|||||||
this.absorbRange
|
this.absorbRange
|
||||||
) {
|
) {
|
||||||
obj.position.copyFrom(this._point);
|
obj.position.copyFrom(this._point);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
updateOnScaled() {
|
updateOnScaled() {
|
||||||
const scaled = this.getAllParentScaled();
|
const scaled = this.getAllParentScaled();
|
||||||
@ -101,6 +129,22 @@ export class AbsorbableLine extends Graphics implements AbsorbablePosition {
|
|||||||
this.absorbRange = absorbRange;
|
this.absorbRange = absorbRange;
|
||||||
this.redraw();
|
this.redraw();
|
||||||
}
|
}
|
||||||
|
isOverlapping(other: AbsorbablePosition): boolean {
|
||||||
|
if (other instanceof AbsorbableLine) {
|
||||||
|
const contain = isLineContainOther(
|
||||||
|
{ p1: this.p1, p2: this.p2 },
|
||||||
|
{ p1: other.p1, p2: other.p2 }
|
||||||
|
);
|
||||||
|
return contain;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
compareTo(other: AbsorbablePosition): number {
|
||||||
|
if (other instanceof AbsorbableLine) {
|
||||||
|
return distance2(this.p1, this.p2) - distance2(other.p1, other.p2);
|
||||||
|
}
|
||||||
|
throw new Error('非可吸附线');
|
||||||
|
}
|
||||||
redraw() {
|
redraw() {
|
||||||
this.clear();
|
this.clear();
|
||||||
this.lineStyle(1, new Color(this._color));
|
this.lineStyle(1, new Color(this._color));
|
||||||
@ -108,17 +152,15 @@ export class AbsorbableLine extends Graphics implements AbsorbablePosition {
|
|||||||
this.lineTo(this.p2.x, this.p2.y);
|
this.lineTo(this.p2.x, this.p2.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
tryAbsorb(...objs: DisplayObject[]): boolean {
|
tryAbsorb(...objs: DisplayObject[]): void {
|
||||||
for (let i = 0; i < objs.length; i++) {
|
for (let i = 0; i < objs.length; i++) {
|
||||||
const obj = objs[i];
|
const obj = objs[i];
|
||||||
const p = obj.position.clone();
|
const p = obj.position.clone();
|
||||||
if (linePoint(this.p1, this.p2, p, this.absorbRange, true)) {
|
if (linePoint(this.p1, this.p2, p, this.absorbRange, true)) {
|
||||||
const fp = calculateFootPointFromPointToLine(this.p1, this.p2, p);
|
const fp = calculateFootPointFromPointToLine(this.p1, this.p2, p);
|
||||||
obj.position.copyFrom(fp);
|
obj.position.copyFrom(fp);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +180,18 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition {
|
|||||||
this.absorbRange = absorbRange;
|
this.absorbRange = absorbRange;
|
||||||
this.redraw();
|
this.redraw();
|
||||||
}
|
}
|
||||||
|
isOverlapping(other: AbsorbablePosition): boolean {
|
||||||
|
if (other instanceof AbsorbableCircle) {
|
||||||
|
return this.p0.equals(other.p0) && this.radius === other.radius;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
compareTo(other: AbsorbablePosition): number {
|
||||||
|
if (other instanceof AbsorbableCircle) {
|
||||||
|
return this.absorbRange - other.absorbRange;
|
||||||
|
}
|
||||||
|
throw new Error('非可吸附圆');
|
||||||
|
}
|
||||||
|
|
||||||
redraw() {
|
redraw() {
|
||||||
this.clear();
|
this.clear();
|
||||||
@ -145,7 +199,7 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition {
|
|||||||
this.drawCircle(this.p0.x, this.p0.y, this.radius);
|
this.drawCircle(this.p0.x, this.p0.y, this.radius);
|
||||||
}
|
}
|
||||||
|
|
||||||
tryAbsorb(...objs: DisplayObject[]): boolean {
|
tryAbsorb(...objs: DisplayObject[]): void {
|
||||||
for (let i = 0; i < objs.length; i++) {
|
for (let i = 0; i < objs.length; i++) {
|
||||||
const obj = objs[i];
|
const obj = objs[i];
|
||||||
const len = distance(
|
const len = distance(
|
||||||
@ -165,9 +219,7 @@ export class AbsorbableCircle extends Graphics implements AbsorbablePosition {
|
|||||||
obj.position
|
obj.position
|
||||||
);
|
);
|
||||||
obj.position.copyFrom(p);
|
obj.position.copyFrom(p);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ export interface StompCliOption {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
onAuthenticationFailed?: () => void;
|
onAuthenticationFailed?: () => void;
|
||||||
reconnectDelay?: number; // 重连延时,默认3秒
|
reconnectDelay?: number; // 重连延时,默认3秒,设置为0不重连.
|
||||||
heartbeatIncoming?: number; // 服务端过来的心跳间隔,默认30秒
|
heartbeatIncoming?: number; // 服务端过来的心跳间隔,默认30秒
|
||||||
heartbeatOutgoing?: number; // 到服务端的心跳间隔,默认30秒
|
heartbeatOutgoing?: number; // 到服务端的心跳间隔,默认30秒
|
||||||
}
|
}
|
||||||
@ -36,18 +36,22 @@ const DefaultStompOption: StompCliOption = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export class StompCli {
|
export class StompCli {
|
||||||
private static enabled = false;
|
|
||||||
private static options: StompCliOption;
|
|
||||||
private static client: StompClient;
|
private static client: StompClient;
|
||||||
|
private static options: StompCliOption;
|
||||||
private static appMsgBroker: AppWsMsgBroker[] = [];
|
private static appMsgBroker: AppWsMsgBroker[] = [];
|
||||||
|
/**
|
||||||
|
* key-订阅路径
|
||||||
|
*/
|
||||||
|
subscriptions: Map<string, AppStateSubscription> = new Map<
|
||||||
|
string,
|
||||||
|
AppStateSubscription
|
||||||
|
>();
|
||||||
private static connected = false;
|
private static connected = false;
|
||||||
static new(options: StompCliOption) {
|
static new(options: StompCliOption) {
|
||||||
if (StompCli.enabled) {
|
if (StompCli.client) {
|
||||||
// 已经启用
|
// 已经创建
|
||||||
return;
|
return;
|
||||||
// throw new Error('websocket 已连接,若确实需要重新连接,请先断开StompCli.close再重新StompCli.new')
|
|
||||||
}
|
}
|
||||||
StompCli.enabled = true;
|
|
||||||
StompCli.options = Object.assign({}, DefaultStompOption, options);
|
StompCli.options = Object.assign({}, DefaultStompOption, options);
|
||||||
StompCli.client = new StompClient({
|
StompCli.client = new StompClient({
|
||||||
brokerURL: StompCli.options.wsUrl,
|
brokerURL: StompCli.options.wsUrl,
|
||||||
@ -62,6 +66,7 @@ export class StompCli {
|
|||||||
StompCli.client.onConnect = () => {
|
StompCli.client.onConnect = () => {
|
||||||
// console.log('websocket连接(重连),重新订阅', StompCli.appMsgBroker.length)
|
// console.log('websocket连接(重连),重新订阅', StompCli.appMsgBroker.length)
|
||||||
StompCli.connected = true;
|
StompCli.connected = true;
|
||||||
|
StompCli.emitConnectStateChangeEvent();
|
||||||
StompCli.appMsgBroker.forEach((broker) => {
|
StompCli.appMsgBroker.forEach((broker) => {
|
||||||
broker.resubscribe();
|
broker.resubscribe();
|
||||||
});
|
});
|
||||||
@ -83,10 +88,12 @@ export class StompCli {
|
|||||||
StompCli.client.onDisconnect = (frame: Frame) => {
|
StompCli.client.onDisconnect = (frame: Frame) => {
|
||||||
console.log('Stomp 断开连接', frame);
|
console.log('Stomp 断开连接', frame);
|
||||||
StompCli.connected = false;
|
StompCli.connected = false;
|
||||||
|
StompCli.emitConnectStateChangeEvent();
|
||||||
};
|
};
|
||||||
StompCli.client.onWebSocketClose = (evt: CloseEvent) => {
|
StompCli.client.onWebSocketClose = (evt: CloseEvent) => {
|
||||||
console.log('websocket 关闭', evt);
|
console.log('websocket 关闭', evt);
|
||||||
StompCli.connected = false;
|
StompCli.connected = false;
|
||||||
|
StompCli.emitConnectStateChangeEvent();
|
||||||
};
|
};
|
||||||
// websocket错误处理
|
// websocket错误处理
|
||||||
StompCli.client.onWebSocketError = (err: Event) => {
|
StompCli.client.onWebSocketError = (err: Event) => {
|
||||||
@ -96,8 +103,10 @@ export class StompCli {
|
|||||||
StompCli.client.activate();
|
StompCli.client.activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static isEnabled(): boolean {
|
static emitConnectStateChangeEvent() {
|
||||||
return StompCli.enabled;
|
StompCli.appMsgBroker.forEach((broker) => {
|
||||||
|
broker.app.emit('websocket-state-change', broker.app, StompCli.connected);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static isConnected(): boolean {
|
static isConnected(): boolean {
|
||||||
@ -135,7 +144,6 @@ export class StompCli {
|
|||||||
* 关闭websocket连接
|
* 关闭websocket连接
|
||||||
*/
|
*/
|
||||||
static close() {
|
static close() {
|
||||||
StompCli.enabled = false;
|
|
||||||
StompCli.connected = false;
|
StompCli.connected = false;
|
||||||
if (StompCli.client) {
|
if (StompCli.client) {
|
||||||
StompCli.client.deactivate();
|
StompCli.client.deactivate();
|
||||||
|
@ -194,7 +194,7 @@ export class CommonMouseTool extends AppInteractionPlugin {
|
|||||||
const graphic = this.leftDownTarget.getGraphic();
|
const graphic = this.leftDownTarget.getGraphic();
|
||||||
if (graphic) {
|
if (graphic) {
|
||||||
const app = this.app;
|
const app = this.app;
|
||||||
console.log(this.leftDownTarget.isGraphic());
|
// console.log(this.leftDownTarget.isGraphic());
|
||||||
// 图形选中
|
// 图形选中
|
||||||
if (!e.ctrlKey && !graphic.selected && graphic.selectable) {
|
if (!e.ctrlKey && !graphic.selected && graphic.selectable) {
|
||||||
app.updateSelected(graphic);
|
app.updateSelected(graphic);
|
||||||
|
@ -171,11 +171,40 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
this.app.canvas.addAssistantAppend(this.apContainer);
|
this.app.canvas.addAssistantAppend(this.apContainer);
|
||||||
app.on('options-update', (options) => {
|
app.on('options-update', (options) => {
|
||||||
if (options.absorbablePositions) {
|
if (options.absorbablePositions) {
|
||||||
this.absorbablePositions = options.absorbablePositions;
|
this.absorbablePositions = this.filterAbsorbablePositions(
|
||||||
|
options.absorbablePositions
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 过滤重复的吸附位置
|
||||||
|
* @param positions
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
filterAbsorbablePositions(
|
||||||
|
positions: AbsorbablePosition[]
|
||||||
|
): AbsorbablePosition[] {
|
||||||
|
const aps: AbsorbablePosition[] = [];
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
const ap1 = positions[i];
|
||||||
|
let ap: AbsorbablePosition | null = ap1;
|
||||||
|
for (let j = positions.length - 1; j > i; j--) {
|
||||||
|
const ap2 = positions[j];
|
||||||
|
if (ap.isOverlapping(ap2) && ap.compareTo(ap2) <= 0) {
|
||||||
|
ap = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ap != null) {
|
||||||
|
aps.push(ap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(positions, aps);
|
||||||
|
return aps;
|
||||||
|
}
|
||||||
|
|
||||||
static new(app: GraphicApp) {
|
static new(app: GraphicApp) {
|
||||||
return new GraphicTransformPlugin(app);
|
return new GraphicTransformPlugin(app);
|
||||||
}
|
}
|
||||||
@ -266,9 +295,7 @@ export class GraphicTransformPlugin extends InteractionPluginBase {
|
|||||||
if (this.absorbablePositions) {
|
if (this.absorbablePositions) {
|
||||||
for (let i = 0; i < this.absorbablePositions.length; i++) {
|
for (let i = 0; i < this.absorbablePositions.length; i++) {
|
||||||
const ap = this.absorbablePositions[i];
|
const ap = this.absorbablePositions[i];
|
||||||
if (ap.tryAbsorb(...targets)) {
|
ap.tryAbsorb(...targets);
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 事件发布
|
// 事件发布
|
||||||
|
@ -607,3 +607,71 @@ export function getIntersectionPoint(line1: number[], line2: number[]) {
|
|||||||
-denominator;
|
-denominator;
|
||||||
return new Point(x, y);
|
return new Point(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否平行线
|
||||||
|
* @param p1
|
||||||
|
* @param p2
|
||||||
|
* @param pa
|
||||||
|
* @param pb
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function isParallelLines(
|
||||||
|
p1: IPointData,
|
||||||
|
p2: IPointData,
|
||||||
|
pa: IPointData,
|
||||||
|
pb: IPointData
|
||||||
|
): boolean {
|
||||||
|
const vle1 = Vector2.direction(Vector2.from(p1), Vector2.from(p2));
|
||||||
|
const vle2 = Vector2.direction(Vector2.from(pa), Vector2.from(pb));
|
||||||
|
if (vle2.equals(vle1)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return vle1.equals(Vector2.direction(Vector2.from(pb), Vector2.from(pa)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点是否在线段上
|
||||||
|
* @param p1
|
||||||
|
* @param p2
|
||||||
|
* @param p
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function isPointOnLine(
|
||||||
|
p1: IPointData,
|
||||||
|
p2: IPointData,
|
||||||
|
p: IPointData
|
||||||
|
): boolean {
|
||||||
|
const vp1 = Vector2.from(p1);
|
||||||
|
const vp2 = Vector2.from(p2);
|
||||||
|
const vp = Vector2.from(p);
|
||||||
|
if (vp1.equals(vp) || vp2.equals(vp)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const vle = Vector2.direction(vp1, Vector2.from(p2));
|
||||||
|
const vpe = Vector2.direction(vp1, vp);
|
||||||
|
if (vle.equals(vpe)) {
|
||||||
|
return (
|
||||||
|
Vector2.difference(vp1, vp2).squaredLength() >=
|
||||||
|
Vector2.difference(vp1, vp).squaredLength()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 两条线段是否存在包含关系
|
||||||
|
* @param line1
|
||||||
|
* @param line2
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function isLineContainOther(
|
||||||
|
line1: { p1: IPointData; p2: IPointData },
|
||||||
|
line2: { p1: IPointData; p2: IPointData }
|
||||||
|
): boolean {
|
||||||
|
return (
|
||||||
|
(isPointOnLine(line1.p1, line1.p2, line2.p1) &&
|
||||||
|
isPointOnLine(line1.p1, line1.p2, line2.p2)) ||
|
||||||
|
(isPointOnLine(line2.p1, line2.p2, line1.p1) &&
|
||||||
|
isPointOnLine(line2.p1, line2.p2, line1.p2))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
@ -134,6 +134,12 @@ onMounted(() => {
|
|||||||
const dom = document.getElementById('draw-app-container');
|
const dom = document.getElementById('draw-app-container');
|
||||||
if (dom) {
|
if (dom) {
|
||||||
const drawApp = drawStore.initDrawApp(dom);
|
const drawApp = drawStore.initDrawApp(dom);
|
||||||
|
drawApp.on('websocket-connected', (app) => {
|
||||||
|
console.log('应用websocket成功连接');
|
||||||
|
});
|
||||||
|
drawApp.on('websocket-disconnected', (app) => {
|
||||||
|
console.log('应用websocket断开连接');
|
||||||
|
});
|
||||||
loadDrawDatas(drawApp);
|
loadDrawDatas(drawApp);
|
||||||
onResize();
|
onResize();
|
||||||
drawApp.enableWsStomp({
|
drawApp.enableWsStomp({
|
||||||
|
Loading…
Reference in New Issue
Block a user