Переглянути джерело

feat: 线段采用配置式渲染

bill 1 місяць тому
батько
коміт
f513118d09

+ 20 - 10
src/core/components/line-icon/icon.vue

@@ -45,6 +45,7 @@ import {
   Pos,
 } from "@/utils/math.ts";
 import { copy } from "@/utils/shared.ts";
+import { useTestPoints } from "@/core/hook/use-debugger.ts";
 
 const props = defineProps<{ data: LineIconData }>();
 const emit = defineEmits<{
@@ -57,6 +58,7 @@ const store = useStore();
 const getOperType = useGetTransformerOperType();
 const viewMat = useViewerInvertTransform();
 const pos = usePointerPos();
+const testPoints = useTestPoints();
 const { shape, tData, data, operateMenus, describes } = useComponentStatus({
   emit,
   props,
@@ -86,21 +88,29 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
       },
       handler(data, mat) {
         if (pos.value && !getOperType()) {
-          if (!posOffset) {
-            const real = viewMat.value.point(pos.value);
-            const prevDec = prevInvMat.decompose();
-            posOffset = {
-              x: real.x - prevDec.x,
-              y: real.y - prevDec.y,
-            };
-          }
+          // if (!posOffset) {
+          //   const real = viewMat.value.point(pos.value);
+          //   const prevDec = prevInvMat.decompose();
+          //   posOffset = {
+          //     x: real.x - prevDec.x,
+          //     y: real.y - prevDec.y,
+          //   };
+          //   testPoints.value = [
+          //     {
+          //       x: real.x - posOffset.x,
+          //       y: real.y - posOffset.y,
+          //     },
+          //   ];
+          // }
           const rpos = viewMat.value.point({
             x: pos.value.x,
             y: pos.value.y,
           });
           const m = mat.m;
-          m[4] = rpos.x - posOffset.x;
-          m[5] = rpos.y - posOffset.y;
+          m[4] = rpos.x;
+          m[5] = rpos.y;
+          // m[4] = rpos.x - posOffset.x;
+          // m[5] = rpos.y - posOffset.y;
           mat = new Transform(m);
         }
         matResponse({

+ 1 - 1
src/core/components/line-icon/index.ts

@@ -64,7 +64,7 @@ export const isRangInner = (line: Pos[], data: LineIconData) => {
   const len = lineLen(line[0], line[1]);
   return (
     data.startLen >= 0 &&
-    data.startLen >= 0 &&
+    data.endLen >= 0 &&
     data.startLen <= len &&
     data.endLen <= len
   );

+ 16 - 2
src/core/components/line/index.ts

@@ -11,8 +11,9 @@ import {
 } from "@/core/hook/use-selection.ts";
 import { EntityShape } from "@/deconstruction.js";
 import mitt from "mitt";
-import { watch } from "vue";
+import { Ref, ref, watch } from "vue";
 import { getInitCtx, NLineDataCtx, normalLineData } from "./attach-server.ts";
+import * as wallRenderer from "./renderer/wall";
 
 export { default as Component } from "./line.vue";
 export { default as TempComponent } from "./temp-line.vue";
@@ -25,6 +26,19 @@ export const defaultStyle = {
   dash: [30, 0],
 };
 
+export const renderer = ref<{
+  genGetShapeAttrib: (data: Ref<LineData | undefined>) => any;
+  Component: any;
+}>();
+export const setRendererType = async (type?: "wall" | "db-line") => {
+  if (type === "wall") {
+    renderer.value = wallRenderer;
+  } else {
+    renderer.value = undefined;
+  }
+};
+setRendererType("wall");
+
 export const addMode = "single-dots";
 
 export const getMouseStyle = (data: LineData) => {
@@ -69,7 +83,7 @@ export type LineDataLine = {
   stroke: string;
   dash: number[];
 };
-export type LineDataPoint = Pos & { id: string }
+export type LineDataPoint = Pos & { id: string };
 export type LineData = Partial<typeof defaultStyle> &
   BaseItem & {
     points: LineDataPoint[];

+ 5 - 0
src/core/components/line/renderer/wall/index.ts

@@ -0,0 +1,5 @@
+import { useGetExtendPolygon } from "./view";
+import Component from './index.vue'
+
+export const genGetShapeAttrib = useGetExtendPolygon
+export { Component }

+ 54 - 0
src/core/components/line/renderer/wall/index.vue

@@ -0,0 +1,54 @@
+<template>
+  <v-line
+    v-for="polygon in polygons"
+    :config="{
+      opacity: opacity,
+      points: flatPositions(polygon),
+      fill: stroke,
+      closed: true,
+      listening: false,
+    }"
+  />
+
+  <template v-if="showLabel">
+    <v-group>
+      <template v-if="gd.steps.value.length">
+        <SizeLine
+          :points="line"
+          :strokeWidth="props.line.strokeWidth"
+          :stroke="props.line.stroke"
+          v-for="line in [...gd.steps.value, ...gd.subSteps.value]"
+        />
+      </template>
+      <SizeLine
+        :points="points"
+        :strokeWidth="props.line.strokeWidth"
+        :stroke="props.line.stroke"
+        v-else
+      />
+    </v-group>
+  </template>
+</template>
+
+<script lang="ts" setup>
+import { computed } from "vue";
+import { useGetDiffLineIconPolygons, useGetExtendPolygon } from "./view";
+import { LineData, LineDataLine } from "../..";
+import { getLinePoints } from "../../attach-server";
+import { flatPositions } from "@/utils/shared";
+import SizeLine from "../../../share/size-line.vue";
+
+const props = defineProps<{
+  getShapeAttrib: ReturnType<typeof useGetExtendPolygon>;
+  data: LineData;
+  line: LineDataLine;
+  opacity?: number;
+  stroke?: string;
+  showLabel: any;
+}>();
+
+const polygon = computed(() => props.getShapeAttrib(props.line));
+const points = computed(() => getLinePoints(props.data, props.line));
+const gd = useGetDiffLineIconPolygons(props.line, points);
+const polygons = computed(() => gd.diff(polygon.value));
+</script>

+ 4 - 61
src/core/components/line/attach-view.ts

@@ -10,16 +10,13 @@ import {
   Pos,
   verticalVector,
 } from "@/utils/math";
-import { LineData, LineDataLine } from ".";
-import { getJoinLine, getLinePoints } from "./attach-server";
+import { LineData, LineDataLine } from "../..";
+import { getJoinLine, getLinePoints } from "../../attach-server";
 import { MathUtils } from "three";
 import { diffArrayChange, round } from "@/utils/shared";
-import { globalWatch, installGlobalVar } from "@/core/hook/use-global-vars";
 import { useStore } from "@/core/store";
-import { computed, nextTick, reactive, Ref, watch, watchEffect } from "vue";
-import { Transform } from "konva/lib/Util";
-import { sortFn } from "@/core/store/store";
-import { getLineIconEndpoints } from "../line-icon";
+import { computed, nextTick, reactive, Ref, watch } from "vue";
+import { getLineIconEndpoints } from "../../../line-icon";
 import { useDrawIngData } from "@/core/hook/use-draw";
 import { polygonDifference, polygonDifferenceOnly } from "@/utils/math-clip";
 
@@ -260,60 +257,6 @@ export const useGetExtendPolygon = (lineData: Ref<LineData | undefined>) => {
 };
 
 // 计算与icon相差的多边形
-export const useGetDiffIconPolygons = installGlobalVar(() => {
-  const store = useStore();
-  const iconPolygons = reactive({}) as { [key in string]: Pos[] };
-  const icons = computed(() => store.getTypeItems("icon"));
-  const line = computed(() => store.getTypeItems("line")[0]);
-  const watchIcon = (id: string) => {
-    const stopWatch = watchEffect(() => {
-      const icon = icons.value.find((item) => item.id === id);
-      if (!icon) {
-        stopWatch();
-        delete iconPolygons[id];
-        return;
-      }
-      if (!line.value || sortFn(line.value, icon) > 0) {
-        delete iconPolygons[id];
-        return;
-      }
-
-      const rect = [
-        { x: -icon.width / 2, y: -icon.height / 2 },
-        { x: icon.width / 2, y: -icon.height / 2 },
-        { x: icon.width / 2, y: icon.height / 2 },
-        { x: -icon.width / 2, y: icon.height / 2 },
-      ];
-      const mat = new Transform(icon.mat);
-      iconPolygons[id] = rect.map((p) => mat.point(p));
-    });
-  };
-
-  const stopWatch = globalWatch(
-    () => {
-      return icons.value.map((item) => item.id);
-    },
-    (ids, oIds = []) => {
-      const { added, deleted } = diffArrayChange(ids, oIds);
-      deleted.forEach((id) => {
-        delete iconPolygons[id];
-      });
-      added.forEach(watchIcon);
-    },
-    { immediate: true }
-  );
-
-  return {
-    var: (polygon: Pos[]) => {
-      const targets = Object.values(iconPolygons);
-      if (!targets.length) return [polygon];
-      return polygonDifference(polygon, targets);
-    },
-    onDestroy: stopWatch,
-  };
-});
-
-// 计算与icon相差的多边形
 export const useGetDiffLineIconPolygons = (
   line: LineDataLine,
   linePoints: Ref<Pos[]>

+ 21 - 47
src/core/components/line/single-line.vue

@@ -5,7 +5,7 @@
   <EditLine
     :ref="(d: any) => shape = d?.shape"
     :data="lineData"
-    :opacity="0"
+    :opacity="renderer ? 0 : 1"
     :points="points"
     :closed="false"
     :id="line.id"
@@ -22,45 +22,22 @@
     @add-point="addPoint"
   />
 
-  <v-line
-    v-for="polygon in polygons"
-    :config="{
-      opacity: drawProps ? 0.7 : 1,
-      points: flatPositions(polygon),
-      fill: isDrawIng ? themeColor : style.stroke,
-      closed: true,
-      listening: false,
-    }"
-  />
-  <!-- v-if="status.active" -->
-  <!-- <v-text :config="{ ...pointsCenter(points), text: line.id }" /> -->
-  <template
-    v-if="
+  <component
+    v-if="renderer"
+    :is="renderer?.Component"
+    :opacity="drawProps ? 0.7 : 1"
+    :stroke="isDrawIng ? themeColor : style.stroke"
+    :getShapeAttrib="getShapeAttrib"
+    :data="data"
+    :line="line"
+    :showLabel="
       status.active ||
       config.showComponentSize ||
       isDrawIng ||
       dragPointIds?.includes(line.a) ||
       dragPointIds?.includes(line.b)
     "
-  >
-    <v-group>
-      <template v-if="gd.steps.value.length">
-        <SizeLine
-          :points="line"
-          :strokeWidth="style.strokeWidth"
-          :stroke="style.stroke"
-          v-for="line in [...gd.steps.value, ...gd.subSteps.value]"
-        />
-      </template>
-      <SizeLine
-        :points="points"
-        :strokeWidth="style.strokeWidth"
-        :stroke="style.stroke"
-        v-else
-      />
-    </v-group>
-  </template>
-
+  />
   <PropertyUpdate
     :describes="describes"
     :data="line"
@@ -82,7 +59,7 @@
       :data="drawProps.data"
       :line="drawProps.prev"
       :drawMode="drawProps.point"
-      :get-extend-polygon="drawGetExtendPolygon"
+      :getShapeAttrib="drawGetShapeAttrib"
     />
     <singlePoint
       :data="drawProps.data"
@@ -93,7 +70,7 @@
       :data="drawProps.data"
       :line="drawProps.next"
       :drawMode="drawProps.point"
-      :get-extend-polygon="drawGetExtendPolygon"
+      :getShapeAttrib="drawGetShapeAttrib"
     />
     <singlePoint
       :data="drawProps.data"
@@ -107,12 +84,11 @@
 import EditLine from "../share/edit-line.vue";
 import singlePoint from "./single-point.vue";
 import { computed, ref } from "vue";
-import { getMouseStyle, LineData, LineDataLine, shapeName } from "./index.ts";
-import { flatPositions, onlyId } from "@/utils/shared.ts";
-import { pointsCenter, Pos } from "@/utils/math.ts";
+import { getMouseStyle, LineData, LineDataLine, shapeName, renderer } from "./index.ts";
+import { onlyId } from "@/utils/shared.ts";
+import { Pos } from "@/utils/math.ts";
 import { Line } from "konva/lib/shapes/Line";
 import { DC } from "@/deconstruction.js";
-import SizeLine from "../share/size-line.vue";
 import { useConfig } from "@/core/hook/use-config.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import {
@@ -120,7 +96,6 @@ import {
   useMouseShapeStatus,
 } from "@/core/hook/use-mouse-status.ts";
 import { themeColor } from "@/constant";
-import { useGetDiffLineIconPolygons, useGetExtendPolygon } from "./attach-view.ts";
 import {
   getLinePoints,
   useDrawLinePoint,
@@ -137,7 +112,7 @@ const props = defineProps<{
   data: LineData;
   dragPointIds?: string[];
   drawMode?: LineData["points"][number];
-  getExtendPolygon: (line: LineDataLine) => Pos[];
+  getShapeAttrib?: (line: LineDataLine) => any;
 }>();
 
 const emit = defineEmits<{
@@ -154,11 +129,8 @@ const emit = defineEmits<{
   (e: "dragLineEnd", value: LineDataLine): void;
 }>();
 
-const polygon = computed(() => props.getExtendPolygon(line.value));
 const line = computed(() => props.line);
 const points = computed(() => getLinePoints(props.data, props.line));
-const gd = useGetDiffLineIconPolygons(line.value, points);
-const polygons = computed(() => gd.diff(polygon.value));
 
 const shape = ref<DC<Line>>();
 const lineData = computed(() => props.line);
@@ -189,8 +161,10 @@ const { drawProps, enter: enterDrawLinePoint } = useDrawLinePoint(
   }
 );
 
-const drawGetExtendPolygon = useGetExtendPolygon(computed(() => drawProps.value?.data));
-
+const drawData = computed(() => drawProps.value?.data);
+const drawGetShapeAttrib = computed(
+  () => renderer.value && renderer.value.genGetShapeAttrib(drawData)
+);
 const menus = [
   { label: "加点", handler: enterDrawLinePoint },
   { label: "删除", handler: delHandler },

+ 5 - 4
src/core/components/line/temp-line.vue

@@ -19,7 +19,7 @@
         @dragLineStart="dragstartLineHandler"
         @dragLine="dragLineHandler"
         @dragLineEnd="dragendLineHandler"
-        :getExtendPolygon="getExtendPolygon"
+        :get-shape-attrib="getShapeAttrib"
       />
     </v-group>
     <v-group>
@@ -41,7 +41,7 @@
 </template>
 
 <script lang="ts" setup>
-import { delPoint, LineData } from "./index.ts";
+import { delPoint, LineData, renderer } from "./index.ts";
 import singleLine from "./single-line.vue";
 import singlePoint from "./single-point.vue";
 import { useInitData } from "./use-draw.ts";
@@ -60,7 +60,6 @@ import { useMouseShapeStatus } from "@/core/hook/use-mouse-status.ts";
 import { Pos } from "@/utils/math.ts";
 import { useSnapConfig, useSnapResultInfo } from "@/core/hook/use-snap.ts";
 import { Line } from "konva/lib/shapes/Line";
-import { useGetExtendPolygon } from "./attach-view.ts";
 
 const props = defineProps<{
   data: LineData;
@@ -79,7 +78,9 @@ const data = computed(() => {
   if (!initData.value || props.addMode) return props.data;
   return initData.value;
 });
-const getExtendPolygon = useGetExtendPolygon(computed(() => data.value));
+const getShapeAttrib = computed(
+  () => renderer.value && renderer.value.genGetShapeAttrib(data)
+);
 
 const dragPointIds = ref<string[]>();
 let track = false;

+ 5 - 3
src/example/platform/resource-swkk.ts

@@ -275,9 +275,11 @@ export const getAITaggingInfos = async (
   };
 
   for (const data of ais) {
-    const reg = data.imagePath.match(/floor_(\d)\.png/);
-    const curSubgroup = reg ? Number(reg[1]) : undefined;
-    if (curSubgroup !== subgroup) continue;
+    if (data.imagePath) {
+      const reg = data.imagePath.match(/floor_(\d)\.png/);
+      const curSubgroup = reg ? Number(reg[1]) : undefined;
+      if (curSubgroup !== subgroup) continue;
+    }
 
     for (const shape of data.shapes) {
       const icon =