|
@@ -1,32 +1,17 @@
|
|
|
-import {
|
|
|
- PolygonsAttrib,
|
|
|
- PolygonsLineAttrib,
|
|
|
- PolygonsPointAttrib,
|
|
|
-} from "@/request/type";
|
|
|
+import { PolygonsAttrib, PolygonsPointAttrib } from "@/request/type";
|
|
|
import {
|
|
|
WholeLine,
|
|
|
- EntityDragHandlers,
|
|
|
- openEntityDrag,
|
|
|
- getRealAbsoluteSize,
|
|
|
incEntitysFactoryGenerate,
|
|
|
- WholeLineLine,
|
|
|
- WholeLinePoint,
|
|
|
Attrib,
|
|
|
- wholeLineFixLineAddPoint,
|
|
|
- wholeLinePolygonLastAddPoint,
|
|
|
- wholeLinePolygonAddPoint,
|
|
|
- wholeLineAddPoint,
|
|
|
- shapeParentsEq,
|
|
|
- getWholeLinePolygonPoints,
|
|
|
- wholeLineDelPointByPointIds,
|
|
|
+ penWholeLinePoygonsEdit,
|
|
|
} from "drawing-board";
|
|
|
import mitt from "mitt";
|
|
|
-import { Path } from "konva/lib/shapes/Path";
|
|
|
import { Group } from "konva/lib/Group";
|
|
|
-import { Circle } from "konva/lib/shapes/Circle";
|
|
|
import { Line } from "konva/lib/shapes/Line";
|
|
|
-import { Label, Tag } from "konva/lib/shapes/Label";
|
|
|
-import { Text } from "konva/lib/shapes/Text";
|
|
|
+import { PYLine } from "./line";
|
|
|
+import { PYPoint } from "./point";
|
|
|
+import { ref } from "vue";
|
|
|
+import { PYPolygon } from "./polygon";
|
|
|
|
|
|
// 加点
|
|
|
const getPolygonPoint = (position: number[]) => {
|
|
@@ -39,312 +24,65 @@ const getPolygonPoint = (position: number[]) => {
|
|
|
};
|
|
|
|
|
|
export class Polygons extends WholeLine<PolygonsAttrib & Attrib, Group, Line> {
|
|
|
+ currentId = ref<string>();
|
|
|
bus = mitt<{
|
|
|
hoverPoint: PolygonsPointAttrib | null;
|
|
|
activePoint: PolygonsPointAttrib;
|
|
|
}>();
|
|
|
- points: PolygonsPointAttrib[] = [];
|
|
|
- pointDragHandler = {} as EntityDragHandlers<PolygonsPointAttrib, number[]>;
|
|
|
-
|
|
|
- diffRedraw() {
|
|
|
- const inc = super.diffRedraw();
|
|
|
- inc.pointEntityInc.adds.forEach((point) => {
|
|
|
- if (!point.attrib.rtk) {
|
|
|
- openEntityDrag(point, this.pointDragHandler);
|
|
|
- }
|
|
|
- point.enableMouseAct(point.actShape);
|
|
|
- });
|
|
|
- inc.lineEntityInc.adds.forEach((line) => {
|
|
|
- line.enableMouseAct(line.actShape);
|
|
|
- });
|
|
|
- return inc;
|
|
|
- }
|
|
|
|
|
|
initIncFactory() {
|
|
|
- this.incLinesFactory = incEntitysFactoryGenerate(
|
|
|
- WholeLineLine<PolygonsLineAttrib, Line>,
|
|
|
- this,
|
|
|
- (line) => {
|
|
|
- line.setConfig(this.attrib);
|
|
|
- line.setActShapeFactory(lineActShapeFactory);
|
|
|
- }
|
|
|
+ this.incLinesFactory = incEntitysFactoryGenerate(PYLine, this, (line) =>
|
|
|
+ line.setConfig(this.attrib)
|
|
|
);
|
|
|
- this.incPointsFactory = incEntitysFactoryGenerate(
|
|
|
- WholeLinePoint<PolygonsPointAttrib, Group>,
|
|
|
+ this.incPointsFactory = incEntitysFactoryGenerate(PYPoint, this);
|
|
|
+
|
|
|
+ this.incPolygonFactory = incEntitysFactoryGenerate(
|
|
|
+ PYPolygon,
|
|
|
this,
|
|
|
- (point) => {
|
|
|
- point.setActShapeFactory(pointActShapeFactory);
|
|
|
+ (py) => {
|
|
|
+ py.setConfig(this.attrib);
|
|
|
}
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- currentPolygonId: string | null = null;
|
|
|
-
|
|
|
- enableAddMode(polygonId: string) {
|
|
|
- this.modeDestory();
|
|
|
- this.currentPolygonId = polygonId;
|
|
|
-
|
|
|
- const polyginAttrib = this.attrib.polygons.find(
|
|
|
- ({ id }) => id === polygonId
|
|
|
- );
|
|
|
- if (!polyginAttrib) return;
|
|
|
-
|
|
|
- const root = this.container;
|
|
|
- const stage = root.stage;
|
|
|
- let prevPid: string;
|
|
|
- stage.on("click.addMode", (evt) => {
|
|
|
- const target = shapeParentsEq(evt.target, (shape) => {
|
|
|
- const id = shape.id();
|
|
|
- return (
|
|
|
- id.includes(WholeLineLine.namespace) ||
|
|
|
- id.includes(WholeLinePoint.namespace)
|
|
|
- );
|
|
|
- });
|
|
|
- const child = target && this.find(target.id());
|
|
|
- const pixel = [evt.evt.x, evt.evt.y];
|
|
|
-
|
|
|
- if (child instanceof WholeLineLine) {
|
|
|
- wholeLineFixLineAddPoint(
|
|
|
- this.attrib,
|
|
|
- child.attrib.id,
|
|
|
- getPolygonPoint(root.getRealFromStage(pixel))
|
|
|
- );
|
|
|
- } else {
|
|
|
- const pointAttrib =
|
|
|
- child instanceof WholeLinePoint
|
|
|
- ? child.attrib
|
|
|
- : getPolygonPoint(this.container.getRealFromStage(pixel));
|
|
|
-
|
|
|
- const exixts = getWholeLinePolygonPoints(
|
|
|
- this.attrib,
|
|
|
- polyginAttrib.id
|
|
|
- ).some(({ id }) => id === pointAttrib.id);
|
|
|
-
|
|
|
- if (exixts) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (polyginAttrib.lineIds.length > 0) {
|
|
|
- wholeLinePolygonLastAddPoint(this.attrib, polygonId, pointAttrib);
|
|
|
- } else if (prevPid) {
|
|
|
- wholeLinePolygonAddPoint(
|
|
|
- this.attrib,
|
|
|
- polygonId,
|
|
|
- prevPid,
|
|
|
- pointAttrib
|
|
|
- );
|
|
|
- } else {
|
|
|
- prevPid = wholeLineAddPoint(this.attrib, pointAttrib)!.id as string;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- this.redraw();
|
|
|
+ removePolygon(polygonId: string) {
|
|
|
+ const ndx = this.attrib.polygons.findIndex(({ id }) => id === polygonId);
|
|
|
+ if (~ndx) {
|
|
|
+ this.attrib.polygons.splice(ndx, 1);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- enableDelMode(polygonId: string) {
|
|
|
- this.currentPolygonId = polygonId;
|
|
|
- this.modeDestory();
|
|
|
-
|
|
|
- const polyginAttrib = this.attrib.polygons.find(
|
|
|
- ({ id }) => id === polygonId
|
|
|
- );
|
|
|
- if (!polyginAttrib) return;
|
|
|
-
|
|
|
- const root = this.container;
|
|
|
- const stage = root.stage;
|
|
|
- stage.on("click.delMode", (evt) => {
|
|
|
- const target = shapeParentsEq(evt.target, (shape) => {
|
|
|
- const id = shape.id();
|
|
|
- return id.includes(WholeLinePoint.namespace);
|
|
|
- });
|
|
|
- const child = target && this.find(target.id());
|
|
|
- if (child) {
|
|
|
- const pointAttrib = child.attrib as PolygonsPointAttrib;
|
|
|
- wholeLineDelPointByPointIds(
|
|
|
- this.attrib,
|
|
|
- pointAttrib.id,
|
|
|
- !pointAttrib.rtk
|
|
|
- );
|
|
|
- }
|
|
|
+ private _leaveEditMode: (() => void) | void = void 0;
|
|
|
+ enterEditMode(polygonId?: string) {
|
|
|
+ const { continuous, end } = penWholeLinePoygonsEdit({
|
|
|
+ tree: this.container,
|
|
|
+ config: this.attrib,
|
|
|
+ polygonId,
|
|
|
+ pointAttribFactory: getPolygonPoint,
|
|
|
+ quotePoint: false,
|
|
|
+ canDelPoint: (p) => !p.rtk,
|
|
|
+ changePolygon: (pid) => {
|
|
|
+ this.currentId.value = pid;
|
|
|
+ },
|
|
|
});
|
|
|
|
|
|
- this.redraw();
|
|
|
- }
|
|
|
-
|
|
|
- private modeDestory() {
|
|
|
- this.container.stage.off("click.addMode");
|
|
|
- this.container.stage.off("click.delMode");
|
|
|
+ this.container.stage.on("click.editPolygonsMode", continuous);
|
|
|
+ this._leaveEditMode = () => {
|
|
|
+ this.container.stage.off("click.editPolygonsMode", continuous);
|
|
|
+ end();
|
|
|
+ };
|
|
|
}
|
|
|
-
|
|
|
- commonMode() {
|
|
|
- this.currentPolygonId = null;
|
|
|
- this.modeDestory();
|
|
|
- this.redraw();
|
|
|
+ leaveEditMode() {
|
|
|
+ this._leaveEditMode && this._leaveEditMode();
|
|
|
}
|
|
|
|
|
|
- init() {
|
|
|
- this.pointDragHandler = {
|
|
|
- readyHandler: (attrib) => {
|
|
|
- return [attrib.x, attrib.y];
|
|
|
- },
|
|
|
- moveHandler: (pointAttrib, move) => {
|
|
|
- pointAttrib.x = move[0];
|
|
|
- pointAttrib.y = move[1];
|
|
|
- },
|
|
|
- };
|
|
|
- super.init();
|
|
|
- }
|
|
|
mounted(): void {
|
|
|
super.mounted();
|
|
|
- this.enableAddMode("1");
|
|
|
+ this.enterEditMode("1");
|
|
|
}
|
|
|
|
|
|
destory(): void {
|
|
|
super.destory();
|
|
|
- this.modeDestory();
|
|
|
+ this.leaveEditMode();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: any) => {
|
|
|
- const polygons = tree.parent as Polygons;
|
|
|
- const size = { width: 40, height: 40 };
|
|
|
- const out = new Path({
|
|
|
- data: `M22 44C32.6667 33.891 38 25.891 38 20C38 11.1634 30.8366 4 22 4C13.1634 4 6 11.1634 6 20C6 25.891 11.3333 33.891 22 44Z`,
|
|
|
- });
|
|
|
- const inner = new Path({
|
|
|
- fill: "#fff",
|
|
|
- data: `M22 30C27.5228 30 32 25.5228 32 20C32 14.4772 27.5228 10 22 10C16.4772 10 12 14.4772 12 20C12 25.5228 16.4772 30 22 30Z`,
|
|
|
- });
|
|
|
- const rect = new Circle({
|
|
|
- radius: Math.min(size.width, size.height) / 2,
|
|
|
- fill: "rgba(0, 0, 0, 0)",
|
|
|
- offset: { x: -size.width / 2, y: -size.height / 2 },
|
|
|
- });
|
|
|
- const index = new Text({
|
|
|
- name: "text",
|
|
|
- text: `1`,
|
|
|
- fontFamily: "Calibri",
|
|
|
- fontSize: 12,
|
|
|
- padding: 5,
|
|
|
- offsetY: -8,
|
|
|
- fill: "#000",
|
|
|
- });
|
|
|
-
|
|
|
- const label = new Label({
|
|
|
- visible: false,
|
|
|
- opacity: 0.75,
|
|
|
- name: "label",
|
|
|
- offsetX: -size.width / 2,
|
|
|
- offsetY: -6,
|
|
|
- });
|
|
|
-
|
|
|
- label.add(
|
|
|
- new Tag({
|
|
|
- name: "tag",
|
|
|
- fill: "rgba(255, 255, 255, 0.8)",
|
|
|
- pointerDirection: "down",
|
|
|
- pointerWidth: 5,
|
|
|
- pointerHeight: 5,
|
|
|
- lineJoin: "round",
|
|
|
- shadowColor: "black",
|
|
|
- shadowBlur: 10,
|
|
|
- shadowOffsetX: 10,
|
|
|
- shadowOffsetY: 10,
|
|
|
- shadowOpacity: 0.5,
|
|
|
- }),
|
|
|
- new Text({
|
|
|
- name: "text",
|
|
|
- text: `P${attrib.id}`,
|
|
|
- fontFamily: "Calibri",
|
|
|
- fontSize: 10,
|
|
|
- padding: 5,
|
|
|
- fill: "#000",
|
|
|
- })
|
|
|
- );
|
|
|
-
|
|
|
- const offsetGroup = new Group();
|
|
|
- offsetGroup.add(out, inner, rect, label, index);
|
|
|
- offsetGroup.x(-size.width / 2);
|
|
|
- offsetGroup.y(-size.height);
|
|
|
-
|
|
|
- const group = new Group();
|
|
|
- group.add(offsetGroup);
|
|
|
-
|
|
|
- const setStyle = () => {
|
|
|
- let [width, height] = getRealAbsoluteSize(group, [1, 1]);
|
|
|
- group.scale({ x: width, y: height });
|
|
|
-
|
|
|
- if (polygons.currentPolygonId) {
|
|
|
- const points = getWholeLinePolygonPoints(
|
|
|
- polygons.attrib,
|
|
|
- polygons.currentPolygonId
|
|
|
- ).map(({ id }) => id);
|
|
|
- const ndx = points.indexOf(attrib.id);
|
|
|
- if (~ndx) {
|
|
|
- index.text((ndx + 1).toString()).visible(true);
|
|
|
- index.offsetX(-rect.width() / 2 + index.width() / 2.5);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- index.visible(false);
|
|
|
- };
|
|
|
-
|
|
|
- const result = {
|
|
|
- shape: group,
|
|
|
- common: () => {
|
|
|
- out.fill(attrib.rtk ? "#728190" : "#409EFF");
|
|
|
- label.visible(false);
|
|
|
- polygons.bus.emit("hoverPoint", null);
|
|
|
- },
|
|
|
- hover: () => {
|
|
|
- out.fill(attrib.rtk ? "#728190" : "#E6A23C");
|
|
|
- label.visible(true);
|
|
|
- polygons.bus.emit("hoverPoint", tree.attrib);
|
|
|
- },
|
|
|
- setData(data: number[]) {
|
|
|
- setStyle();
|
|
|
- group.x(data[0]);
|
|
|
- group.y(data[1]);
|
|
|
- },
|
|
|
- active() {
|
|
|
- out.fill("#E6A23C");
|
|
|
- if (!polygons.currentPolygonId) {
|
|
|
- polygons.bus.emit("activePoint", tree.attrib);
|
|
|
- }
|
|
|
- },
|
|
|
- draging() {
|
|
|
- out.fill("#E6A23C");
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- if (attrib.rtk) {
|
|
|
- return result;
|
|
|
- } else {
|
|
|
- return {
|
|
|
- ...result,
|
|
|
- draging() {
|
|
|
- out.fill("#E6A23C");
|
|
|
- },
|
|
|
- };
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const lineActShapeFactory = () => {
|
|
|
- const line = new Line({
|
|
|
- strokeScaleEnabled: false,
|
|
|
- strokeWidth: 5,
|
|
|
- });
|
|
|
- return {
|
|
|
- shape: line,
|
|
|
- setData(data: number[]) {
|
|
|
- line.points(data);
|
|
|
- },
|
|
|
- common: () => {
|
|
|
- line.stroke("#FFFFFF");
|
|
|
- },
|
|
|
- hover: () => {
|
|
|
- line.stroke("#FF0000");
|
|
|
- },
|
|
|
- };
|
|
|
-};
|