|
@@ -1,4 +1,4 @@
|
|
-import { SColor, SLine, SPainter, SPoint } from "@saga-web/draw/lib";
|
|
|
|
|
|
+import { SColor, SLine, SPainter, SPoint, SRect } from "@saga-web/draw/lib";
|
|
import { SMouseEvent } from "@saga-web/base";
|
|
import { SMouseEvent } from "@saga-web/base";
|
|
import { SMathUtil } from "../utils/SMathUtil";
|
|
import { SMathUtil } from "../utils/SMathUtil";
|
|
import { SRelationState } from "..";
|
|
import { SRelationState } from "..";
|
|
@@ -7,13 +7,30 @@ import { SGraphItem } from "@saga-web/graph/lib";
|
|
/**
|
|
/**
|
|
* 直线item
|
|
* 直线item
|
|
*
|
|
*
|
|
|
|
+ * @author 张宇(taohuzy@163.com)
|
|
* */
|
|
* */
|
|
|
|
|
|
export class SLineItem extends SGraphItem {
|
|
export class SLineItem extends SGraphItem {
|
|
- /** 线段起始点 */
|
|
|
|
- p1: SPoint | undefined;
|
|
|
|
- /** 线段终止点 */
|
|
|
|
- p2: SPoint | undefined;
|
|
|
|
|
|
+ /** X坐标最小值 */
|
|
|
|
+ private minX = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ /** X坐标最大值 */
|
|
|
|
+ private maxX = Number.MIN_SAFE_INTEGER;
|
|
|
|
+ /** Y坐标最小值 */
|
|
|
|
+ private minY = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ /** Y坐标最大值 */
|
|
|
|
+ private maxY = Number.MIN_SAFE_INTEGER;
|
|
|
|
+
|
|
|
|
+ /** 线段 */
|
|
|
|
+ _line: SPoint[] = [];
|
|
|
|
+ get line(): SPoint[] {
|
|
|
|
+ return this._line;
|
|
|
|
+ }
|
|
|
|
+ set line(arr: SPoint[]) {
|
|
|
|
+ this._line = arr;
|
|
|
|
+ this._xyzListToSPointList(arr);
|
|
|
|
+ this.update();
|
|
|
|
+ }
|
|
|
|
+
|
|
/** 是否完成绘制 */
|
|
/** 是否完成绘制 */
|
|
_status: SRelationState = SRelationState.Create;
|
|
_status: SRelationState = SRelationState.Create;
|
|
get status(): SRelationState {
|
|
get status(): SRelationState {
|
|
@@ -23,6 +40,7 @@ export class SLineItem extends SGraphItem {
|
|
this._status = v;
|
|
this._status = v;
|
|
this.update();
|
|
this.update();
|
|
}
|
|
}
|
|
|
|
+
|
|
/** 线条颜色 */
|
|
/** 线条颜色 */
|
|
_strokeColor: string = "#000000";
|
|
_strokeColor: string = "#000000";
|
|
get strokeColor(): string {
|
|
get strokeColor(): string {
|
|
@@ -32,6 +50,7 @@ export class SLineItem extends SGraphItem {
|
|
this._strokeColor = v;
|
|
this._strokeColor = v;
|
|
this.update();
|
|
this.update();
|
|
}
|
|
}
|
|
|
|
+
|
|
/** 填充色 */
|
|
/** 填充色 */
|
|
_fillColor: string = "#2196f3";
|
|
_fillColor: string = "#2196f3";
|
|
get fillColor(): string {
|
|
get fillColor(): string {
|
|
@@ -41,6 +60,7 @@ export class SLineItem extends SGraphItem {
|
|
this._fillColor = v;
|
|
this._fillColor = v;
|
|
this.update();
|
|
this.update();
|
|
}
|
|
}
|
|
|
|
+
|
|
/** 线条宽度 */
|
|
/** 线条宽度 */
|
|
_lineWidth: number = 1;
|
|
_lineWidth: number = 1;
|
|
get lineWidth(): number {
|
|
get lineWidth(): number {
|
|
@@ -50,24 +70,29 @@ export class SLineItem extends SGraphItem {
|
|
this._lineWidth = v;
|
|
this._lineWidth = v;
|
|
this.update();
|
|
this.update();
|
|
}
|
|
}
|
|
|
|
+
|
|
/** 拖动灵敏度 */
|
|
/** 拖动灵敏度 */
|
|
dis: number = 10;
|
|
dis: number = 10;
|
|
|
|
+
|
|
/** 拖动灵敏度 */
|
|
/** 拖动灵敏度 */
|
|
sceneDis: number = 10;
|
|
sceneDis: number = 10;
|
|
|
|
|
|
|
|
+ /** 当前点索引 */
|
|
|
|
+ curIndex: number = -1;
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 构造函数
|
|
* 构造函数
|
|
*
|
|
*
|
|
* @param parent 父级
|
|
* @param parent 父级
|
|
- * @param line 线段
|
|
|
|
|
|
+ * @param line 坐标集合
|
|
* */
|
|
* */
|
|
- constructor(parent: SGraphItem | null, line: SLine);
|
|
|
|
|
|
+ constructor(parent: SGraphItem | null, line: SPoint[]);
|
|
|
|
|
|
/**
|
|
/**
|
|
* 构造函数
|
|
* 构造函数
|
|
*
|
|
*
|
|
* @param parent 父级
|
|
* @param parent 父级
|
|
- * @param point 线段起点
|
|
|
|
|
|
+ * @param point 第一个点坐标
|
|
* */
|
|
* */
|
|
constructor(parent: SGraphItem | null, point: SPoint);
|
|
constructor(parent: SGraphItem | null, point: SPoint);
|
|
|
|
|
|
@@ -75,19 +100,54 @@ export class SLineItem extends SGraphItem {
|
|
* 构造函数
|
|
* 构造函数
|
|
*
|
|
*
|
|
* @param parent 父级
|
|
* @param parent 父级
|
|
- * @param l 线段or线段起点
|
|
|
|
|
|
+ * @param l 坐标集合|第一个点坐标
|
|
* */
|
|
* */
|
|
- constructor(parent: SGraphItem | null, l: SPoint | SLine) {
|
|
|
|
|
|
+ constructor(parent: SGraphItem | null, l: SPoint | SPoint[]) {
|
|
super(parent);
|
|
super(parent);
|
|
if (l instanceof SPoint) {
|
|
if (l instanceof SPoint) {
|
|
- this.p1 = l;
|
|
|
|
|
|
+ this.line.push(l);
|
|
} else {
|
|
} else {
|
|
- this.p1 = l.p1;
|
|
|
|
- this.p2 = l.p2;
|
|
|
|
|
|
+ this.line = l;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * 添加点至数组中
|
|
|
|
+ *
|
|
|
|
+ * @param p 添加的点
|
|
|
|
+ * @param index 添加到的索引
|
|
|
|
+ * */
|
|
|
|
+ private addPoint(p: SPoint): void {
|
|
|
|
+ if (this.line.length < 2) {
|
|
|
|
+ this.line.push(p);
|
|
|
|
+ } else {
|
|
|
|
+ this.line[1] = p;
|
|
|
|
+ this.status = SRelationState.Normal;
|
|
|
|
+ }
|
|
|
|
+ this._xyzListToSPointList(this.line);
|
|
|
|
+ this.update();
|
|
|
|
+ } // Function addPoint()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 鼠标双击事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onDoubleClick(event: SMouseEvent): boolean {
|
|
|
|
+ if (this.contains(event.x, event.y)) {
|
|
|
|
+ // 判断是否点击到线上
|
|
|
|
+ if (this.status == SRelationState.Normal) {
|
|
|
|
+ this.status = SRelationState.Edit;
|
|
|
|
+ } else if ((this.status = SRelationState.Edit)) {
|
|
|
|
+ this.status = SRelationState.Normal;
|
|
|
|
+ }
|
|
|
|
+ this.update();
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onDoubleClick()
|
|
|
|
+
|
|
|
|
+ /**
|
|
* 鼠标按下事件
|
|
* 鼠标按下事件
|
|
*
|
|
*
|
|
* @param event 鼠标事件
|
|
* @param event 鼠标事件
|
|
@@ -97,7 +157,10 @@ export class SLineItem extends SGraphItem {
|
|
if (this.status == SRelationState.Normal) {
|
|
if (this.status == SRelationState.Normal) {
|
|
return super.onMouseDown(event);
|
|
return super.onMouseDown(event);
|
|
} else if (this.status == SRelationState.Edit) {
|
|
} else if (this.status == SRelationState.Edit) {
|
|
|
|
+ // 判断是否点击到端点上(获取端点索引值)
|
|
|
|
+ this.findNearestPoint(new SPoint(event.x, event.y));
|
|
} else if (this.status == SRelationState.Create) {
|
|
} else if (this.status == SRelationState.Create) {
|
|
|
|
+ this.addPoint(new SPoint(event.x, event.y));
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
this.$emit("mousedown");
|
|
this.$emit("mousedown");
|
|
@@ -105,6 +168,19 @@ export class SLineItem extends SGraphItem {
|
|
} // Function onMouseDown()
|
|
} // Function onMouseDown()
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * 鼠标抬起事件
|
|
|
|
+ *
|
|
|
|
+ * @param event 事件参数
|
|
|
|
+ * @return boolean
|
|
|
|
+ */
|
|
|
|
+ onMouseUp(event: SMouseEvent): boolean {
|
|
|
|
+ if (this._status == SRelationState.Edit) {
|
|
|
|
+ this.curIndex = -1;
|
|
|
|
+ }
|
|
|
|
+ return true;
|
|
|
|
+ } // Function onMouseUp()
|
|
|
|
+
|
|
|
|
+ /**
|
|
* 鼠标移动事件
|
|
* 鼠标移动事件
|
|
*
|
|
*
|
|
* @param event 鼠标事件
|
|
* @param event 鼠标事件
|
|
@@ -112,32 +188,72 @@ export class SLineItem extends SGraphItem {
|
|
* */
|
|
* */
|
|
onMouseMove(event: SMouseEvent): boolean {
|
|
onMouseMove(event: SMouseEvent): boolean {
|
|
if (this.status == SRelationState.Create) {
|
|
if (this.status == SRelationState.Create) {
|
|
- if (!this.p2) {
|
|
|
|
- this.p2 = new SPoint(event.x, event.y);
|
|
|
|
- } else {
|
|
|
|
- this.p2.x = event.x;
|
|
|
|
- this.p2.y = event.y;
|
|
|
|
|
|
+ if (this.line[0] instanceof SPoint) {
|
|
|
|
+ this.line[1] = new SPoint(event.x, event.y);
|
|
|
|
+ }
|
|
|
|
+ } else if (this.status == SRelationState.Edit) {
|
|
|
|
+ if (-1 != this.curIndex) {
|
|
|
|
+ this.line[this.curIndex].x = event.x;
|
|
|
|
+ this.line[this.curIndex].y = event.y;
|
|
}
|
|
}
|
|
- return true;
|
|
|
|
} else {
|
|
} else {
|
|
return super.onMouseMove(event);
|
|
return super.onMouseMove(event);
|
|
}
|
|
}
|
|
|
|
+ this._xyzListToSPointList(this.line);
|
|
|
|
+ this.update();
|
|
|
|
+ return true;
|
|
} // Function onMouseMove()
|
|
} // Function onMouseMove()
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 鼠标移动事件
|
|
|
|
|
|
+ * 获取点击点与Point[]中的点距离最近点
|
|
*
|
|
*
|
|
- * @param event 鼠标事件
|
|
|
|
- * @return 是否处理事件
|
|
|
|
|
|
+ * @param p 鼠标点击点
|
|
* */
|
|
* */
|
|
- onMouseUp(event: SMouseEvent): boolean {
|
|
|
|
- if (this.status == SRelationState.Create) {
|
|
|
|
- this.status = SRelationState.Edit;
|
|
|
|
- return true;
|
|
|
|
- } else {
|
|
|
|
- return super.onMouseUp(event);
|
|
|
|
|
|
+ findNearestPoint(p: SPoint): void {
|
|
|
|
+ let len = this.sceneDis;
|
|
|
|
+ for (let i = 0; i < 2; i++) {
|
|
|
|
+ let dis = SMathUtil.pointDistance(
|
|
|
|
+ p.x,
|
|
|
|
+ p.y,
|
|
|
|
+ this.line[i].x,
|
|
|
|
+ this.line[i].y
|
|
|
|
+ );
|
|
|
|
+ if (dis < len) {
|
|
|
|
+ len = dis;
|
|
|
|
+ this.curIndex = i;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- } // Function onMouseUp()
|
|
|
|
|
|
+ } // Function findNearestPoint()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * xyz数据转换为SPoint格式函数;获取外接矩阵参数
|
|
|
|
+ *
|
|
|
|
+ * @param arr 外层传入的数据PointList
|
|
|
|
+ */
|
|
|
|
+ protected _xyzListToSPointList(arr: SPoint[]): void {
|
|
|
|
+ if (arr.length) {
|
|
|
|
+ this.minX = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ this.maxX = Number.MIN_SAFE_INTEGER;
|
|
|
|
+ this.minY = Number.MAX_SAFE_INTEGER;
|
|
|
|
+ this.maxY = Number.MIN_SAFE_INTEGER;
|
|
|
|
+ arr.forEach(it => {
|
|
|
|
+ let x = it.x,
|
|
|
|
+ y = it.y;
|
|
|
|
+ if (x < this.minX) {
|
|
|
|
+ this.minX = x;
|
|
|
|
+ }
|
|
|
|
+ if (y < this.minY) {
|
|
|
|
+ this.minY = y;
|
|
|
|
+ }
|
|
|
|
+ if (x > this.maxX) {
|
|
|
|
+ this.maxX = x;
|
|
|
|
+ }
|
|
|
|
+ if (y > this.maxY) {
|
|
|
|
+ this.maxY = y;
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
/**
|
|
* 判断点是否在区域内
|
|
* 判断点是否在区域内
|
|
@@ -147,11 +263,11 @@ export class SLineItem extends SGraphItem {
|
|
* @return true-是
|
|
* @return true-是
|
|
*/
|
|
*/
|
|
contains(x: number, y: number): boolean {
|
|
contains(x: number, y: number): boolean {
|
|
- if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
|
|
|
|
|
|
+ if (this.line.length == 2) {
|
|
let p = new SPoint(x, y);
|
|
let p = new SPoint(x, y);
|
|
if (
|
|
if (
|
|
- SMathUtil.pointToLine(p, new SLine(this.p1, this.p2)).MinDis <
|
|
|
|
- this.dis
|
|
|
|
|
|
+ SMathUtil.pointToLine(p, new SLine(this.line[0], this.line[1]))
|
|
|
|
+ .MinDis < this.dis
|
|
) {
|
|
) {
|
|
return true;
|
|
return true;
|
|
}
|
|
}
|
|
@@ -160,6 +276,34 @@ export class SLineItem extends SGraphItem {
|
|
} // Function contains()
|
|
} // Function contains()
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * 取消操作item事件
|
|
|
|
+ *
|
|
|
|
+ * */
|
|
|
|
+ cancelOperate(): void {
|
|
|
|
+ if (this.status == SRelationState.Create) {
|
|
|
|
+ this.parent = null;
|
|
|
|
+ this.releaseItem();
|
|
|
|
+ } else if (this.status == SRelationState.Edit) {
|
|
|
|
+ this.status = SRelationState.Normal;
|
|
|
|
+ this.releaseItem();
|
|
|
|
+ }
|
|
|
|
+ } // Function cancelOperate()
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Item对象边界区域
|
|
|
|
+ *
|
|
|
|
+ * @return SRect
|
|
|
|
+ */
|
|
|
|
+ boundingRect(): SRect {
|
|
|
|
+ return new SRect(
|
|
|
|
+ this.minX,
|
|
|
|
+ this.minY,
|
|
|
|
+ this.maxX - this.minX,
|
|
|
|
+ this.maxY - this.minY
|
|
|
|
+ );
|
|
|
|
+ } // Function boundingRect()
|
|
|
|
+
|
|
|
|
+ /**
|
|
* Item绘制操作
|
|
* Item绘制操作
|
|
*
|
|
*
|
|
* @param painter painter对象
|
|
* @param painter painter对象
|
|
@@ -168,18 +312,45 @@ export class SLineItem extends SGraphItem {
|
|
this.sceneDis = painter.toPx(this.dis);
|
|
this.sceneDis = painter.toPx(this.dis);
|
|
painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
painter.pen.color = new SColor(this.strokeColor);
|
|
painter.pen.color = new SColor(this.strokeColor);
|
|
- if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
|
|
|
|
- // 绘制基本图形
|
|
|
|
- painter.drawLine(this.p1, this.p2);
|
|
|
|
- // 编辑态
|
|
|
|
- if (this.status == SRelationState.Edit) {
|
|
|
|
- painter.brush.color = SColor.White;
|
|
|
|
|
|
+ if (this.line.length == 2) {
|
|
|
|
+ // 绘制外轮廓
|
|
|
|
+ // painter.brush.color = SColor.Transparent;
|
|
|
|
+ // painter.pen.color = new SColor("#128eee");
|
|
|
|
+ // painter.drawRect(this.boundingRect());
|
|
|
|
|
|
- // painter.brush.color = new SColor(this.fillColor);
|
|
|
|
|
|
+ // 绘制直线
|
|
|
|
+ painter.pen.color = new SColor(this.strokeColor);
|
|
|
|
+ painter.drawLine(this.line[0], this.line[1]);
|
|
|
|
|
|
- painter.drawCircle(this.p1.x, this.p1.y, painter.toPx(5));
|
|
|
|
-
|
|
|
|
- painter.drawCircle(this.p2.x, this.p2.y, painter.toPx(5));
|
|
|
|
|
|
+ if (
|
|
|
|
+ this.status == SRelationState.Edit ||
|
|
|
|
+ this.status == SRelationState.Create
|
|
|
|
+ ) {
|
|
|
|
+ // 绘制端点
|
|
|
|
+ painter.brush.color = new SColor(this.fillColor);
|
|
|
|
+ painter.drawCircle(
|
|
|
|
+ this.line[0].x,
|
|
|
|
+ this.line[0].y,
|
|
|
|
+ painter.toPx(5)
|
|
|
|
+ );
|
|
|
|
+ painter.drawCircle(
|
|
|
|
+ this.line[1].x,
|
|
|
|
+ this.line[1].y,
|
|
|
|
+ painter.toPx(5)
|
|
|
|
+ );
|
|
|
|
+ }
|
|
|
|
+ } else if (this.line.length == 1) {
|
|
|
|
+ if (
|
|
|
|
+ this.status == SRelationState.Edit ||
|
|
|
|
+ this.status == SRelationState.Create
|
|
|
|
+ ) {
|
|
|
|
+ // 绘制端点
|
|
|
|
+ painter.brush.color = new SColor(this.fillColor);
|
|
|
|
+ painter.drawCircle(
|
|
|
|
+ this.line[0].x,
|
|
|
|
+ this.line[0].y,
|
|
|
|
+ painter.toPx(5)
|
|
|
|
+ );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} // Function onDraw()
|
|
} // Function onDraw()
|