|
@@ -157,14 +157,18 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
this.name = data.name;
|
|
|
this.showSelect = false;
|
|
|
// this.text = data.Name;
|
|
|
+ // 样式存在
|
|
|
if (data.style) {
|
|
|
this.setPointList = [];
|
|
|
let setPointList: SPoint[];
|
|
|
+ // 样式中存有轮廓线数据
|
|
|
if (data.style.outLine) {
|
|
|
+ // 轮廓线内容类型是 SPoint 类型
|
|
|
if (data.style.outLine[0] instanceof SPoint) {
|
|
|
// @ts-ignore
|
|
|
this.setPointList = data.style.outLine;
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
setPointList = data.style.outLine.map(i => {
|
|
|
return new SPoint(i.x, i.y);
|
|
|
});
|
|
@@ -174,7 +178,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
|
|
|
// 样式相关
|
|
|
if (data.style.default) {
|
|
|
- // 颜色
|
|
|
+ // 线条颜色
|
|
|
if (data.style.default.strokeColor) {
|
|
|
this.strokeColor = new SColor(
|
|
|
data.style.default.strokeColor
|
|
@@ -242,9 +246,11 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
insertPoint(x: number, y: number, i: number | null = null): SPoint {
|
|
|
const point = new SPoint(x, y);
|
|
|
+ // 没有传入索引
|
|
|
if (i == null) {
|
|
|
this.pointList.push(point);
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
this.pointList.splice(i, 0, point);
|
|
|
}
|
|
|
|
|
@@ -260,18 +266,24 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
deletePoint(i: number | null = null): SPoint | null {
|
|
|
let point;
|
|
|
+ // 传入删除的索引
|
|
|
if (i != null) {
|
|
|
+ // 索引值无效
|
|
|
if (i >= this.pointList.length || i < 0) {
|
|
|
point = null;
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
point = new SPoint(this.pointList[i].x, this.pointList[i].y);
|
|
|
this.pointList.splice(i, 1);
|
|
|
}
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
+ // 轮廓线数据存在
|
|
|
if (this.pointList.length) {
|
|
|
point = this.pointList[this.pointList.length - 1];
|
|
|
this.pointList.pop();
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
point = null;
|
|
|
}
|
|
|
}
|
|
@@ -292,10 +304,12 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
movePoint(x: number, y: number, i: number): SPoint | null {
|
|
|
let point;
|
|
|
+ // 索引值无效
|
|
|
if (i >= this.pointList.length || i < 0) {
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
+ // 轮廓线数据存在
|
|
|
if (this.pointList.length) {
|
|
|
this.pointList[i].x = x;
|
|
|
this.pointList[i].y = y;
|
|
@@ -317,25 +331,28 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
painter.pen.color = this.strokeColor;
|
|
|
painter.brush.color = this.fillColor;
|
|
|
painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
|
+ // 线类型为虚线
|
|
|
if (this.lineStyle == SLineStyle.Dashed) {
|
|
|
painter.pen.lineDash = [
|
|
|
painter.toPx(this.lineWidth * 3),
|
|
|
painter.toPx(this.lineWidth * 7)
|
|
|
];
|
|
|
} else if (this.lineStyle == SLineStyle.Dotted) {
|
|
|
+ // 线类型为点线
|
|
|
painter.pen.lineDash = [
|
|
|
painter.toPx(this.lineWidth),
|
|
|
painter.toPx(this.lineWidth)
|
|
|
];
|
|
|
}
|
|
|
|
|
|
- // 是否选中
|
|
|
+ // 被选中
|
|
|
if (this.selected) {
|
|
|
painter.shadow.shadowBlur = 10;
|
|
|
painter.shadow.shadowColor = new SColor(`#00000033`);
|
|
|
painter.shadow.shadowOffsetX = 5;
|
|
|
painter.shadow.shadowOffsetY = 5;
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
painter.shadow.shadowColor = SColor.Transparent;
|
|
|
}
|
|
|
|
|
@@ -353,6 +370,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
painter.pen.lineCapStyle = SLineCapStyle.Square;
|
|
|
painter.pen.color = this.strokeColor;
|
|
|
painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
|
+ // 最后一个点存在而且轮廓线数据有效
|
|
|
if (this.lastPoint && pointList.length) {
|
|
|
painter.drawLine(
|
|
|
pointList[pointList.length - 1].x,
|
|
@@ -366,6 +384,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
painter.pen.color = SColor.Transparent;
|
|
|
painter.brush.color = new SColor(this.fillColor.value);
|
|
|
painter.pen.lineWidth = painter.toPx(this.lineWidth);
|
|
|
+ // 最后一个点存在
|
|
|
if (this.lastPoint) {
|
|
|
painter.drawPolygon([...pointList, this.lastPoint]);
|
|
|
// 绘制顶点块
|
|
@@ -374,8 +393,9 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
pointList.forEach(item => {
|
|
|
painter.drawCircle(item.x, item.y, painter.toPx(this.len / 2));
|
|
|
});
|
|
|
- // 如果最后一个点在第一个点的灵敏度范围内,第一个点填充变红
|
|
|
+ // 轮廓线有效
|
|
|
if (this.pointList.length) {
|
|
|
+ // 如果最后一个点在第一个点的灵敏度范围内,第一个点填充变红
|
|
|
if (
|
|
|
SMathUtil.pointDistance(
|
|
|
this.lastPoint.x,
|
|
@@ -395,6 +415,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
}
|
|
|
}
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
painter.drawPolygon(pointList);
|
|
|
}
|
|
|
}
|
|
@@ -416,8 +437,10 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
// 绘制顶点块
|
|
|
painter.pen.color = SColor.Black;
|
|
|
painter.brush.color = SColor.White;
|
|
|
+ // 遍历轮廓线列表
|
|
|
pointList.forEach((item, index) => {
|
|
|
painter.brush.color = SColor.White;
|
|
|
+ // 设置选中点样式
|
|
|
if (index == this.curIndex) {
|
|
|
painter.brush.color = new SColor("#2196f3");
|
|
|
}
|
|
@@ -437,6 +460,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
// 1 判断是否点击在多边形顶点
|
|
|
let lenIndex = -1; // 当前点击到的点位索引;
|
|
|
let curenLen = this.scenceLen; // 当前的灵敏度
|
|
|
+ // 遍历轮廓线列表
|
|
|
this.pointList.forEach((item, index) => {
|
|
|
let dis = SMathUtil.pointDistance(
|
|
|
event.x,
|
|
@@ -444,6 +468,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
item.x,
|
|
|
item.y
|
|
|
);
|
|
|
+ // 鼠标点在线段的吸附范围内
|
|
|
if (dis < curenLen) {
|
|
|
curenLen = dis;
|
|
|
lenIndex = index;
|
|
@@ -452,6 +477,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
|
|
|
// 若点击到,对该索引对应的点做删除
|
|
|
if (lenIndex != -1) {
|
|
|
+ // 顶点个数小于3个
|
|
|
if (this.pointList.length <= 3) {
|
|
|
return;
|
|
|
}
|
|
@@ -469,11 +495,13 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
]);
|
|
|
}
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
// 1 判断是否点击在多边形顶点
|
|
|
this.curIndex = -1;
|
|
|
this.curPoint = null;
|
|
|
let lenIndex = -1; // 当前点击到的点位索引;
|
|
|
let curenLen = this.scenceLen; // 当前的灵敏度
|
|
|
+ // 遍历轮廓线数据
|
|
|
this.pointList.forEach((item, index) => {
|
|
|
let dis = SMathUtil.pointDistance(
|
|
|
event.x,
|
|
@@ -481,12 +509,14 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
item.x,
|
|
|
item.y
|
|
|
);
|
|
|
+ // 鼠标点在线段的吸附范围内
|
|
|
if (dis < curenLen) {
|
|
|
curenLen = dis;
|
|
|
lenIndex = index;
|
|
|
}
|
|
|
});
|
|
|
this.curIndex = lenIndex;
|
|
|
+ // 有选中的点
|
|
|
// 2判断是否点击在多边形得边上
|
|
|
if (-1 == lenIndex) {
|
|
|
let len = SMathUtil.pointToLine(
|
|
@@ -494,18 +524,21 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
new SLine(this.pointList[0], this.pointList[1])
|
|
|
),
|
|
|
index = 0;
|
|
|
+ // 顶点数据个数超过3个,即有效多边形
|
|
|
if (this.pointList.length > 2) {
|
|
|
for (let i = 1; i < this.pointList.length; i++) {
|
|
|
let dis = SMathUtil.pointToLine(
|
|
|
new SPoint(event.x, event.y),
|
|
|
new SLine(this.pointList[i], this.pointList[i + 1])
|
|
|
);
|
|
|
+ // 是最后一个点,则使用最后一个点链接第一个点生成线
|
|
|
if (i + 1 == this.pointList.length) {
|
|
|
dis = SMathUtil.pointToLine(
|
|
|
new SPoint(event.x, event.y),
|
|
|
new SLine(this.pointList[i], this.pointList[0])
|
|
|
);
|
|
|
}
|
|
|
+ // 该点在多变形的吸附范围内
|
|
|
if (dis.MinDis < len.MinDis) {
|
|
|
len = dis;
|
|
|
index = i;
|
|
@@ -560,6 +593,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* 执行取消操作执行
|
|
|
*/
|
|
|
undo(): void {
|
|
|
+ // 处于正常态
|
|
|
if (this.status == SItemStatus.Normal) {
|
|
|
return;
|
|
|
}
|
|
@@ -570,6 +604,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* 执行重做操作执行
|
|
|
*/
|
|
|
redo(): void {
|
|
|
+ // 处于正常态
|
|
|
if (this.status == SItemStatus.Normal) {
|
|
|
return;
|
|
|
}
|
|
@@ -587,11 +622,12 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 是否处理该事件
|
|
|
*/
|
|
|
onDoubleClick(event: SMouseEvent): boolean {
|
|
|
- // 如果位show状态 双击改对象则需改为编辑状态
|
|
|
+ // 处于正常态
|
|
|
if (SItemStatus.Normal == this.status) {
|
|
|
this.status = SItemStatus.Edit;
|
|
|
this.grabItem(this);
|
|
|
} else if (SItemStatus.Edit == this.status) {
|
|
|
+ // 处于编辑态
|
|
|
this.status = SItemStatus.Normal;
|
|
|
this.releaseItem();
|
|
|
}
|
|
@@ -607,10 +643,13 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 是否处理该事件
|
|
|
*/
|
|
|
onKeyDown(event: KeyboardEvent): boolean {
|
|
|
+ // 处于正常态
|
|
|
if (this.status == SItemStatus.Normal) {
|
|
|
return false;
|
|
|
} else if (this.status == SItemStatus.Create) {
|
|
|
+ // 处于创建态
|
|
|
if (event.code == "Enter") {
|
|
|
+ // 按下 enter 键
|
|
|
// 当顶点大于二个时才又条件执行闭合操作并清空堆栈
|
|
|
if (this.pointList.length > 2) {
|
|
|
this.status = SItemStatus.Normal;
|
|
@@ -621,7 +660,9 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
}
|
|
|
}
|
|
|
} else if (this.status == SItemStatus.Edit) {
|
|
|
+ // 处于编辑态
|
|
|
if (event.key == "Alt") {
|
|
|
+ // 按下 alt 键
|
|
|
this.isAlt = true;
|
|
|
}
|
|
|
}
|
|
@@ -637,11 +678,15 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
onKeyUp(event: KeyboardEvent): void {
|
|
|
if (this.status == SItemStatus.Edit) {
|
|
|
+ // 处于编辑态
|
|
|
if (event.key == "Alt") {
|
|
|
+ // 按下 alt 键
|
|
|
this.isAlt = false;
|
|
|
} else if (event.keyCode == SKeyCode.Delete) {
|
|
|
+ // 按下 delete 键
|
|
|
// 当多边形的顶点大于三个允许删除点
|
|
|
if (this.pointList.length > 3) {
|
|
|
+ // 顶点个数超过 3 个可以删除
|
|
|
this.deletePoint(this.curIndex);
|
|
|
}
|
|
|
}
|
|
@@ -657,14 +702,16 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 是否处理该事件
|
|
|
*/
|
|
|
onMouseDown(event: SMouseEvent): boolean {
|
|
|
+ // 按下 shift 键
|
|
|
if (event.shiftKey) {
|
|
|
event = this.compare(event);
|
|
|
}
|
|
|
|
|
|
- // 如果状态为编辑状态则添加点
|
|
|
+ // 处于创建态
|
|
|
if (this.status == SItemStatus.Create) {
|
|
|
// 新增顶点
|
|
|
let len = -1;
|
|
|
+ // 轮廓线数据有效
|
|
|
if (this.pointList.length) {
|
|
|
len = SMathUtil.pointDistance(
|
|
|
event.x,
|
|
@@ -674,6 +721,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
+ // 顶点个数超过 2 个且距离第一个点的距离大于0且在多边形吸附范围内
|
|
|
if (this.pointList.length > 2 && len > 0 && len < this.scenceLen) {
|
|
|
this.status = SItemStatus.Normal;
|
|
|
//3 传递完成事件状态
|
|
@@ -681,15 +729,17 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
//1 grabItem 置为null
|
|
|
this.releaseItem();
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
this.insertPoint(event.x, event.y);
|
|
|
// 记录新增顶点操作记录压入堆栈
|
|
|
let pos = new SPoint(event.x, event.y);
|
|
|
this.recordAction(SGraphPointListInsert, [this.pointList, pos]);
|
|
|
}
|
|
|
} else if (this.status == SItemStatus.Edit) {
|
|
|
- // 对多边形数组做编辑操作
|
|
|
+ // 处于编辑态,对多边形数组做编辑操作
|
|
|
this.editPolygonPoint(event);
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
// return super.onMouseDown(event);
|
|
|
super.onMouseDown(event);
|
|
|
}
|
|
@@ -724,17 +774,22 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 是否处理该事件
|
|
|
*/
|
|
|
onMouseMove(event: SMouseEvent): boolean {
|
|
|
+ // shift 键被按下
|
|
|
if (event.shiftKey) {
|
|
|
event = this.compare(event);
|
|
|
}
|
|
|
|
|
|
+ // 处于创建态
|
|
|
if (this.status == SItemStatus.Create) {
|
|
|
this.lastPoint = new SPoint();
|
|
|
this.lastPoint.x = event.x;
|
|
|
this.lastPoint.y = event.y;
|
|
|
this.update();
|
|
|
} else if (this.status == SItemStatus.Edit) {
|
|
|
+ // 处于编辑态
|
|
|
+ // 鼠标左键移动
|
|
|
if (event.buttons == 1) {
|
|
|
+ // 有选中的点
|
|
|
if (-1 != this.curIndex) {
|
|
|
this.pointList[this.curIndex].x = event.x;
|
|
|
this.pointList[this.curIndex].y = event.y;
|
|
@@ -742,6 +797,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
}
|
|
|
this.update();
|
|
|
} else {
|
|
|
+ // 否则
|
|
|
return super.onMouseMove(event);
|
|
|
}
|
|
|
|
|
@@ -754,11 +810,15 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @param event 事件
|
|
|
*/
|
|
|
compare(event: SMouseEvent): SMouseEvent {
|
|
|
+ // 轮廓线有效
|
|
|
if (this.pointList.length) {
|
|
|
let last = new SPoint(event.x, event.y);
|
|
|
+ // 处于创建态
|
|
|
if (this.status == SItemStatus.Create) {
|
|
|
last = this.pointList[this.pointList.length - 1];
|
|
|
} else if (this.status == SItemStatus.Edit) {
|
|
|
+ // 处于编辑态
|
|
|
+ // 当前有选中的点
|
|
|
if (this.curIndex > 0) {
|
|
|
last = this.pointList[this.curIndex - 1];
|
|
|
}
|
|
@@ -766,9 +826,11 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
|
|
|
const dx = Math.abs(event.x - last.x);
|
|
|
const dy = Math.abs(event.y - last.y);
|
|
|
+ // y 轴方向偏移量较大,则锁定 x 坐标
|
|
|
if (dy > dx) {
|
|
|
event.x = last.x;
|
|
|
} else {
|
|
|
+ // 否则,锁定 y 轴坐标
|
|
|
event.y = last.y;
|
|
|
}
|
|
|
}
|
|
@@ -783,7 +845,9 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 是否处理该事件
|
|
|
*/
|
|
|
onMouseUp(event: SMouseEvent): boolean {
|
|
|
+ // 处于编辑态
|
|
|
if (this.status == SItemStatus.Edit) {
|
|
|
+ // 当前有选中的点
|
|
|
if (-1 != this.curIndex) {
|
|
|
const pos = new SPoint(
|
|
|
this.pointList[this.curIndex].x,
|
|
@@ -797,6 +861,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
]);
|
|
|
}
|
|
|
} else if (this.status == SItemStatus.Normal) {
|
|
|
+ // 处于正常态
|
|
|
return super.onMouseUp(event);
|
|
|
}
|
|
|
return true;
|
|
@@ -806,6 +871,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* 移动后处理所有坐标,并肩原点置为场景原点
|
|
|
*/
|
|
|
moveToOrigin(): void {
|
|
|
+ // 遍历顶点列表
|
|
|
this.pointList = this.pointList.map(t => {
|
|
|
t.x = t.x + this.x;
|
|
|
t.y = t.y + this.y;
|
|
@@ -832,10 +898,10 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
cancelOperate(): void {
|
|
|
// 当状态为展示状态
|
|
|
if (this.status == SItemStatus.Create) {
|
|
|
- // 闭合多边形
|
|
|
+ // 处于创建态
|
|
|
this.parent = null;
|
|
|
} else if (this.status == SItemStatus.Edit) {
|
|
|
- // 编辑状态
|
|
|
+ // 处于编辑状态
|
|
|
this.status = SItemStatus.Normal;
|
|
|
}
|
|
|
|
|
@@ -848,26 +914,32 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
* @return 边界区域
|
|
|
*/
|
|
|
boundingRect(): SRect {
|
|
|
+ // 轮廓线有效
|
|
|
if (this.pointList.length) {
|
|
|
this.minX = this.pointList[0].x;
|
|
|
this.maxX = this.pointList[0].x;
|
|
|
this.minY = this.pointList[0].y;
|
|
|
this.maxY = this.pointList[0].y;
|
|
|
+ // 遍历顶点列表
|
|
|
this.pointList.forEach(it => {
|
|
|
let x = it.x,
|
|
|
y = it.y;
|
|
|
+ // 保存 x 最小值
|
|
|
if (x < this.minX) {
|
|
|
this.minX = x;
|
|
|
}
|
|
|
|
|
|
+ // 保存 y 最小值
|
|
|
if (y < this.minY) {
|
|
|
this.minY = y;
|
|
|
}
|
|
|
|
|
|
+ // 保存 x 最大值
|
|
|
if (x > this.maxX) {
|
|
|
this.maxX = x;
|
|
|
}
|
|
|
|
|
|
+ // 保存 y 最大值
|
|
|
if (y > this.maxY) {
|
|
|
this.maxY = y;
|
|
|
}
|
|
@@ -891,6 +963,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
contains(x: number, y: number): boolean {
|
|
|
let arr = this.pointList;
|
|
|
+ // 轮廓线数据无效或者该点不在多边形内部
|
|
|
if (arr.length < 3 || !SPolygonUtil.pointIn(x, y, arr)) {
|
|
|
return false;
|
|
|
}
|
|
@@ -905,6 +978,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
*/
|
|
|
toData(): any {
|
|
|
this.moveToOrigin();
|
|
|
+ // 遍历顶点列表
|
|
|
const Line = this.pointList.map(pos => {
|
|
|
return {
|
|
|
x: pos.x,
|
|
@@ -929,6 +1003,7 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
resize(old: SSize, newS: SSize): void {
|
|
|
const xs = newS.width / old.width;
|
|
|
const ys = newS.height / old.height;
|
|
|
+ // 遍历顶点列表,
|
|
|
this.pointList = this.pointList.map(item => {
|
|
|
item.x = item.x * xs;
|
|
|
item.y = item.y * ys;
|
|
@@ -945,13 +1020,13 @@ export class SBasePolygonEdit extends SGraphEdit {
|
|
|
this.scenceLen = painter.toPx(this.len);
|
|
|
// 当状态为展示状态
|
|
|
if (this.status == SItemStatus.Normal) {
|
|
|
- // 闭合多边形
|
|
|
+ // 处于正常态
|
|
|
this.drawShowPolygon(painter, this.pointList);
|
|
|
} else if (this.status == SItemStatus.Create) {
|
|
|
- // 创建状态
|
|
|
+ // 处于创建态
|
|
|
this.drawCreatePolygon(painter, this.pointList);
|
|
|
} else {
|
|
|
- // 编辑状态
|
|
|
+ // 处于编辑状态
|
|
|
this.drawEditPolygon(painter, this.pointList);
|
|
|
}
|
|
|
}
|