Browse Source

feat: 添加纯线类型

bill 2 ngày trước cách đây
mục cha
commit
cb14adc072
44 tập tin đã thay đổi với 533 bổ sung218 xóa
  1. 9 15
      src/core/components/arrow/arrow.vue
  2. 1 6
      src/core/components/arrow/index.ts
  3. 4 1
      src/core/components/circle/circle.vue
  4. 1 2
      src/core/components/circle/index.ts
  5. 2 0
      src/core/components/icon/icon.ts
  6. 10 1
      src/core/components/icon/icon.vue
  7. 1 0
      src/core/components/image/index.ts
  8. 4 0
      src/core/components/index.ts
  9. 121 0
      src/core/components/line-chunk/index.ts
  10. 4 1
      src/core/components/line-icon/icon.vue
  11. 2 0
      src/core/components/line-icon/index.ts
  12. 77 51
      src/core/components/line/attach-server.ts
  13. 5 2
      src/core/components/line/index.ts
  14. 1 1
      src/core/components/line/line.vue
  15. 3 2
      src/core/components/line/renderer/wall/index.vue
  16. 22 5
      src/core/components/line/single-line.vue
  17. 2 1
      src/core/components/line/single-point.vue
  18. 7 1
      src/core/components/line/temp-line.vue
  19. 27 10
      src/core/components/line/use-draw.ts
  20. 1 2
      src/core/components/polygon/index.ts
  21. 9 1
      src/core/components/polygon/polygon.vue
  22. 1 3
      src/core/components/rectangle/index.ts
  23. 3 1
      src/core/components/rectangle/rectangle.vue
  24. 5 1
      src/core/components/share/edit-line.vue
  25. 1 1
      src/core/components/share/edit-point.vue
  26. 1 1
      src/core/components/share/size-line.vue
  27. 2 3
      src/core/components/triangle/index.ts
  28. 4 1
      src/core/components/triangle/triangle.vue
  29. 38 0
      src/core/hook/use-describe.ts
  30. 1 0
      src/core/hook/use-draw.ts
  31. 0 3
      src/core/hook/use-selection.ts
  32. 0 1
      src/core/hook/use-transformer.ts
  33. 40 0
      src/core/html-mount/propertys/describes.ts
  34. 6 6
      src/core/html-mount/propertys/index.ts
  35. 1 0
      src/core/html-mount/propertys/mount-describes.vue
  36. 0 1
      src/core/html-mount/propertys/mount.vue
  37. 0 0
      src/core/html-mount/propertys/sys-describes.json
  38. 44 44
      src/core/store/store.ts
  39. 7 5
      src/core/viewer.ts
  40. 14 6
      src/example/components/slide/actions.ts
  41. 5 1
      src/example/constant.ts
  42. 37 24
      src/example/fuse/views/defStyle.ts
  43. 8 12
      src/example/fuse/views/overview/index.vue
  44. 2 2
      src/example/platform/platform-draw.ts

+ 9 - 15
src/core/components/arrow/arrow.vue

@@ -21,7 +21,13 @@
 
 <script lang="ts" setup>
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
-import { ArrowData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import {
+  ArrowData,
+  getMouseStyle,
+  defaultStyle,
+  matResponse,
+  fixedStrokeOptions,
+} from "./index.ts";
 import { TempComponent } from "./";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
 import { Line } from "konva/lib/shapes/Line";
@@ -30,6 +36,7 @@ import { Group } from "konva/lib/Group";
 import { flatPositions } from "@/utils/shared.ts";
 import { themeColor } from "@/constant";
 import { watch, watchEffect } from "vue";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: ArrowData }>();
 const emit = defineEmits<{
@@ -102,18 +109,5 @@ watchEffect(() => {
   }
 });
 
-// const draw = useInteractiveDrawShapeAPI();
-// const store = useStore();
-// operateMenus.push({
-//   label: "钢笔编辑",
-//   handler() {
-//     draw.enterDrawShape("arrow", {
-//       ...props.data,
-//       getMessages: () => {
-//         const line = store.getItemById(props.data.id) as ArrowData;
-//         return line ? line.points : [];
-//       },
-//     });
-//   },
-// });
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions);
 </script>

+ 1 - 6
src/core/components/arrow/index.ts

@@ -26,6 +26,7 @@ export const defaultStyle = {
 // export const fill
 
 export const addMode = "area";
+export const fixedStrokeOptions = [1, 2, 4];
 
 export const getMouseStyle = (data: ArrowData) => {
   const strokeStatus = getMouseColors(data.fill || defaultStyle.fill);
@@ -117,9 +118,3 @@ export const matResponse = ({data, mat, increment}: MatResponseProps<'arrow'>) =
   data.attitude = transfrom.copy().multiply(attitude).m;
   return data;
 }
-
-export const getPredefine = (key: keyof ArrowData) => {
-  if (key === 'strokeWidth') {
-    return { proportion: true }
-  }
-}

+ 4 - 1
src/core/components/circle/circle.vue

@@ -17,7 +17,7 @@
 </template>
 
 <script lang="ts" setup>
-import { CircleData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import { CircleData, getMouseStyle, defaultStyle, matResponse, fixedStrokeOptions } from "./index.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import TempCircle from "./temp-circle.vue";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
@@ -27,6 +27,7 @@ import { Ellipse } from "konva/lib/shapes/Ellipse";
 import { Pos } from "@/utils/math.ts";
 import { copy } from "@/utils/shared.ts";
 import { setShapeTransform } from "@/utils/shape.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: CircleData }>();
 const emit = defineEmits<{
@@ -97,4 +98,6 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus<
     // "ref", "zIndex"
   ],
 });
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions);
+
 </script>

+ 1 - 2
src/core/components/circle/index.ts

@@ -28,6 +28,7 @@ export const defaultStyle = {
 };
 
 export const addMode = "area";
+export const fixedStrokeOptions = [1, 2, 4];
 
 export const getMouseStyle = (data: CircleData) => {
   const fillStatus = data.fill && getMouseColors(data.fill);
@@ -144,7 +145,5 @@ export const matResponse = (
 export const getPredefine = (key: keyof CircleData) => {
   if (["fill", "stroke"].includes(key)) {
     return { canun: true };
-  } else if (key === "strokeWidth") {
-    return { proportion: true };
   }
 };

+ 2 - 0
src/core/components/icon/icon.ts

@@ -15,10 +15,12 @@ export const shapeName = "图例";
 export const defaultStyle = {
   coverFill: "#000000",
   coverOpcatiy: 0,
+  strokeWidth: 1,
   strokeScaleEnabled: false,
   width: 80,
   height: 80,
 };
+export const fixedStrokeOptions = [1, 2, 4];
 
 type ColorCounts = [string, number][];
 const colorsManage = (counts: ColorCounts, color: any) => {

+ 10 - 1
src/core/components/icon/icon.vue

@@ -12,7 +12,13 @@
 
 <script lang="ts" setup>
 import TempIcon from "./temp-icon.vue";
-import { IconData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import {
+  IconData,
+  getMouseStyle,
+  defaultStyle,
+  matResponse,
+  fixedStrokeOptions,
+} from "./index.ts";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import { Transform } from "konva/lib/Util";
@@ -20,6 +26,7 @@ import { useCustomTransformer } from "@/core/hook/use-transformer.ts";
 import { Group } from "konva/lib/Group";
 import { Rect } from "konva/lib/shapes/Rect";
 import { setShapeTransform } from "@/utils/shape.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: IconData }>();
 const emit = defineEmits<{
@@ -79,4 +86,6 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
   },
   propertys: ["name", "fill", "stroke", "strokeWidth"],
 });
+
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions, undefined, true);
 </script>

+ 1 - 0
src/core/components/image/index.ts

@@ -73,6 +73,7 @@ export const interactiveToData: InteractiveTo<"image"> = ({
   ...args
 }) => {
   if (info.cur) {
+    console.log(preset)
     return interactiveFixData({
       ...args,
       info,

+ 4 - 0
src/core/components/index.ts

@@ -4,6 +4,7 @@ import * as circle from "./circle";
 import * as triangle from "./triangle";
 import * as polygon from "./polygon";
 import * as line from "./line";
+import * as lineChunk from "./line-chunk";
 import * as lineIcon from "./line-icon/index";
 import * as text from "./text";
 import * as icon from "./icon";
@@ -22,6 +23,7 @@ import { CircleData } from "./circle";
 import { TriangleData } from "./triangle";
 import { PolygonData } from "./polygon";
 import { LineData } from "./line";
+import { LineChunkData } from "./line-chunk";
 import { LineIconData } from "./line-icon/index";
 import { TextData } from "./text";
 import { IconData } from "./icon";
@@ -43,6 +45,7 @@ const _components = {
   triangle,
   polygon,
   line,
+  lineChunk,
   lineIcon,
   text,
   icon,
@@ -94,6 +97,7 @@ export type DrawDataItem = {
   triangle: TriangleData;
   polygon: PolygonData;
   line: LineData;
+  lineChunk: LineChunkData;
   lineIcon: LineIconData,
   text: TextData;
   icon: IconData;

+ 121 - 0
src/core/components/line-chunk/index.ts

@@ -0,0 +1,121 @@
+import { inRevise, onlyId } from "@/utils/shared";
+import { InteractiveFix, InteractiveTo } from "..";
+import { LineData, generateUseDraw } from "../line";
+import { getBaseItem } from "../util";
+import { getMouseColors } from "@/utils/colors";
+import { SelectionManageBus, UseGetSelectionManage } from "@/core/hook/use-selection";
+import { useStore } from "@/core/store";
+import { EntityShape } from "@/deconstruction";
+import { Group } from "konva/lib/Group";
+import mitt from "mitt";
+import { watch } from "vue";
+
+export const shapeName = "线段";
+export const defaultStyle = {
+  strokeWidth: 3,
+  stroke: "#000000",
+  fixed: true,
+  dash: [30, 0],
+};
+
+export const fixedStrokeOptions = [1, 2, 4];
+export const useDraw = generateUseDraw('lineChunk');
+
+export const getMouseStyle = (data: LineData) => {
+  const strokeStatus = getMouseColors(data.stroke || defaultStyle.stroke);
+  const strokeWidth = data.strokeWidth || defaultStyle.strokeWidth;
+  return {
+    default: { stroke: data.stroke || defaultStyle.stroke, strokeWidth },
+    hover: { stroke: strokeStatus.hover },
+    select: { stroke: strokeStatus.select },
+    focus: { stroke: strokeStatus.hover },
+    press: { stroke: strokeStatus.press },
+  };
+};
+
+export const interactiveFixData: InteractiveFix<'lineChunk'> = ({ data, info }) => {
+  const nv = [...info.consumed, info.cur!];
+
+  data.points.length = nv.length;
+  for (let i = 0; i < nv.length; i++) {
+    if (inRevise(data.points[i], nv[i])) {
+      if (!data.points[i]) {
+        data.points[i] = {
+          id: onlyId(),
+          ...nv[i],
+        };
+      } else {
+        data.points[i] = {
+          ...data.points[i],
+          ...nv[i],
+        };
+      }
+    }
+  }
+  data.lines.length = nv.length - 1;
+  for (let i = 0; i < nv.length - 1; i++) {
+    if (!data.lines[i]) {
+      data.lines[i] = {
+        id: onlyId(),
+        ...defaultStyle,
+        a: data.points[i].id,
+        b: data.points[i + 1].id,
+      };
+    }
+  }
+
+  // data.polygon = [{points: [data.lines.map((item) => item.id)], id: onlyId()}];
+  return data;
+};
+
+export const interactiveToData: InteractiveTo<'lineChunk'> = ({
+  info,
+  preset = {},
+  ...args
+}) => {
+  if (info.cur) {
+    const baseItem = getBaseItem();
+    return interactiveFixData({
+      ...args,
+      info,
+      data: {
+        ...defaultStyle,
+        ...baseItem,
+        ...preset,
+        lines: [],
+        points: [],
+        polygon: [],
+      },
+    });
+  }
+};
+
+
+export const useGetSelectionManage: UseGetSelectionManage = () => {
+  const store = useStore();
+
+  const canSelect = (shape: EntityShape) => {
+    const id = shape.id();
+    const line = store.getTypeItems('lineChunk')[0];
+    return !!(id && line.lines.some((item) => item.id === id) && !(shape instanceof Group));
+  };
+  const listener = (shape: EntityShape) => {
+    const bus: SelectionManageBus = mitt();
+    const stop = watch(
+      () => canSelect(shape),
+      (exixts, _) => {
+        if (!exixts) {
+          bus.emit("del", shape);
+        }
+      },
+      { immediate: true }
+    );
+    return { stop, bus };
+  };
+
+  return { canSelect, listener };
+};
+
+
+export type LineChunkData = LineData;
+export * from "../line";

+ 4 - 1
src/core/components/line-icon/icon.vue

@@ -21,6 +21,7 @@ import {
   getSnapLine,
   getLineIconEndpoints,
   isRangInner,
+  fixedStrokeOptions,
 } from "./index.ts";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
@@ -48,6 +49,7 @@ import {
 } from "@/utils/math.ts";
 import { asyncTimeout, copy } from "@/utils/shared.ts";
 import { useTestPoints } from "@/core/hook/use-debugger.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: LineIconData }>();
 const emit = defineEmits<{
@@ -60,7 +62,6 @@ const store = useStore();
 const getOperType = useGetTransformerOperType();
 const viewMat = useViewerInvertTransform();
 const pos = usePointerPos();
-const testPoints = useTestPoints();
 const { shape, tData, data, operateMenus, describes } = useComponentStatus({
   emit,
   props,
@@ -256,4 +257,6 @@ if (props.data.type === "align-bottom" || props.data.type === "align-bottom-fix"
     }
   );
 }
+
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions, undefined, true);
 </script>

+ 2 - 0
src/core/components/line-icon/index.ts

@@ -22,6 +22,8 @@ import { DrawStore } from "@/core/store/index.ts";
 export { defaultStyle, addMode, TempComponent, Component };
 export { getMouseStyle, getPredefine } from "../icon/index.ts";
 
+export const fixedStrokeOptions = [1, 2, 4];
+
 export const shapeName = "线段图例";
 export type LineIconData = Omit<IconData, "mat" | "width"> & {
   startLen: number;

+ 77 - 51
src/core/components/line/attach-server.ts

@@ -50,6 +50,7 @@ import {
 } from "../line-icon";
 import { useDrawIngData } from "@/core/hook/use-draw";
 import { useComponentDescribes } from "@/core/hook/use-component";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe";
 
 export type NLineDataCtx = {
   del: {
@@ -161,20 +162,23 @@ export const getJoinLine = (
     });
 };
 
-export const foreNormalLineData = (data:LineData) => {
+export const foreNormalLineData = (data: LineData) => {
   for (let i = 0; i < data.lines.length; i++) {
-    const {a, b} = data.lines[i]
-    if (!data.points.some(p => p.id === a) || !data.points.some(p => p.id === b)) {
-      data.lines.splice(i--, 1)
+    const { a, b } = data.lines[i];
+    if (
+      !data.points.some((p) => p.id === a) ||
+      !data.points.some((p) => p.id === b)
+    ) {
+      data.lines.splice(i--, 1);
     }
   }
   for (let i = 0; i < data.points.length; i++) {
-    const id = data.points[i].id
-    if (!data.lines.some(l => l.a === id || l.b === id)) {
-      data.points.splice(i, 1)
+    const id = data.points[i].id;
+    if (!data.lines.some((l) => l.a === id || l.b === id)) {
+      data.points.splice(i, 1);
     }
   }
-}
+};
 
 export const normalLineData = (data: LineData, ctx: NLineDataCtx) => {
   const changePoints = [
@@ -494,10 +498,10 @@ export const genMoveLineHandler = (
   };
 };
 
-export const useLineDataSnapInfos = () => {
+export const useLineDataSnapInfos = (type: "line" | "lineChunk") => {
   const infos = useCustomSnapInfos();
   const store = useStore();
-  const lineData = computed(() => store.getTypeItems("line")[0]);
+  const lineData = computed(() => store.getTypeItems(type)[0]);
   let snapInfos: ComponentSnapInfo[];
 
   const updateSnapInfos = (pointIds: string[]) => {
@@ -581,54 +585,74 @@ export const updateLineLength = (
   Object.assign(points[1], npoints[1]);
 };
 
-export const useLineDescribes = (line: Ref<LineDataLine>) => {
+export const useLineDescribes = (
+  line: Ref<LineDataLine>,
+  type: "line" | "lineChunk",
+  fixedStroke = false,
+  fixedStrokeOptions: number[] = []
+) => {
   const d: any = useComponentDescribes(line, ["stroke", "strokeWidth"], {});
   const store = useStore();
-  const lineData = computed(() => store.getTypeItems("line")[0]);
+  const lineData = computed(() => store.getTypeItems(type)[0]);
   const points = computed(() => [
     lineData.value.points.find((p) => p.id === line.value.a)!,
     lineData.value.points.find((p) => p.id === line.value.b)!,
   ]);
   let setLineVector: Vector2;
 
-  watch(d, (d) => {
-    d.strokeWidth.props = {
-      ...d.strokeWidth.props,
-      proportion: true,
-    };
-    d.strokeWidth.label = "厚度";
-    d.stroke.label = "颜色";
-
-  d.length = {
-    type: "inputNum",
-    label: "长度",
-    "layout-type": "row",
-    props: {
-      proportion: true,
-    },
-    
-    get value() {
-      return lineLen(points.value[0], points.value[1]);
-    },
-    set value(val) {
-      console.log(val, d.length.isChange);
-      if (!d.isChange) {
-        setLineVector = lineVector(points.value);
-      }
-      updateLineLength(
-        lineData.value,
-        line.value,
-        val,
-        undefined,
-        setLineVector
-      );
+  if (fixedStroke) {
+    watch(
+      d,
+      (d) => {
+        d.strokeWidth.label = "厚度";
+        d.strokeWidth.props = {
+          ...d.strokeWidth.props,
+          proportion: true,
+        };
+      },
+      { immediate: true }
+    );
+  } else {
+    useInstallStrokeWidthDescribe(d, line, fixedStrokeOptions);
+  }
+  
+  watch(
+    d,
+    (d) => {
+      d.stroke.label = "颜色";
+      d.length = {
+        type: "inputNum",
+        label: "长度",
+        "layout-type": "row",
+        props: {
+          proportion: true,
+        },
+
+        get value() {
+          return lineLen(points.value[0], points.value[1]);
+        },
+        set value(val) {
+          console.log(val, d.length.isChange);
+          if (!d.isChange) {
+            setLineVector = lineVector(points.value);
+          }
+          updateLineLength(
+            lineData.value,
+            line.value,
+            val,
+            undefined,
+            setLineVector
+          );
+        },
+      };
     },
-  };
-  }, {immediate: true});
-  return d as PropertyDescribes;
+    { immediate: true }
+  );
+  return d as Ref<PropertyDescribes>;
 };
 
 export const useDrawLinePoint = (
+  type: "line" | "lineChunk",
   data: Ref<LineData>,
   line: Ref<LineDataLine>,
   callback: (data: {
@@ -660,18 +684,20 @@ export const useDrawLinePoint = (
     point: LineData["points"][0];
   }>();
   const runHook = useRunHook();
-  const snapInfos = useLineDataSnapInfos();
+  const store = useStore();
+
+  const snapInfos = useLineDataSnapInfos(type);
   const snap = useSnap();
   const stage = useStage();
-  const store = useStore();
   const icons = computed(() =>
-    store.getTypeItems("lineIcon").filter((item) => item.lineId === line.value.id)
+    store
+      .getTypeItems("lineIcon")
+      .filter((item) => item.lineId === line.value.id)
   );
   const drawStore = useDrawIngData();
   const cursor = useCursor();
   const enterDraw = () => {
-    const points = getLinePoints(data.value, line.value)
-    console.log(points, data.value, line.value)
+    const points = getLinePoints(data.value, line.value);
     const cdata: LineData = { ...data.value, points, lines: [] };
     const point = reactive({ ...lineCenter(points), id: onlyId() });
     const cIcons = icons.value.map((icon) => ({ ...icon, id: onlyId() }));

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

@@ -2,7 +2,7 @@ import { lineVector, Pos, vectorAngle, verticalVector } from "@/utils/math.ts";
 import { BaseItem, generateSnapInfos, getBaseItem } from "../util.ts";
 import { getMouseColors } from "@/utils/colors.ts";
 import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts";
-import { copy, inRevise, onlyId, rangMod } from "@/utils/shared.ts";
+import { inRevise, onlyId, rangMod } from "@/utils/shared.ts";
 import { MathUtils } from "three";
 import { DrawStore, useStore } from "@/core/store/index.ts";
 import {
@@ -15,10 +15,13 @@ import { Ref, ref, watch } from "vue";
 import { getInitCtx, NLineDataCtx, normalLineData } from "./attach-server.ts";
 import * as wallRenderer from "./renderer/wall";
 import { Group } from "konva/lib/Group";
+import { generateUseDraw } from "./use-draw.ts";
 
 export { default as Component } from "./line.vue";
 export { default as TempComponent } from "./temp-line.vue";
-export { useDraw } from "./use-draw.ts";
+export { generateUseDraw } from "./use-draw.ts";
+
+export const useDraw = generateUseDraw("line");
 
 export const shapeName = "墙";
 export const defaultStyle = {

+ 1 - 1
src/core/components/line/line.vue

@@ -1,5 +1,5 @@
 <template>
-  <TempLine :data="data" @updateShape="emit('updateShape', data)" />
+  <TempLine :data="data" @updateShape="emit('updateShape', data)"  />
 </template>
 
 <script lang="ts" setup>

+ 3 - 2
src/core/components/line/renderer/wall/index.vue

@@ -7,8 +7,8 @@
       fill: stroke,
       closed: true,
       listening: false,
-      stroke: '#000000',
-      strokeWidth: strokeWidth,
+      stroke: border ? '#000000' : undefined,
+      strokeWidth: border ? strokeWidth : undefined,
     }"
   />
 
@@ -42,6 +42,7 @@ const props = defineProps<{
   opacity?: number;
   stroke?: string;
   showLabel: any;
+  border?: boolean;
 }>();
 
 const polygon = computed(() => props.getShapeAttrib(props.line));

+ 22 - 5
src/core/components/line/single-line.vue

@@ -30,6 +30,7 @@
     :getShapeAttrib="getShapeAttrib"
     :data="data"
     :line="line"
+    :border="type === 'line'"
     :showLabel="
       active ||
       config.showComponentSize ||
@@ -56,23 +57,27 @@
 
   <template v-if="drawProps">
     <SingleLine
+      :type="type"
       :data="drawProps.data"
       :line="drawProps.prev"
       :drawMode="drawProps.point"
       :getShapeAttrib="drawGetShapeAttrib"
     />
     <singlePoint
+      :type="type"
       :data="drawProps.data"
       :line="drawProps.prev"
       :drawMode="drawProps.point"
     />
     <SingleLine
+      :type="type"
       :data="drawProps.data"
       :line="drawProps.next"
       :drawMode="drawProps.point"
       :getShapeAttrib="drawGetShapeAttrib"
     />
     <singlePoint
+      :type="type"
       :data="drawProps.data"
       :line="drawProps.next"
       :drawMode="drawProps.point"
@@ -83,8 +88,8 @@
 <script lang="ts" setup>
 import EditLine from "../share/edit-line.vue";
 import singlePoint from "./single-point.vue";
-import { computed, ref, watchEffect } from "vue";
-import { getMouseStyle, LineData, LineDataLine, shapeName, renderer } from "./index.ts";
+import { computed, ref } from "vue";
+import { getMouseStyle, LineData, LineDataLine, renderer } from "./index.ts";
 import { onlyId } from "@/utils/shared.ts";
 import { Pos } from "@/utils/math.ts";
 import { Line } from "konva/lib/shapes/Line";
@@ -105,10 +110,13 @@ import {
 import { useStore } from "@/core/store/index.ts";
 import { useHistory } from "@/core/hook/use-history.ts";
 import { useTransformIngShapes } from "@/core/hook/use-global-vars.ts";
+import { components } from "../index.ts";
+import { fixedStrokeOptions } from "../line-chunk/index.ts";
 
 const props = defineProps<{
   line: LineDataLine;
   addMode?: boolean;
+  type: "line" | "lineChunk";
   canEdit?: boolean;
   data: LineData;
   dragPointIds?: string[];
@@ -116,6 +124,8 @@ const props = defineProps<{
   getShapeAttrib?: (line: LineDataLine) => any;
 }>();
 
+const shapeName = computed(() => components[props.type].shapeName);
+
 const emit = defineEmits<{
   (e: "updatePoint", value: LineData["points"][number]): void;
   (e: "addPoint", value: LineData["points"][number]): void;
@@ -135,7 +145,13 @@ const points = computed(() => getLinePoints(props.data, props.line));
 
 const shape = ref<DC<Line>>();
 const lineData = computed(() => props.line);
-const describes = useLineDescribes(lineData);
+
+const describes = useLineDescribes(
+  lineData,
+  props.type,
+  props.type !== "lineChunk",
+  fixedStrokeOptions
+);
 const delHandler = () => {
   emit("updateBefore", [props.line.a, props.line.b]);
   emit("delLine");
@@ -145,6 +161,7 @@ const delHandler = () => {
 const store = useStore();
 const history = useHistory();
 const { drawProps, enter: enterDrawLinePoint } = useDrawLinePoint(
+  props.type,
   computed(() => props.data),
   computed(() => props.line),
   (data) => {
@@ -162,7 +179,7 @@ const { drawProps, enter: enterDrawLinePoint } = useDrawLinePoint(
 );
 
 const drawData = computed(() => drawProps.value?.data);
-const drawGetShapeAttrib = renderer.value!.genGetShapeAttrib(drawData)
+const drawGetShapeAttrib = renderer.value!.genGetShapeAttrib(drawData);
 const menus = [
   { label: "加点", handler: enterDrawLinePoint },
   { label: "删除", handler: delHandler },
@@ -200,7 +217,7 @@ const addPoint = (pos: Pos) => {
   emit("update");
 };
 
-const lDataSnap = useLineDataSnapInfos();
+const lDataSnap = useLineDataSnapInfos(props.type);
 const config = useConfig();
 const dragstartHandler = (eIds: string[]) => {
   emit("updateBefore", eIds);

+ 2 - 1
src/core/components/line/single-point.vue

@@ -34,6 +34,7 @@ import { Circle } from "konva/lib/shapes/Circle";
 
 const props = defineProps<{
   lineShape?: DC<Line>;
+  type: 'line' | 'lineChunk';
   line: LineData["lines"][number];
   addMode?: boolean;
   data: LineData;
@@ -88,7 +89,7 @@ const delPoint = (point: LineData["points"][number]) => {
   emit("update");
 };
 
-const lDataSnap = useLineDataSnapInfos();
+const lDataSnap = useLineDataSnapInfos(props.type);
 const dragIng = ref(false);
 const dragstartHandler = (eIds: string[]) => {
   emit("updateBefore", eIds);

+ 7 - 1
src/core/components/line/temp-line.vue

@@ -7,6 +7,7 @@
         :key="item.id"
         :line="item"
         :data="data"
+        :type="type"
         :add-mode="addMode"
         :can-edit="!initData && !operMode.mulSelection"
         :dragPointIds="dragPointIds"
@@ -27,6 +28,7 @@
         v-for="(item, ndx) in data.lines"
         :line-shape="lineShapes[ndx]"
         :dragPointIds="dragPointIds"
+        :type="type"
         :key="item.id"
         :line="item"
         :data="data"
@@ -60,6 +62,7 @@ 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 { useStore } from "@/core/store/index.ts";
 
 const props = defineProps<{
   data: LineData;
@@ -68,7 +71,10 @@ const props = defineProps<{
 }>();
 
 const operMode = useOperMode();
-const initData = useInitData();
+const store = useStore();
+const type = computed(() => store.getType(props.data.id) as "line" | "lineChunk");
+const initData = useInitData(type.value);
+
 const emit = defineEmits<{
   (e: "updateShape"): void;
 }>();

+ 27 - 10
src/core/components/line/use-draw.ts

@@ -5,14 +5,14 @@ import {
   useInteractiveDrawShapeAPI,
   usePointBeforeHandler,
 } from "@/core/hook/use-draw";
-import { components, ComponentSnapInfo, SnapPoint } from "..";
+import { components, ComponentSnapInfo, ShapeType, SnapPoint } from "..";
 import { useHistory, useHistoryAttach } from "@/core/hook/use-history";
 import { useStore } from "@/core/store";
 import { useViewerTransform } from "@/core/hook/use-viewer";
 import { useOperMode } from "@/core/hook/use-status";
 import { installGlobalVar, useCursor } from "@/core/hook/use-global-vars";
 import { useInteractiveDots } from "@/core/hook/use-interactive";
-import { computed, nextTick, reactive, ref, watch } from "vue";
+import { computed, nextTick, reactive, ref, watch, watchEffect } from "vue";
 import { copy, mergeFuns } from "@/utils/shared";
 import { lineVector, Pos } from "@/utils/math";
 import { getSnapInfos, type LineData } from "./";
@@ -23,11 +23,23 @@ import { useProportion } from "@/core/hook/use-proportion";
 
 type PayData = Pos;
 
-export let initData: LineData | undefined;
-export const useInitData = installGlobalVar(() => ref<LineData>());
+const useTypeInitData = installGlobalVar(() =>
+  ref<Record<string, LineData | undefined>>({})
+);
+export const useInitData = (type: string) => {
+  const allInitData = useTypeInitData();
+  return computed({
+    get: () => allInitData.value[type],
+    set: (value) => (allInitData.value[type] = value),
+  });
+};
 
-export const useDraw = () => {
-  const type = "line";
+export const generateUseDraw = (type: "line" | "lineChunk" = "line") => {
+  console.log("generateUseDraw", type);
+  return () => useDraw(type);
+};
+
+const useDraw = (type: "line" | "lineChunk" = "line") => {
   const { quitDrawShape } = useInteractiveDrawShapeAPI();
   const isRuning = useDrawRunning(type);
   const obj = components[type];
@@ -36,9 +48,10 @@ export const useDraw = () => {
   const store = useStore();
   const viewTransform = useViewerTransform();
   const operMode = useOperMode();
-  const hInitData = useInitData();
+  const hInitData = useInitData(type);
   const customSnapInfos = useCustomSnapInfos();
-  const { invTransform } = useProportion()
+  const { invTransform } = useProportion();
+  let initData: LineData | undefined;
 
   // 可能历史空间会撤销 重做更改到正在绘制的组件
   const currentCursor = ref("./icons/m_add.png");
@@ -55,12 +68,14 @@ export const useDraw = () => {
     shapeType: type,
     isRuning,
     enter() {
+      console.log("enter, ", type);
       cursorPop = cursor.push(currentCursor.value);
       watch(currentCursor, () => {
         cursorPop?.set(currentCursor.value);
       });
     },
     quit: () => {
+      console.log("quit, ", type);
       quitDrawShape();
       beforeHandler.clear();
       cursorPop && cursorPop();
@@ -254,7 +269,7 @@ export const useDraw = () => {
     const keyInput = getKeywordInput(
       (inputData, prev) => {
         const len = Number(inputData);
-        
+
         if (len && drawItems[0].lines.length) {
           const line = drawItems[0].lines[drawItems[0].lines.length - 1];
           const points = [
@@ -262,7 +277,9 @@ export const useDraw = () => {
             drawItems[0].points.find((p) => p.id === line.b)!,
           ];
           const vector = lineVector(points);
-          const position = vector.multiplyScalar(invTransform(len)).add(points[0]);
+          const position = vector
+            .multiplyScalar(invTransform(len))
+            .add(points[0]);
           cur.x = position.x;
           cur.y = position.y;
           isInputChange = true;

+ 1 - 2
src/core/components/polygon/index.ts

@@ -9,6 +9,7 @@ export { default as Component } from "./polygon.vue";
 export { default as TempComponent } from "./temp-polygon.vue";
 
 export const shapeName = "多边形";
+export const fixedStrokeOptions = [1, 2, 4];
 export const defaultStyle = {
   stroke: "#000000",
   fixed: true,
@@ -112,7 +113,5 @@ export const matResponse = ({
 export const getPredefine = (key: keyof PolygonData) => {
   if (["fill", "stroke"].includes(key)) {
     return { canun: true };
-  } else if (key === "strokeWidth") {
-    return { proportion: true };
   }
 };

+ 9 - 1
src/core/components/polygon/polygon.vue

@@ -20,13 +20,20 @@
 </template>
 
 <script lang="ts" setup>
-import { PolygonData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import {
+  PolygonData,
+  getMouseStyle,
+  defaultStyle,
+  matResponse,
+  fixedStrokeOptions,
+} from "./index.ts";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import TempLine from "./temp-polygon.vue";
 import { useInteractiveDrawShapeAPI } from "@/core/hook/use-draw.ts";
 import { useStore } from "@/core/store/index.ts";
 import { Pos } from "@/utils/math.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: PolygonData }>();
 const emit = defineEmits<{
@@ -86,4 +93,5 @@ operateMenus.push({
     });
   },
 });
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions);
 </script>

+ 1 - 3
src/core/components/rectangle/index.ts

@@ -19,6 +19,7 @@ export const defaultStyle = {
   fontStyle: "normal",
   fontColor: "#000000",
 };
+export const fixedStrokeOptions = [1, 2, 4];
 
 export const getMouseStyle = (data: RectangleData) => {
   const fillStatus = data.fill && getMouseColors(data.fill);
@@ -125,8 +126,5 @@ export const getPredefine = (key: keyof RectangleData) => {
 
   if (["fill", "stroke"].includes(key)) {
     return { canun: true };
-  } else if (key === "strokeWidth") {
-    return { proportion: true };
   }
-
 };

+ 3 - 1
src/core/components/rectangle/rectangle.vue

@@ -16,10 +16,11 @@
 </template>
 
 <script lang="ts" setup>
-import { RectangleData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import { RectangleData, getMouseStyle, defaultStyle, matResponse, fixedStrokeOptions } from "./index.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import TempLine from "./temp-rectangle.vue";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
 
 const props = defineProps<{ data: RectangleData }>();
 const emit = defineEmits<{
@@ -60,4 +61,5 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
     // "ref", "zIndex"
   ],
 });
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions);
 </script>

+ 5 - 1
src/core/components/share/edit-line.vue

@@ -8,7 +8,7 @@
       stroke: data.stroke,
       zIndex: zIndex,
       points: flatPositions(points),
-      hitStrokeWidth: width,
+      hitStrokeWidth: hitWidth,
     }"
   />
 
@@ -171,6 +171,10 @@ const center = computed(() => lineCenter(points.value));
 const width = computed(() =>
   props.data.fixed ? props.data.strokeWidth * scale.value : props.data.strokeWidth
 );
+const hitWidth = computed(() => {
+  const hitWidth = Math.max(props.data.strokeWidth || 0, 10);
+  return props.data.fixed ? hitWidth * scale.value : hitWidth;
+});
 const pointStyle = computed(() => {
   const color = getMouseColors(props.data.stroke || themeColor);
   const size = (width.value || 1) + 6 || 5;

+ 1 - 1
src/core/components/share/edit-point.vue

@@ -64,7 +64,7 @@ const scale = useFixedScale();
 const viewer = useViewer();
 const style = computed(() => {
   const color = getMouseColors(props.color || themeColor);
-  let size = props.size || 5;
+  let size = Math.max(props.size || 10, 10);
   size = props.fixed ? scale.value * size : size;
 
   return {

+ 1 - 1
src/core/components/share/size-line.vue

@@ -50,7 +50,7 @@ const props = withDefaults(
 );
 const fscale = useFixedScale();
 const scale = computed(() => (props.fixed ? fscale.value : 1));
-const style = computed(() => ({ stroke: props.stroke, strokeWidth: 10 * scale.value }));
+const style = computed(() => ({ stroke: props.stroke, strokeWidth: 4 * scale.value }));
 const fontSize = computed(() => 10 * scale.value + style.value.strokeWidth * 2);
 const len = computed(() =>
   props.closed ? props.points.length : props.points.length - 1

+ 2 - 3
src/core/components/triangle/index.ts

@@ -19,6 +19,7 @@ export const defaultStyle = {
 };
 
 export const addMode = "area";
+export const fixedStrokeOptions = [1, 2, 4];
 
 export const getMouseStyle = (data: TriangleData) => {
   const fillStatus = data.fill && getMouseColors(data.fill);
@@ -104,7 +105,5 @@ export const getPredefine = (key: keyof TriangleData) => {
 
   if (["fill", "stroke"].includes(key)) {
     return { canun: true };
-  } else if (key === "strokeWidth") {
-    return { proportion: true };
-  }
+  } 
 };

+ 4 - 1
src/core/components/triangle/triangle.vue

@@ -17,10 +17,12 @@
 </template>
 
 <script lang="ts" setup>
-import { TriangleData, getMouseStyle, defaultStyle, matResponse } from "./index.ts";
+import { TriangleData, fixedStrokeOptions, getMouseStyle, matResponse } from "./index.ts";
 import { PropertyUpdate, Operate } from "../../html-mount/propertys/index.ts";
 import TempLine from "./temp-triangle.vue";
 import { useComponentStatus } from "@/core/hook/use-component.ts";
+import { useInstallStrokeWidthDescribe } from "@/core/hook/use-describe.ts";
+import { watchEffect } from "vue";
 
 const props = defineProps<{ data: TriangleData }>();
 const emit = defineEmits<{
@@ -60,4 +62,5 @@ const { shape, tData, operateMenus, describes, data } = useComponentStatus({
     // "ref", "zIndex"
   ],
 });
+useInstallStrokeWidthDescribe(describes, data, fixedStrokeOptions);
 </script>

+ 38 - 0
src/core/hook/use-describe.ts

@@ -0,0 +1,38 @@
+import { computed, Ref, watch } from "vue";
+import { PropertyDescribes } from "../html-mount/propertys";
+import {
+  getFixedStrokeWidthProperty,
+  sysDescribes,
+} from "../html-mount/propertys/describes";
+import { useStore } from "../store";
+import { Proportion } from "../store/store";
+
+export const useInstallStrokeWidthDescribe = (
+  describes: Ref<PropertyDescribes>,
+  shape: Ref<{ strokeWidth?: number; fixed?: boolean }>,
+  options = [1, 2, 4],
+  defProportion?: Proportion,
+  fixed = false
+) => {
+  const store = useStore();
+  const proportion = computed(() => {
+    return defProportion || { ...store.config.strokeProportion };
+  });
+
+  watch(
+    () => [fixed || shape.value.fixed, proportion.value] as const,
+    ([fixed, proportion]) => {
+      if (fixed) {
+        const property = getFixedStrokeWidthProperty(shape);
+        property.props.options = options.map((size) => ({
+          label: `${size} ${proportion.unit}`,
+          value: size / proportion.scale,
+        }));
+        describes.value.strokeWidth = property as PropertyDescribes[string];
+      } else {
+        describes.value.strokeWidth = sysDescribes.strokeWidth as any;
+      }
+    },
+    { immediate: true, flush: 'sync' }
+  );
+};

+ 1 - 0
src/core/hook/use-draw.ts

@@ -132,6 +132,7 @@ export const useInteractiveDrawShapeAPI = installGlobalVar(() => {
         operate: { single },
         callback: leave,
       };
+      console.log(interactiveProps.value)
       enter();
     },
     quitDrawShape: () => {

+ 0 - 3
src/core/hook/use-selection.ts

@@ -244,7 +244,6 @@ export const useStoreSelectionManage = installGlobalVar((): SelectionManage => {
       return false;
     }
     const item = store.items.find((item) => item.id === id);
-    console.log(shape)
     return !!(item && !item.lock);
   };
   const listener = (shape: EntityShape) => {
@@ -297,8 +296,6 @@ export const useSelectionRevise = () => {
     selfSet = true;
     status.selects = shapes;
     selfSet = false;
-
-    console.log(shapes, shapes.map(item => store.getItemById(item.id())))
   };
 
   let initSelections: EntityShape[] = [];

+ 0 - 1
src/core/hook/use-transformer.ts

@@ -256,7 +256,6 @@ export const useShapeDrag = (shape: Ref<DC<EntityShape> | undefined>) => {
 
     let start: Pos | undefined;
     const enter = (position: Pos) => {
-      console.log('enter')
       mode.push(Mode.update);
       if (!start) {
         start = position;

+ 40 - 0
src/core/html-mount/propertys/describes.ts

@@ -0,0 +1,40 @@
+import { Ref } from "vue";
+import sysDescribes from "./sys-describes.json";
+
+export const getFixedStrokeWidthProperty = (self: Ref<{ strokeWidth?: number }>) => {
+  const property = {
+    type: "select",
+    label: "边框粗细",
+    props: {
+      options: [
+        {
+          label: "1px",
+          value: 1,
+        },
+        {
+          label: "2px",
+          value: 2,
+        },
+        {
+          label: "4px",
+          value: 4,
+        },
+      ],
+    },
+    "layout-type": "row",
+    get value() {
+      if (self.value.strokeWidth) {
+        return property.props.options.find(item => Math.abs(item.value - self.value.strokeWidth!) < 0.01)?.value;
+      } else {
+        return self.value.strokeWidth
+      }
+    },
+    set value(val) {
+      self.value.strokeWidth = val!
+    },
+  };
+
+  return property
+};
+
+export { sysDescribes };

+ 6 - 6
src/core/html-mount/propertys/index.ts

@@ -7,8 +7,8 @@ import InputNum from "./components/input-num.vue";
 import Proportion from "./components/proportion.vue";
 import Text from "./components/text.vue";
 import FixProportion from "./components/fix-proportion.vue";
-import originDescribes from "./describes.json";
-import { ref, Ref } from "vue";
+import { sysDescribes } from "./describes";
+import { Ref } from "vue";
 
 export const colorType = "color";
 export const selectType = "select";
@@ -18,7 +18,7 @@ export const proportionType = "proportion";
 export const fixProportionType = "fixProportion"
 export const textType = 'text'
 export const inputNumType = 'inputNum'
-export { originDescribes }
+export { sysDescribes }
 
 export const propertyComponents = {
   [colorType]: Color,
@@ -58,15 +58,15 @@ export type PropertysData<T extends PropertyDescribes = PropertyDescribes> = {
   [K in keyof T]: PropertyValue<T[K]["type"]>;
 };
 
-export type PropertyKey = keyof typeof originDescribes;
+export type PropertyKey = keyof typeof sysDescribes;
 export type PropertyKeys = PropertyKey[];
 
 export const mergeDescribes = (data: Ref<any>, defData: any, keys: PropertyKeys, describes: PropertyDescribes = {}) => {
   for (const key of keys) {
-    if (!originDescribes[key]) {
+    if (!sysDescribes[key]) {
       continue;
     }
-    ;(describes as any)[key] = { ...originDescribes[key] };
+    ;(describes as any)[key] = { ...sysDescribes[key] };
 
     if (!("value" in describes[key])) {
       Object.defineProperty(describes[key], "value", {

+ 1 - 0
src/core/html-mount/propertys/mount-describes.vue

@@ -64,6 +64,7 @@ const props = defineProps<{
   describes: PropertyDescribes;
   calDelete?: boolean;
 }>();
+
 const emit = defineEmits<{
   (e: "change"): void;
   (e: "delete"): void;

+ 0 - 1
src/core/html-mount/propertys/mount.vue

@@ -63,5 +63,4 @@ const hidden = computed(
       mode.value.has(Mode.draging))
 );
 
-watch(hidden, (hide) => !hide && console.log(props.data));
 </script>

src/core/html-mount/propertys/describes.json → src/core/html-mount/propertys/sys-describes.json


+ 44 - 44
src/core/store/store.ts

@@ -7,21 +7,24 @@ export const sortFn = (
   b: Pick<DrawItem, "zIndex" | "createTime">
 ) => a.zIndex - b.zIndex || a.createTime - b.createTime;
 
+export type Proportion = { scale: number; unit: string };
 export type StoreConfig = {
-  proportion: { scale: number, unit: string }
+  proportion: Proportion;
+  strokeProportion: Proportion;
   compass: {
     rotation: number;
     url: string;
   };
 };
 export type StoreData = {
-  layers: Record<string, DrawData>,
+  layers: Record<string, DrawData>;
   config: StoreConfig;
   __currentLayer: string;
 };
 const defConfig: StoreData["config"] = {
-  compass: { rotation: 0, url: 'icons/edit_compass.svg' },
-  proportion: {scale: 10, unit: 'mm'}
+  compass: { rotation: 0, url: "icons/edit_compass.svg" },
+  proportion: { scale: 1, unit: "px" },
+  strokeProportion: { scale: 1, unit: "px" }
 };
 
 export const getEmptyStoreData = (): StoreData => {
@@ -36,22 +39,22 @@ export const useStoreRaw = defineStore("draw-data", {
   state: () => ({ data: getEmptyStoreData() }),
   getters: {
     currentLayer() {
-      const layer = (this as any).data.__currentLayer
-      const layers = (this as any).layers
+      const layer = (this as any).data.__currentLayer;
+      const layers = (this as any).layers;
       if (layers.includes(layer)) {
-        return layer
+        return layer;
       } else {
-        return layers[0] 
+        return layers[0];
       }
     },
     layers() {
-      const data = this.data as StoreData
-      return Object.keys(data.layers)
+      const data = this.data as StoreData;
+      return Object.keys(data.layers);
     },
     typeItems() {
-      const data = this.data as StoreData
-      const layer = (this as any).currentLayer
-      return data.layers[layer] || {}
+      const data = this.data as StoreData;
+      const layer = (this as any).currentLayer;
+      return data.layers[layer] || {};
     },
     items() {
       return Object.values(this.typeItems).flat() as DrawItem[];
@@ -65,26 +68,26 @@ export const useStoreRaw = defineStore("draw-data", {
   },
   actions: {
     setStore(store: Partial<StoreData>) {
-      const newStore = JSON.parse(JSON.stringify(store)) ;
+      const newStore = JSON.parse(JSON.stringify(store));
       this.$patch((state) => {
         state.data = {
           ...state.data,
           ...newStore,
           config: {
             ...state.data.config,
-            ...(newStore.config || {})
-          }
+            ...(newStore.config || {}),
+          },
         };
       });
     },
     setLayerStore(layerStore: DrawData) {
-      this.$patch(state => {
-        state.data.layers[this.currentLayer] = layerStore
-      })
+      this.$patch((state) => {
+        state.data.layers[this.currentLayer] = layerStore;
+      });
     },
     getItemNdx<T extends ShapeType>(type: T, id: string) {
       const items = this.typeItems[type];
-      
+
       if (items) {
         return items.findIndex((item) => item.id === id);
       }
@@ -101,7 +104,7 @@ export const useStoreRaw = defineStore("draw-data", {
       items.forEach((item) => this.addItem(type, item));
     },
     addItem<T extends ShapeType>(type: T, item: DrawItem<T>) {
-      const typeItems = this.typeItems
+      const typeItems = this.typeItems;
       this.$patch(() => {
         if (!(type in typeItems)) {
           typeItems[type] = [];
@@ -111,7 +114,7 @@ export const useStoreRaw = defineStore("draw-data", {
     },
     delItem<T extends ShapeType>(type: T, id: string) {
       const ndx = this.getItemNdx(type, id);
-      const typeItems = this.typeItems
+      const typeItems = this.typeItems;
       if (~ndx) {
         this.$patch(() => {
           typeItems[type]!.splice(ndx, 1);
@@ -122,14 +125,14 @@ export const useStoreRaw = defineStore("draw-data", {
       type: T,
       playData: { value: Partial<DrawItem<T>>; id: string }
     ) {
-      const typeItems = this.typeItems
+      const typeItems = this.typeItems;
       const ndx = this.getItemNdx(type, playData.id);
       if (~ndx) {
         this.$patch(() => {
-          console.log()
-          const old = typeItems[type]![ndx]
+          console.log();
+          const old = typeItems[type]![ndx];
           Object.assign(typeItems[type]![ndx], playData.value);
-          const newv = typeItems[type]![ndx]
+          const newv = typeItems[type]![ndx];
         });
       }
     },
@@ -141,8 +144,8 @@ export const useStoreRaw = defineStore("draw-data", {
       }
     },
     getType(id: string) {
-      const typeItems = this.typeItems
-      const types = (Object.keys(typeItems)) as ShapeType[];
+      const typeItems = this.typeItems;
+      const types = Object.keys(typeItems) as ShapeType[];
       for (const type of types) {
         if (typeItems[type]?.some((item) => item.id === id)) {
           return type;
@@ -162,25 +165,25 @@ export const useStoreRaw = defineStore("draw-data", {
       this.$patch((state) => {
         state.data.config = {
           ...state.data.config,
-          ...config
+          ...config,
         };
       });
     },
     setCurrentLayer(layer: string) {
       if (!this.layers.includes(layer)) {
-        throw `不存在${layer}层`
+        throw `不存在${layer}层`;
       } else {
-        this.data.__currentLayer = layer
+        this.data.__currentLayer = layer;
       }
     },
     clear() {
-      this.data.layers[this.currentLayer] = {}
+      this.data.layers[this.currentLayer] = {};
     },
     addLayer(layer: string) {
       if (this.layers.includes(layer)) {
-        throw `已存在${layer}层`
+        throw `已存在${layer}层`;
       } else {
-        this.data.layers[layer] = {}
+        this.data.layers[layer] = {};
       }
     },
     delLayer(layer: string, translateLayer?: string) {
@@ -190,23 +193,20 @@ export const useStoreRaw = defineStore("draw-data", {
 
       if (translateLayer) {
         if (!this.layers.includes(translateLayer)) {
-          throw `不存在${translateLayer}层`
+          throw `不存在${translateLayer}层`;
         }
-        const layerData = this.data.layers[layer]  
-        const tLayerData = this.data.layers[translateLayer]
-        const keys = Object.keys(layerData) as ShapeType[]
+        const layerData = this.data.layers[layer];
+        const tLayerData = this.data.layers[translateLayer];
+        const keys = Object.keys(layerData) as ShapeType[];
 
         for (const key of keys) {
           if (key in tLayerData && tLayerData[key]) {
-            tLayerData[key] = [
-              ...tLayerData[key],
-              ...layerData[key]!
-            ] as any
+            tLayerData[key] = [...tLayerData[key], ...layerData[key]!] as any;
           } else {
-            tLayerData[key] = layerData[key] as any
+            tLayerData[key] = layerData[key] as any;
           }
         }
       }
-    }
+    },
   },
 });

+ 7 - 5
src/core/viewer.ts

@@ -93,14 +93,16 @@ export class Viewer {
 
   scale(center: Pos, scale: number, initMat = this.viewMat) {
     const base = initMat.decompose().scaleX;
-    const isMin = base * scale < 0.05
-    const isMax = base * scale > 50
+    const min = 0.005
+    const max = 50
+    const isMin = base * scale < min
+    const isMax = base * scale > max
     if (isMax || isMin) {
-      console.error("缩放范围0.05~50 将自动调整缩放值");
+      console.error(`缩放范围${min}~${max} 将自动调整缩放值`);
       if (scale > 1 && isMin) {
-        scale = 0.05 / base
+        scale = min / base
       } else if (scale < 1 && isMax) {
-        scale = 50 / base
+        scale = max / base
       } else {
         return;
       }

+ 14 - 6
src/example/components/slide/actions.ts

@@ -19,7 +19,7 @@ import { Rect } from "konva/lib/shapes/Rect";
 import { Size } from "@/utils/math";
 import { getBaseItem } from "@/core/components/util";
 import { loading } from "@/example/loadding";
-import { getImageSize } from "@/utils/shape";
+import { overviewMMToPixel } from "@/example/constant";
 
 export type PresetAdd<T extends ShapeType = ShapeType> = {
   type: T;
@@ -41,7 +41,7 @@ export const draw: MenuItem = {
   value: uuid(),
   defSelect: true,
   children: [
-    // { icon: "line", ...genDrawItem('sequentLine') },
+    { icon: "line", ...genDrawItem('lineChunk') },
     { icon: "line", ...genDrawItem("line") },
     { icon: "arrows", ...genDrawItem("arrow"), single: true },
     { icon: "rectangle", ...genDrawItem("rectangle"), single: true },
@@ -97,16 +97,20 @@ export const imp: MenuItem = {
           tileGroups,
         });
         const realSize = result.info.size;
-        const imageSize = await getImageSize(result.url);
-        const scale = realSize.width / imageSize.width;
+        const scale = 1000 * overviewMMToPixel;
+
 
         ElMessage.warning("请在画图面板中选择放置位置,鼠标右键取消");
         draw.enterDrawShape(
           "image",
           {
-            width: realSize.width,
-            height: realSize.height,
+            width: realSize.width * scale,
+            height: realSize.height * scale,
             url: result.url,
+            key: "kankan-floor-cover",
+            lock: true,
+            cornerRadius: 0,
+            zIndex: -2,
           },
           true
         );
@@ -140,7 +144,11 @@ export const imp: MenuItem = {
           {
             width: image.width,
             height: image.height,
+            key: "kankan-floor-cover",
             url,
+            lock: true,
+            cornerRadius: 0,
+            zIndex: -2,
           },
           true
         );

+ 5 - 1
src/example/constant.ts

@@ -255,4 +255,8 @@ export const tableTitleKey = "__tableTitleKey";
 export const tableCompassKey = "__tableCompassKey";
 export const mapImageKey = "__mapKey";
 export const tableCoverWidth = 370;
-export const tableCoverHeight = 306;
+export const tableCoverHeight = 306;
+
+// 像素转毫米比例
+export const overviewMMToPixel = 0.1
+export const overviewBorderMMToPixel = 7.69

+ 37 - 24
src/example/fuse/views/defStyle.ts

@@ -1,10 +1,20 @@
 import { defaultStyle as iconDefStyle } from "@/core/components/icon";
+import { fixedStrokeOptions as iconFixedStrokeOptions } from "@/core/components/icon";
 import { defaultStyle as lineIconDefStyle } from "@/core/components/line-icon";
+import { fixedStrokeOptions as lineIconFixedStrokeOptions } from "@/core/components/line-icon";
 import { defaultStyle as rectDefStyle } from "@/core/components/rectangle";
+import { fixedStrokeOptions as rectFixedStrokeOptions } from "@/core/components/rectangle";
 import { defaultStyle as circleDefStyle } from "@/core/components/circle";
+import { fixedStrokeOptions as circleFixedStrokeOptions } from "@/core/components/circle";
 import { defaultStyle as triangleDefStyle } from "@/core/components/triangle";
+import { fixedStrokeOptions as triangleFixedStrokeOptions } from "@/core/components/triangle";
 import { defaultStyle as polygonDefStyle } from "@/core/components/polygon";
+import { fixedStrokeOptions as polygonFixedStrokeOptions } from "@/core/components/polygon";
 import { defaultStyle as arrowDefStyle } from "@/core/components/arrow";
+import { fixedStrokeOptions as arrowFixedStrokeOptions } from "@/core/components/arrow";
+import { defaultStyle as lineDefStyle } from "@/core/components/line";
+import { defaultStyle as lineChunkDefStyle } from "@/core/components/line-chunk";
+import { fixedStrokeOptions as lineChunkFixedStrokeOptions } from "@/core/components/line-chunk";
 import {
   defaultStyle as serialDefStyle,
   defaultTableStyle as serialTableDefStyle,
@@ -17,7 +27,7 @@ import { getRealPixel } from "./tabulation/gen-tab";
 import { Draw } from "@/example/components/container/use-draw";
 import { ShapeType } from "@/index";
 import { watch } from "vue";
-import { PropertyDescribes } from "@/core/html-mount/propertys";
+import { overviewBorderMMToPixel, overviewMMToPixel } from "@/example/constant";
 
 const setDefStyle = <T extends {}>(
   sys: T,
@@ -116,31 +126,34 @@ export const tabCustomStyle = (p: PaperKey, draw: Draw) => {
   return mergeFuns(backs);
 };
 
+const getOverviewRealPixel = (real: number, border = false) =>
+  real * (border ? overviewBorderMMToPixel : overviewMMToPixel);
+
 export const overviewCustomStyle = (draw: Draw) => {
-  const filterIcon = (data: PropertyDescribes) => {
-    data.strokeWidth.props = {
-      ...data.strokeWidth.props,
-      proportion: true,
-    };
-    return data;
-  };
+  const realFixedStrokeOptions = [0.13, 0.18, 0.25, 0.35, 0.5, 0.7];
+  const defFixelStroke = getOverviewRealPixel(realFixedStrokeOptions[0], true);
   const backs = [
-    draw.mountFilter.setMenusFilter("icon", filterIcon),
-    draw.mountFilter.setMenusFilter("lineIcon", filterIcon),
-    setDefStyle(
-      iconDefStyle,
-      {
-        strokeWidth: 1,
-      } as any,
-      "icon"
-    ),
-    setDefStyle(
-      lineIconDefStyle,
-      {
-        strokeWidth: 1,
-      } as any,
-      "icon"
-    ),
+    setDefStyle(lineDefStyle, { strokeWidth: getOverviewRealPixel(120) }),
+    setDefStyle(triangleFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(circleFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(arrowFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(rectFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(polygonFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(iconFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(lineIconFixedStrokeOptions, realFixedStrokeOptions),
+    setDefStyle(lineChunkFixedStrokeOptions, realFixedStrokeOptions),
+    
+
+    setDefStyle(lineChunkDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(lineIconDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(iconDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(polygonDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(triangleDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(circleDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(arrowDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(rectDefStyle, { strokeWidth: defFixelStroke }),
+    setDefStyle(iconDefStyle, { strokeWidth: 1 } as any, "icon"),
+    setDefStyle(lineIconDefStyle, { strokeWidth: 1 } as any, "icon"),
   ];
   return mergeFuns(backs);
 };

+ 8 - 12
src/example/fuse/views/overview/index.vue

@@ -1,16 +1,8 @@
 <template>
-  <Container
-    :upload-resourse="uploadResourse"
-    v-model:full="full"
-    :ref="(d: any) => (draw = d?.draw)"
-  >
+  <Container :upload-resourse="uploadResourse" v-model:full="full" :ref="(d: any) => (draw = d?.draw)">
     <template #header>
-      <Header
-        @selectVR="(scene) => (vrScene = scene)"
-        title="绘图"
-        @save-after="() => mergeFuns(saveAfterHandlers)()"
-        :ref="(r) => (header = r)"
-      />
+      <Header @selectVR="(scene) => (vrScene = scene)" title="绘图" @save-after="() => mergeFuns(saveAfterHandlers)()"
+        :ref="(r) => (header = r)" />
     </template>
     <template #slide>
       <Slide />
@@ -42,6 +34,7 @@ import { params, preventReload } from "@/example/env";
 import { getFloors } from "@/example/platform/resource-swkk";
 import { mergeFuns } from "@/utils/shared";
 import { drawPlatformResource } from "@/example/platform/platform-draw";
+import { overviewBorderMMToPixel, overviewMMToPixel } from "@/example/constant";
 
 const uploadResourse = window.platform.uploadResourse;
 const full = ref(false);
@@ -93,7 +86,10 @@ const init = async (draw: Draw) => {
   draw.config.showLabelLine = true;
   draw.config.showComponentSize = false;
   draw.config.back = { color: "#f0f2f5", opacity: 1 };
-  draw.store.setConfig({ proportion: { scale: 10, unit: "mm" } });
+  draw.store.setConfig({
+    proportion: { scale: 1 / overviewMMToPixel, unit: "mm" },
+    strokeProportion: { scale: 1 / overviewBorderMMToPixel, unit: "mm" },
+  });
   // setMap(draw);
   draw.store.setStore(overviewData.value.store);
   overviewData.value.viewport && draw.viewer.setViewMat(overviewData.value.viewport);

+ 2 - 2
src/example/platform/platform-draw.ts

@@ -22,6 +22,7 @@ import {
   LineIconData,
 } from "@/core/components/line-icon";
 import { RectangleData } from "@/core/components/rectangle";
+import { overviewMMToPixel } from "../constant";
 
 const getSizePlaceBoxImage = ({ width, height }: Size) => {
   const borderWidth = 10;
@@ -427,11 +428,10 @@ export const drawPlatformResource = async (
   draw: Draw
 ) => {
   // 默认为米,转为厘米
-  const resource = await getResource({ ...sceneData, scale: 100 });
+  const resource = await getResource({ ...sceneData, scale: 1000 * overviewMMToPixel });
   let bound = null as ReturnType<ReturnType<typeof genBound>["get"]>;
 
   await draw.history.onceTrack(async () => {
-    draw.store.setConfig({ proportion: { scale: 10, unit: "mm" } });
     bound = await drawSceneResource(resource, draw);
     if (typeof resource.compass === "number") {
       draw.store.setConfig({