Explorar o código

fix: 优化流程

bill hai 1 ano
pai
achega
951aa3daf7

+ 29 - 17
src/app/4dmap/path.ts

@@ -1,4 +1,5 @@
 import {
+  ShapeStylesStatusKey,
   WholeLinePolygon,
   WholeLinePolygonAttrib,
   mergeFuns,
@@ -7,10 +8,9 @@ import { polygonShapeFactory } from "../../board/packages/whole-line/style";
 import { Line } from "konva/lib/shapes/Line";
 import { Polygons } from "./polygons";
 import { Group } from "konva/lib/Group";
-import { watchEffect } from "vue";
+import { watch } from "vue";
 
-const polygonActShapeFactory = (attrib, tree) => {
-  const polygons = tree.parent as Polygons;
+const polygonActShapeFactory = () => {
   const act = polygonShapeFactory({
     autoClose: true,
   });
@@ -28,9 +28,6 @@ const polygonActShapeFactory = (attrib, tree) => {
     active() {
       path.fill("rgba(64, 158, 255, 0.3)");
       act.closeLine.active();
-      if (!polygons.status.newModel) {
-        polygons.bus.emit("clickPolygon", attrib);
-      }
     },
   };
   return result;
@@ -45,21 +42,36 @@ export class PoPath extends WholeLinePolygon<WholeLinePolygonAttrib, Group> {
   }
 
   protected initReactive() {
+    const updateStatus = (status: ShapeStylesStatusKey) => {
+      this.bus.emit("statusChange", { [status]: true });
+    };
+    updateStatus("common");
+
     const polygons = this.parent as unknown as Polygons;
+    this.bus.on("shapeStatusChange", ({ current, type }) => {
+      console.log(current, type);
+      if (polygons.status.editPolygonId) return;
+      if (current === "active") {
+        type === "click" &&
+          polygons.bus.emit("activePolygonId", this.attrib.id);
+      } else if (polygons.status.lightPolygonId === this.attrib.id) {
+        type === "click" && polygons.bus.emit("activePolygonId", null);
+      } else {
+        updateStatus(current);
+      }
+    });
+
     return mergeFuns(
       super.initReactive(),
-      watchEffect(
-        () => {
-          if (polygons.status.editPolygonId) {
-            if (polygons.status.editPolygonId === this.attrib.id) {
-              this.bus.emit("statusChange", { active: true });
-            } else {
-              this.bus.emit("statusChange", { common: true });
-            }
-          } else if (polygons.status.lightPolygonId === this.attrib.id) {
-            this.bus.emit("statusChange", { hover: true });
+      watch(
+        () => [polygons.status.editPolygonId, polygons.status.lightPolygonId],
+        ([eId, lId]) => {
+          if (eId === this.attrib.id) {
+            updateStatus("active");
+          } else if (lId === this.attrib.id) {
+            updateStatus("hover");
           } else {
-            this.bus.emit("statusChange", { active: false, hover: false });
+            updateStatus("common");
           }
         },
         { flush: "post" }

+ 19 - 12
src/app/4dmap/point.ts

@@ -15,7 +15,7 @@ import { Circle } from "konva/lib/shapes/Circle";
 import { Polygons } from "./polygons";
 import { point } from "../../board/packages/whole-line/style";
 import { Label, Tag } from "konva/lib/shapes/Label";
-import { watch } from "vue";
+import { watch, watchEffect } from "vue";
 
 const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: PoPoint) => {
   const polygons = tree.parent as unknown as Polygons;
@@ -115,6 +115,8 @@ const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: PoPoint) => {
     },
     hover: () => {
       label.visible(true);
+      out.fill("#409EFF");
+      select.fill("#409EFF");
     },
     setData(data: number[]) {
       let [width, height] = getRealAbsoluteSize(group, [1, 1]);
@@ -123,12 +125,6 @@ const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: PoPoint) => {
       group.y(data[1]);
       text.text(attrib.title || `P${attrib.id}`);
 
-      if (polygons.status.activePointId === attrib.id) {
-        label.visible(true);
-      } else {
-        label.visible(false);
-      }
-
       if (~tree.editPolygonNdx) {
         index.text((tree.editPolygonNdx + 1).toString()).visible(true);
         index.offsetX(-rect.width() / 2 + index.width() / 2);
@@ -146,10 +142,6 @@ const pointActShapeFactory = (attrib: PolygonsPointAttrib, tree: PoPoint) => {
         select.fill("#e0403c");
       }
     },
-    active() {
-      polygons.bus.emit("clickPoint", attrib);
-      label.visible(true);
-    },
   };
 
   return result;
@@ -178,6 +170,12 @@ export class PoPoint extends WholeLinePoint<PolygonsPointAttrib, Group> {
   }
 
   protected initReactive() {
+    const polygons = this.parent as unknown as Polygons;
+    this.bus.on("shapeStatusChange", ({ current }) => {
+      if (current === "active") {
+        polygons.bus.emit("clickPoint", this.attrib);
+      }
+    });
     return mergeFuns(
       super.initReactive(),
       watch(
@@ -210,7 +208,6 @@ export class PoPoint extends WholeLinePoint<PolygonsPointAttrib, Group> {
               }
             },
           });
-
           onCleanup(() => {
             anchor.off("mouseenter.anchor mouseleave.anchor");
             clearCursor && clearCursor();
@@ -218,6 +215,16 @@ export class PoPoint extends WholeLinePoint<PolygonsPointAttrib, Group> {
           });
         },
         { immediate: true }
+      ),
+      watchEffect(
+        () => {
+          if (polygons.status.lightPointId === this.attrib.id) {
+            this.bus.emit("statusChange", { hover: true });
+          } else {
+            this.bus.emit("statusChange", null);
+          }
+        },
+        { flush: "post" }
       )
     );
   }

+ 4 - 4
src/app/4dmap/polygons.ts

@@ -8,7 +8,6 @@ import {
   Attrib,
   WholeLinePoint,
   EntityEvent,
-  WholeLinePolygonAttrib,
   WholeLine,
   penWholeLinePoygonsEditWithHelperShapesMouse,
   getWholeLinePolygonLinesRaw,
@@ -69,7 +68,8 @@ const lineActShapeFactory = (attrib: PolygonsLineAttrib, tree: any) => {
 export type PolygonsStatus = {
   newModel: boolean;
   lightPolygonId?: string;
-  activePointId?: string;
+  activePolygonId?: string;
+  lightPointId?: string;
   editPolygonId?: string;
   selectPoiIds: string[];
 };
@@ -77,12 +77,12 @@ export class Polygons extends WholeLine<
   PolygonsAttrib & Attrib,
   EntityEvent & {
     clickPoint: PolygonsPointAttrib;
-    clickPolygon: WholeLinePolygonAttrib;
+    activePolygonId: string;
     penEndHandler: void;
   }
 > {
   status: PolygonsStatus = reactive({
-    selectPoiIds: ["108", "109", "110"],
+    selectPoiIds: [],
     newModel: false,
   });
 

+ 23 - 23
src/board/packages/container.ts

@@ -115,29 +115,29 @@ export class Container<
           });
         },
         (instance) => {
-          entityTreeExecute(instance, (entity) => {
-            if (!(entity as any).actShape?.active || entity.activeDestory)
-              return;
-            entity.enableActive((actived) => {
-              if (actived) {
-                if (active !== entity) {
-                  this.bus.emit("active", entity);
-                  active = entity;
-                }
-              } else {
-                if (active === entity) {
-                  this.bus.emit("active", null);
-                  active = null;
-                }
-              }
-            });
-            entity.bus.on("destroyed", () => {
-              if (active === entity) {
-                this.bus.emit("active", null);
-                active = null;
-              }
-            });
-          });
+          // entityTreeExecute(instance, (entity) => {
+          //   if (!(entity as any).actShape?.active || entity.activeDestory)
+          //     return;
+          //   entity.enableActive((actived) => {
+          //     if (actived) {
+          //       if (active !== entity) {
+          //         this.bus.emit("active", entity);
+          //         active = entity;
+          //       }
+          //     } else {
+          //       if (active === entity) {
+          //         this.bus.emit("active", null);
+          //         active = null;
+          //       }
+          //     }
+          //   });
+          //   entity.bus.on("destroyed", () => {
+          //     if (active === entity) {
+          //       this.bus.emit("active", null);
+          //       active = null;
+          //     }
+          //   });
+          // });
         }
       );
     }

+ 12 - 1
src/board/packages/entity.ts

@@ -1,5 +1,11 @@
 import konva from "konva";
-import { Attrib, ShapeStyles, ShapeStylesStatus, ShapeType } from "../type";
+import {
+  Attrib,
+  ShapeStyles,
+  ShapeStylesStatus,
+  ShapeStylesStatusKey,
+  ShapeType,
+} from "../type";
 import { DEV } from "../env";
 import { Group } from "konva/lib/Group";
 import { Layer } from "konva/lib/Layer";
@@ -40,6 +46,11 @@ export type EntityEvent = {
   mounted: void;
   destroyed: void;
   statusChange: Partial<ShapeStylesStatus> | null;
+  shapeStatusChange: {
+    type?: "click" | "mouse";
+    current: ShapeStylesStatusKey;
+    before: ShapeStylesStatusKey;
+  };
   "*": void;
 };
 

+ 77 - 1
src/board/shared/entity-utils.ts

@@ -2,11 +2,12 @@ import { KonvaEventObject } from "konva/lib/Node";
 import { hasTouchEvents } from "../env";
 import { Container } from "../packages";
 import { EntityType, Entity } from "../packages/entity";
-import { Attrib, ShapeType } from "../type";
+import { Attrib, ShapeStylesStatusKey, ShapeType } from "../type";
 import { getTouchOffset } from "./act";
 import { createLineByDire, getLineProjection } from "./math";
 import { disableMouse, enableMouse } from "./shape-mose";
 import { generateId, getChangeAllPoart } from "./util";
+import { computed, ref, watch, watchEffect } from "vue";
 
 const getExtendsProps = (parent: Entity<any, any>) => {
   return parent
@@ -205,3 +206,78 @@ export const addEntityAttrib = (
     interrupt,
   };
 };
+
+const updateEntityStatus = (entity: Entity, status: ShapeStylesStatusKey) => {
+  entity.bus.emit("statusChange", { [status]: true });
+};
+
+export const entityActiveDualControl = (entity: Entity) => {
+  const light = ref(false);
+  const active = ref(false);
+
+  entity.bus.on("shapeStatusChange", ({ current, type }) => {
+    if (current === "active") {
+      active.value = !active.value;
+    } else if (type === "click") {
+      active.value = false;
+    } else if (!active.value) {
+      light.value = !!current;
+    }
+  });
+  const updateStatus = (status: ShapeStylesStatusKey) => {
+    entity.bus.emit("statusChange", { [status]: true });
+  };
+
+  const stop = watch(
+    () => [light.value, active.value],
+    ([light, active]) => {
+      if (active) {
+        updateStatus("active");
+      } else if (light) {
+        updateStatus("hover");
+      } else {
+        updateStatus("common");
+      }
+    },
+    { flush: "post" }
+  );
+
+  return {
+    light,
+    active,
+    stop,
+  };
+};
+
+export const entitysActiveDualControl = (entitys: Entity[]) => {
+  const activeId = ref<string | null>();
+  const lightId = ref<string | null>();
+  const dualControls = entitys.map(entityActiveDualControl);
+
+  entitys.forEach((entity) => {
+    entity.bus.on("destroyed", () => {
+      const ndx = entitys.indexOf(entity);
+      if (~ndx) {
+        dualControls[ndx].stop();
+        dualControls.splice(ndx, 1);
+        entitys.splice(ndx, 1);
+      }
+    });
+  });
+
+  watchEffect(() => {
+    for (let i = 0; i < dualControls.length; i++) {
+      const { active, light } = dualControls[i];
+      if (active.value) {
+        activeId.value = entitys[i].attrib.id;
+      } else if (activeId.value === entitys[i].attrib.id) {
+        activeId.value = null;
+      }
+      if (light.value) {
+        lightId.value = entitys[i].attrib.id;
+      } else if (lightId.value === entitys[i].attrib.id) {
+        lightId.value = null;
+      }
+    }
+  });
+};

+ 85 - 59
src/board/shared/shape-mose.ts

@@ -1,4 +1,10 @@
-import { Attrib, ShapeStyles, ShapeStylesStatus, ShapeType } from "../type";
+import {
+  Attrib,
+  ShapeStyles,
+  ShapeStylesStatus,
+  ShapeStylesStatusKey,
+  ShapeType,
+} from "../type";
 import { Entity } from "../packages/entity";
 import { Shape } from "konva/lib/Shape";
 import { Group } from "konva/lib/Group";
@@ -8,7 +14,6 @@ import { KonvaEventObject } from "konva/lib/Node";
 let mouseDisabled = false;
 const dragShapes: (Shape | Group)[] = [];
 export const disableMouse = () => {
-  console.log("disable mose");
   mouseDisabled = true;
   dragShapes.forEach((shape) => shape.draggable(false));
 };
@@ -42,9 +47,6 @@ export const openShapeMouseStyles = <T extends Shape | Group>(
   if (styles.bus) {
     styles.bus.on("statusChange", (status) => {
       outStatus = status;
-      if (status) {
-        Object.assign(inStatus, status);
-      }
       mouseHandler();
     });
   }
@@ -55,79 +57,103 @@ export const openShapeMouseStyles = <T extends Shape | Group>(
     active: false,
     common: false,
   };
-  let prevApi = "common";
+  let prevApi: ShapeStylesStatusKey = "common";
+  let prevInApi: ShapeStylesStatusKey = "common";
+  let prevInType: "click" | "mouse";
+  const mouseHandler = (
+    ev?: KonvaEventObject<any>,
+    type?: "click" | "mouse"
+  ) => {
+    const inApi = getActiveKey(inStatus);
+    if (styles.bus && (prevInApi !== inApi || prevInType !== type)) {
+      const before = prevApi;
+      prevInApi = inApi;
+      styles.bus.emit("shapeStatusChange", {
+        current: inApi,
+        before: before,
+        type,
+      });
+    }
 
-  const mouseHandler = (ev?: KonvaEventObject<any>) => {
-    let api: string = outStatus && getActiveKey(outStatus);
-    if (!api) {
-      api = mouseDisabled ? "common" : getActiveKey(inStatus) || "common";
+    let api: ShapeStylesStatusKey = outStatus
+      ? getActiveKey(outStatus)
+      : mouseDisabled
+      ? null
+      : inApi;
+
+    const ls = outStatus ? [outStatus, inStatus] : [inStatus];
+    for (const l of ls) {
+      const showStatus = { ...l };
+      while (api && !(api in styles)) {
+        console.log(shape.id(), api, styles);
+        showStatus[api] = false;
+        api = getActiveKey(showStatus);
+      }
+      if (api) break;
     }
+
+    // console.log(shape.id(), api, outStatus);
+    api = api || "common";
     if (prevApi !== api) {
-      styles[api] && styles[api](ev);
+      styles[api](ev);
       prevApi = api;
     }
   };
 
-  if (styles.hover) {
-    useOn(`mouseenter.${namespace}`, (ev) => {
-      inStatus.hover = true;
-      mouseHandler(ev);
-    });
-    useOn(`mouseleave.${namespace}`, (ev) => {
-      inStatus.hover = false;
-      mouseHandler(ev);
-    });
-  }
+  useOn(`mouseenter.${namespace}`, (ev) => {
+    inStatus.hover = true;
+    mouseHandler(ev, "mouse");
+  });
+  useOn(`mouseleave.${namespace}`, (ev) => {
+    inStatus.hover = false;
+    mouseHandler(ev, "mouse");
+  });
 
   let unCheckActive: () => void;
-  if (styles.active) {
-    let clickTime: number = 0;
-    useOn(`click.${namespace} touchend.${namespace}`, (ev) => {
-      if (!styles.active) return;
-      inStatus.active = true;
-      mouseHandler(ev);
-      clickTime = Date.now();
-    });
+  let clickTime: number = 0;
+  useOn(`click.${namespace} touchend.${namespace}`, (ev) => {
+    inStatus.active = true;
+    mouseHandler(ev, "click");
+    clickTime = Date.now();
+  });
 
-    const e = `click.${namespace}${shape.id()} touchend.${namespace}${shape.id()}`;
-    let count = 3;
-    let stage;
-    let tip = false;
-    const interval = setInterval(() => {
-      if (!(stage = shape.getStage())) {
-        if (count < -5) {
-          clearInterval(interval);
-          console.log(shape.name(), shape.id());
-        }
-        if (--count < 0) {
-          tip && console.error("可能发生资源泄露");
-          tip = true;
-        }
-        return;
+  const e = `click.${namespace}${shape.id()} touchend.${namespace}${shape.id()}`;
+  let count = 3;
+  let stage;
+  let tip = false;
+  const interval = setInterval(() => {
+    if (!(stage = shape.getStage())) {
+      if (count < -5) {
+        clearInterval(interval);
       }
-      clearInterval(interval);
-      stage.on(e, (evt) => {
-        if (Date.now() - clickTime > 500 && evt.target !== shape) {
-          inStatus.active = false;
-          mouseHandler(evt);
-        }
-      });
-    }, 100);
+      if (--count < 0) {
+        tip && console.error("可能发生资源泄露");
+        tip = true;
+      }
+      return;
+    }
+    clearInterval(interval);
+    stage.on(e, (evt) => {
+      if (Date.now() - clickTime > 50 && evt.target !== shape) {
+        inStatus.active = false;
+        mouseHandler(evt, "click");
+      }
+    });
+  }, 100);
 
-    unCheckActive = () => {
-      stage && stage.off(e);
-      clearInterval(interval);
-    };
-  }
+  unCheckActive = () => {
+    stage && stage.off(e);
+    clearInterval(interval);
+  };
 
   useOn(`dragstart.${namespace}`, (ev) => {
     inStatus.draging = true;
-    mouseHandler(ev);
+    mouseHandler(ev, "mouse");
   });
   useOn(`dragend.${namespace}`, (ev) => {
     setTimeout(() => {
       inStatus.draging = false;
-      mouseHandler(ev);
+      mouseHandler(ev, "mouse");
     }, 16);
   });
 

+ 10 - 2
src/board/type.ts

@@ -15,6 +15,7 @@ export type GetSetPick<T extends Shape | Group> = {
   [key in keyof T]?: T[key] extends GetSet<infer V, T> ? V : never;
 };
 
+export type ShapeStylesStatusKey = "common" | "hover" | "active" | "draging";
 export type ShapeStylesStatus = {
   draging: boolean;
   hover: boolean;
@@ -23,11 +24,18 @@ export type ShapeStylesStatus = {
 };
 export type ShapeStyles = {
   common: (ev?: KonvaEventObject<any>) => void;
-  bus?: Emitter<{ statusChange: Partial<ShapeStylesStatus> | null }>;
+  bus?: Emitter<{
+    statusChange: Partial<ShapeStylesStatus> | null;
+    shapeStatusChange: {
+      type?: "click" | "mouse";
+      current: ShapeStylesStatusKey;
+      before: ShapeStylesStatusKey;
+    };
+  }>;
   getStatus?: (
     status: ShapeStylesStatus,
     ev: KonvaEventObject<any>
-  ) => "common" | "hover" | "active" | "draging" | null;
+  ) => ShapeStylesStatusKey | null;
   hover?: (ev?: KonvaEventObject<any>) => void;
   active?: (ev?: KonvaEventObject<any>) => void;
   draging?: (ev?: KonvaEventObject<any>) => void;