Bläddra i källkod

fix: 修复bug

bill 2 månader sedan
förälder
incheckning
036784e2ad

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 9 - 1
public/icons/compass.svg


+ 4 - 14
public/styles/style-19.svg

@@ -1,15 +1,5 @@
 <svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
-<g clip-path="url(#clip0_171304_610716)">
-<mask id="mask0_171304_610716" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="32" height="32">
-<path d="M32 0H0V32H32V0Z" fill="white"/>
-</mask>
-<g mask="url(#mask0_171304_610716)">
-<path d="M16.0003 1.33203L21.3337 6.66537L18.6673 6.66536V12.0285C18.6832 12.7511 19.2739 13.332 20.0003 13.332H25.3337V10.6654L30.667 15.9987L25.3337 21.332V18.6654H19.9981C19.2727 18.6666 18.6832 19.2471 18.6673 19.9689V25.332H21.3337L16.0003 30.6654L10.667 25.332H13.3337V19.9987C13.3337 19.2631 12.7379 18.6666 12.0026 18.6654H6.66731V21.332L1.33398 15.9987L6.66731 10.6654V13.332H12.0003C12.7367 13.332 13.3337 12.7351 13.3337 11.9987V6.66536L10.667 6.66537L16.0003 1.33203Z" stroke="black"/>
-</g>
-</g>
-<defs>
-<clipPath id="clip0_171304_610716">
-<rect width="32" height="32" fill="white"/>
-</clipPath>
-</defs>
-</svg>
+  <path
+    d="M16.0003 1.33203L21.3337 6.66537L18.6673 6.66536V12.0285C18.6832 12.7511 19.2739 13.332 20.0003 13.332H25.3337V10.6654L30.667 15.9987L25.3337 21.332V18.6654H19.9981C19.2727 18.6666 18.6832 19.2471 18.6673 19.9689V25.332H21.3337L16.0003 30.6654L10.667 25.332H13.3337V19.9987C13.3337 19.2631 12.7379 18.6666 12.0026 18.6654H6.66731V21.332L1.33398 15.9987L6.66731 10.6654V13.332H12.0003C12.7367 13.332 13.3337 12.7351 13.3337 11.9987V6.66536L10.667 6.66537L16.0003 1.33203Z"
+    stroke="black" />
+</svg>

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

@@ -66,7 +66,6 @@ export const getIconStyle = async (url: string, width = defaultStyle.width, heig
     colorsManage(strokeColorCounts, svgContent.paths[i].stroke)
   }
 
-  console.log(fillColorCounts, strokeColorCounts)
   const color = {
     fill: findColor(fillColorCounts) || null,
     stroke: findColor(strokeColorCounts) || null
@@ -74,8 +73,8 @@ export const getIconStyle = async (url: string, width = defaultStyle.width, heig
   if (!color.fill && !color.stroke) {
     color.stroke = "#000000";
   } 
-  console.log(color, fillColorCounts)
   return {
+    url,
     width,
     height,
     ...color
@@ -140,6 +139,7 @@ export const interactiveToData: InteractiveTo<"icon"> = ({
   ...args
 }) => {
   if (info.cur) {
+  console.error(preset)
     return interactiveFixData({
       ...args,
       viewTransform,
@@ -168,6 +168,7 @@ export const interactiveFixData: InteractiveFix<"icon"> = ({
     const mat = new Transform().translate(info.cur!.x, info.cur!.y);
     data.mat = mat.m;
   }
+  console.error(data)
   return data;
 };
 

+ 1 - 0
src/core/components/icon/temp-icon.vue

@@ -33,6 +33,7 @@ watch(
   async (url) => {
     svg.value = null;
     const svgContent = await getSvgContent(url);
+
     const content = parseSvgContent(svgContent);
     if (content.paths.length === 0) {
       svg.value = null;

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

@@ -25,6 +25,7 @@ export const defaultTableStyle = {
   nameColWidth: 100,
   valueColWidth: 180,
   repColCount: 1,
+  tableStrokeWidth: 1
 };
 export const shapeName = "序号";
 export const addMode = "dot";

+ 2 - 0
src/core/components/serial/serial-group.vue

@@ -102,6 +102,7 @@ const addTable = () => {
     );
   }
 
+  console.log("===>", defaultTableStyle.tableStrokeWidth);
   return tableInteractiveToData({
     info: { cur: [pos, end] },
     preset: {
@@ -110,6 +111,7 @@ const addTable = () => {
       key: joinKey,
       fontSize: defaultTableStyle.fontSize,
       content: [content],
+      strokeWidth: defaultTableStyle.tableStrokeWidth,
     },
     store,
     history,

+ 21 - 10
src/core/hook/use-dxf.ts

@@ -10,6 +10,7 @@ import {
   HatchPolylineBoundary,
   vertex,
 } from "@tarikjabiri/dxf";
+import { defaultStyle as iconDefStyle } from '../components/icon'
 import { useStore } from "../store";
 import Zip from "jszip";
 import { LineData } from "../components/line";
@@ -160,19 +161,23 @@ export const useGetDXF = () => {
       });
     };
 
-    const writeImage = async (imgGroup: Group, minSize: Size) => {
-      let rect = imgGroup.getClientRect();
+    const writeImage = async (imgGroup: Group, scaleCallback?: (scale: Size) => () => void) => {
+      let curRect = imgGroup.getClientRect();
       const oldViewMat = viewer.viewMat;
-      setViewport(rect);
+      setViewport(curRect);
       await nextTick();
-      rect = imgGroup.getClientRect();
+      const imgRect = imgGroup.getClientRect();
+      const back = scaleCallback && scaleCallback({ width: imgRect.width / curRect.width, height: imgRect.height / curRect.height })
+      await nextTick()
       const img = (await imgGroup!.toImage({
         pixelRatio: 1,
         quality: 1,
         mimeType: "image/png",
       })) as HTMLImageElement;
-      const start = invMat.value.point({ x: rect.x, y: rect.y + rect.height });
-      const end = invMat.value.point({ x: rect.x + rect.width, y: rect.y });
+      back && back()
+      await nextTick()
+      const start = invMat.value.point({ x: imgRect.x, y: imgRect.y + imgRect.height });
+      const end = invMat.value.point({ x: imgRect.x + imgRect.width, y: imgRect.y });
       const name = onlyId().replace(/\-/g, "");
       const path = name + ".png";
 
@@ -349,15 +354,21 @@ export const useGetDXF = () => {
 
         case "image":
           item = _item as ImageData;
-          await writeImage($stage.findOne<Group>(`#${item.id}`)!, item);
+          await writeImage($stage.findOne<Group>(`#${item.id}`)!);
           break;
 
         case "icon":
-          item = _item as IconData;
+          const iconItem = _item as IconData;
           const pathGroup = $stage
-            .findOne<Group>(`#${item.id}`)!
+            .findOne<Group>(`#${iconItem.id}`)!
             .findOne<Group>(".rep-position")!;
-          await writeImage(pathGroup, item);
+          await writeImage(pathGroup, (scale) => {
+            const sw = iconItem.strokeWidth || (iconDefStyle as any).strokeWidth || undefined
+            iconItem.strokeWidth = sw && (sw * Math.max(scale.width, scale.height))
+            return () => {
+              iconItem.strokeWidth = sw
+            }
+          });
           break;
       }
     }

+ 6 - 9
src/core/hook/use-expose.ts

@@ -5,6 +5,7 @@ import {
   useLayers,
   useMountMenusFilter,
   useMouseMenusFilter,
+  useRunHook,
   useStage,
   useTempStatus,
 } from "./use-global-vars.ts";
@@ -49,14 +50,8 @@ export const useAutoPaste = () => {
       async handler(pos, val) {
         if (isSvgString(val)) {
           const url = await resourceHandler(val, "svg");
-          // const icon = await getIconStyle(url)
-          // if (icon.fill) {
-          //   icon.fill = '#000000'
-          // }
-          // if (icon.stroke) {
-          //   icon.stroke = '#000000'
-          // }
-          drawAPI.addShape("icon", { url }, pos, true);
+          const style = await getIconStyle(url, 100, 100)
+          drawAPI.addShape("icon", { ...style, fill: undefined, stroke: undefined }, pos, true);
         } else {
           drawAPI.addShape("text", { content: val }, pos, true);
         }
@@ -67,7 +62,8 @@ export const useAutoPaste = () => {
       async handler(pos, val, type) {
         const url = await resourceHandler(val, type);
         if (type.includes("svg")) {
-          drawAPI.addShape("icon", { url, stroke: null, fill: '#000000' }, pos, true);
+          const style = await getIconStyle(url, 100, 100)
+          drawAPI.addShape("icon", { ...style, fill: undefined, stroke: undefined }, pos, true);
         } else {
           const image = await getImage(url);
           drawAPI.addShape(
@@ -318,6 +314,7 @@ export const useExpose = installGlobalVar(() => {
     },
     getViewBoxPositionPixel: useGetViewBoxPositionPixel(),
     viewer,
+    runHook: useRunHook(),
     presetAdd: interactiveProps,
     config: useConfig(),
     mountFilter: useMountMenusFilter(),

+ 14 - 1
src/core/hook/use-global-vars.ts

@@ -28,8 +28,9 @@ import { PropertyDescribes } from "../html-mount/propertys/index.ts";
 import { ShapeType } from "@/index.ts";
 import { isEditableElement } from "@/utils/dom.ts";
 
+let getInstance = getCurrentInstance
 export const useRendererInstance = () => {
-  let instance = getCurrentInstance()!;
+  let instance = getInstance()!;
   while (instance.type.name !== rendererName) {
     if (instance.parent) {
       instance = instance.parent;
@@ -66,6 +67,18 @@ export const installGlobalVar = <T>(
   return useGlobalVar;
 };
 
+export const useRunHook = installGlobalVar(() => {
+  const instance = getCurrentInstance()
+  return <R, T extends () => R>(hook: T): R => {
+    const back = getInstance
+    getInstance = () => instance
+    const result = hook()
+    getInstance = back
+    return result
+  }
+})
+
+
 export type InstanceProps = {
   id?: string;
   data?: StoreData;

+ 2 - 0
src/core/html-mount/propertys/components/num.vue

@@ -44,6 +44,8 @@ const emit = defineEmits<{
 const changeHandler = (val: number) => {
   emit("update:value", val);
 };
+
+console.log(proportion.value.scale, props.value);
 </script>
 
 <style lang="scss" scoped>

+ 81 - 51
src/example/fuse/views/defStyle.ts

@@ -1,71 +1,101 @@
-import { defaultStyle as iconDefStyle } from '@/core/components/icon'
-import { defaultStyle as rectDefStyle } from '@/core/components/rectangle'
-import { defaultStyle as circleDefStyle } from '@/core/components/circle'
-import { defaultStyle as triangleDefStyle } from '@/core/components/triangle'
-import { defaultStyle as arrowDefStyle } from '@/core/components/arrow'
-import { PaperKey } from '@/example/components/slide/actions'
-import { mergeFuns } from '@/utils/shared'
-import { getRealPixel } from './tabulation/gen-tab'
-import { defaultTableStyle } from '@/core/components/serial'
-import { Draw } from '@/example/components/container/use-draw'
+import { defaultStyle as iconDefStyle } from "@/core/components/icon";
+import { defaultStyle as rectDefStyle } from "@/core/components/rectangle";
+import { defaultStyle as circleDefStyle } from "@/core/components/circle";
+import { defaultStyle as triangleDefStyle } from "@/core/components/triangle";
+import { defaultStyle as arrowDefStyle } from "@/core/components/arrow";
+import { defaultStyle as serialDefStyle, defaultTableStyle as serialTableDefStyle } from "@/core/components/serial";
+import { defaultStyle as tableDefStyle } from "@/core/components/table";
+import { PaperKey } from "@/example/components/slide/actions";
+import { mergeFuns } from "@/utils/shared";
+import { getRealPixel } from "./tabulation/gen-tab";
+import { Draw } from "@/example/components/container/use-draw";
 
-const setDefStyle = <T extends {}>(sys: T, custom: Partial<T>) => {
-  const backs: (() => void)[] = []
+const setDefStyle = <T extends {}>(
+  sys: T,
+  custom: Partial<T>,
+  itemKey?: string
+) => {
+  const backs: (() => void)[] = [];
   for (const key in custom) {
-    const oldVal = sys[key]
-    sys[key] = custom[key]!
-    backs.push(() => sys[key] = oldVal)
+    const oldVal = sys[key];
+    sys[key] = custom[key]!;
+    backs.push(() => {
+      sys[key] = oldVal;
+    });
   }
 
-  return mergeFuns(backs)
-}
+  return mergeFuns(backs);
+};
 
 export const tabCustomStyle = (p: PaperKey, draw: Draw) => {
-  draw.mountFilter.setMenusFilter('icon', (data) => {
-    data.strokeWidth.props = {
-      ...data.strokeWidth.props,
-      proportion: true
-    }
-    return data
-  })
+  const types = ["icon", "table", "serial"] as const;
+  types.forEach((type) => {
+    draw.mountFilter.setMenusFilter(type, (data) => {
+      data.strokeWidth.props = {
+        ...data.strokeWidth.props,
+        proportion: true,
+      };
+      return data;
+    });
+  });
+
   const backs = [
     () => {
-      draw.mountFilter.setMenusFilter('icon')
+      types.forEach((type) => {
+        draw.mountFilter.setMenusFilter(type);
+      });
     },
-    setDefStyle(iconDefStyle, {
-      width: getRealPixel(10, p),
-      height: getRealPixel(10, p),
-      strokeWidth: getRealPixel(1, p)
-    } as any),
-    setDefStyle(defaultTableStyle, {
-      nameColWidth: defaultTableStyle.valueColWidth = getRealPixel(20, p),
+    setDefStyle(
+      iconDefStyle,
+      {
+        width: getRealPixel(10, p),
+        height: getRealPixel(10, p),
+        strokeWidth: getRealPixel(1, p),
+      } as any,
+      "icon"
+    ),
+    setDefStyle(serialDefStyle, {
+      nameColWidth: getRealPixel(20, p),
       fontSize: getRealPixel(4, p),
       padding: getRealPixel(2, p),
       colHeight: getRealPixel(8, p),
+      strokeWidth: getRealPixel(1, p),
+      tableStrokeWidth: getRealPixel(2, p),
+      fill: null,
       repColCount: 2,
-    }),
-    setDefStyle(rectDefStyle, {strokeWidth: getRealPixel(1, p)}),
-    setDefStyle(circleDefStyle, {strokeWidth: getRealPixel(1, p)}),
-    setDefStyle(triangleDefStyle, {strokeWidth: getRealPixel(1, p)}),
-    setDefStyle(arrowDefStyle, {strokeWidth: getRealPixel(1, p)}),
-  ]
-  console.log(iconDefStyle)
+    } as any),
+    setDefStyle(serialTableDefStyle, {
+      tableStrokeWidth: getRealPixel(2, p),
+    } as any),
+    setDefStyle(tableDefStyle, { strokeWidth: getRealPixel(2, p) }),
+    setDefStyle(rectDefStyle, { strokeWidth: getRealPixel(1, p) }),
+    setDefStyle(circleDefStyle, { strokeWidth: getRealPixel(1, p) }),
+    setDefStyle(triangleDefStyle, { strokeWidth: getRealPixel(1, p) }),
+    setDefStyle(arrowDefStyle, { strokeWidth: getRealPixel(1, p) }),
+  ];
 
-  return mergeFuns(backs)
-}
+  return mergeFuns(backs);
+};
 
 export const overviewCustomStyle = (draw: Draw) => {
-  draw.mountFilter.setMenusFilter('icon', (data) => {
+  draw.mountFilter.setMenusFilter("icon", (data) => {
     data.strokeWidth.props = {
       ...data.strokeWidth.props,
-      proportion: true
-    }
-    return data
-  })
+      proportion: true,
+    };
+    return data;
+  });
   const backs = [
     () => {
-      draw.mountFilter.setMenusFilter('icon')
-    }
-  ]
-  return mergeFuns(backs)
-}
+      draw.mountFilter.setMenusFilter("icon");
+    },
+    setDefStyle(
+      iconDefStyle,
+      {
+        strokeWidth: 1,
+      } as any,
+      "icon"
+    ),
+  ];
+  return mergeFuns(backs);
+};

+ 9 - 10
src/example/fuse/views/overview/header.vue

@@ -34,6 +34,7 @@ import { repTabulationStore } from "../tabulation/gen-tab.ts";
 import { router } from "../../router.ts";
 import { overviewId, tabulationId } from "@/example/env.ts";
 import { listener } from "@/utils/event.ts";
+import { repeatedlyOnly } from "@/utils/shared.ts";
 
 const props = defineProps<{ title: string }>();
 const draw = useDraw();
@@ -130,9 +131,7 @@ const setViewToTableCover = async () => {
   ] as const;
 };
 
-let isUpload = false;
-const saveHandler = async () => {
-  isUpload = true;
+const saveHandler = repeatedlyOnly(async () => {
   const storeData = draw.getData();
   const [blob, scale, rect] = await draw.enterTemp(async () => {
     const [rect, recover] = await setViewToTableCover();
@@ -157,7 +156,6 @@ const saveHandler = async () => {
     viewport: draw!.viewer.transform.m,
   });
 
-  console.log(rect);
   const cover = {
     url,
     width: rect.width,
@@ -183,21 +181,22 @@ const saveHandler = async () => {
     store: tabStore,
     overviewId: overviewId.value,
   });
-  isUpload = false;
-};
+  console.log("保存完毕");
+});
 
 onUnmounted(
   listener(document.documentElement, "keydown", (ev) => {
-    if (!isUpload && ev.ctrlKey && ev.key.toUpperCase() === "S") {
+    if (ev.ctrlKey && ev.key.toUpperCase() === "S") {
       saveHandler();
     }
   })
 );
 
-const gotoTabulation = async () => {
+const gotoTabulation = repeatedlyOnly(async () => {
   await saveHandler();
+  console.log("跳转tab");
   router.push({ ...router.currentRoute.value, name: "tabulation" } as any);
-};
+});
 
-defineExpose({ gotoTabulation, saveHandler })
+defineExpose({ gotoTabulation, saveHandler });
 </script>

+ 5 - 7
src/example/fuse/views/tabulation/gen-tab.ts

@@ -22,7 +22,7 @@ import { ImageData } from "@/core/components/image";
 import { DrawData } from "@/core/components";
 import { getEmptyStoreData, StoreData } from "@/core/store/store";
 import { defaultLayer } from "@/constant";
-import { IconData } from "@/core/components/icon";
+import { getIconStyle, IconData } from "@/core/components/icon";
 import { MathUtils } from "three";
 
 export const getRealPixel = (real: number, paperKey: PaperKey) => {
@@ -193,15 +193,13 @@ export const genTabulationData = async (paperKey: PaperKey, compass?: number, co
     return title;
   };
 
-  const getCompass = () => {
+  const getCompass = async () => {
     const mat = new Transform().rotate(MathUtils.degToRad(compass!))
+    const style =await getIconStyle('./icons/compass.svg', getRealPixel(37.3366 / 2.3, paperKey), getRealPixel(60 / 2.3, paperKey))
     
     const data: IconData = {
       ...getBaseItem(),
-      width: getRealPixel(37.3366 / 2.3, paperKey),
-      height: getRealPixel(60 / 2.3, paperKey),
-      url: './icons/compass.svg',
-      fill: "#000000",
+      ...style,
       disableDelete: true,
       itemName: '指南针',
       coverOpcatiy: 0,
@@ -234,7 +232,7 @@ export const genTabulationData = async (paperKey: PaperKey, compass?: number, co
     data.text!.push(getCoverScale(image))
   }
   if (compass !== undefined) {
-    data.icon = [getCompass()]
+    data.icon = [await getCompass()]
   }
 
   return data

+ 15 - 2
src/example/fuse/views/tabulation/index.vue

@@ -43,12 +43,13 @@ import { Transform } from "konva/lib/Util";
 import { MathUtils } from "three";
 import { components } from "@/core/components";
 import { ShapeType } from "@/index";
-import { round } from "@/utils/shared";
+import { mergeFuns, round } from "@/utils/shared";
 import { PaperKey } from "@/example/components/slide/actions";
 import { StoreData } from "@/core/store/store";
 import { getImageSize } from "@/utils/shape";
 import { tabCustomStyle } from "../defStyle";
 import { defaultLayer } from "@/constant";
+import { useViewBoxPixelRect } from "@/core/hook/use-viewer";
 
 const uploadResourse = window.platform.uploadResourse;
 const full = ref(false);
@@ -78,6 +79,7 @@ const setMap = async (paperKey: PaperKey, compass: number, store: StoreData) =>
 
 const inited = ref(false);
 const init = async (draw: Draw) => {
+  const quitMerges: Array<() => void> = [];
   await refreshTabulationData();
   draw.config.showCompass = false;
   draw.config.showGrid = false;
@@ -103,7 +105,18 @@ const init = async (draw: Draw) => {
     },
   });
   inited.value = true;
-  return tabCustomStyle(p, draw);
+
+  draw.runHook(() => {
+    const size = useViewBoxPixelRect();
+    quitMerges.push(
+      watchEffect(() => {
+        console.log("当前视口:", size.value);
+      })
+    );
+  });
+
+  quitMerges.push(tabCustomStyle(p, draw));
+  return () => mergeFuns(quitMerges)();
 };
 watch(draw, (draw, _, onCleanup) => {
   if (draw) {

+ 17 - 7
src/example/platform/platform-draw.ts

@@ -5,7 +5,10 @@ import { SceneFloor } from "./platform-resource";
 import { getBaseItem } from "@/core/components/util";
 import { LineData, defaultStyle } from "@/core/components/line";
 import { getInitCtx, normalLineData } from "@/core/components/line/use-draw";
-import { getIconStyle, defaultStyle as iconDefaultStyle } from "@/core/components/icon";
+import {
+  getIconStyle,
+  defaultStyle as iconDefaultStyle,
+} from "@/core/components/icon";
 import { defaultStyle as textDefaultStyle } from "@/core/components/text";
 import { Transform } from "konva/lib/Util";
 import { ElMessage } from "element-plus";
@@ -113,11 +116,13 @@ const getResourceLayers = (data: AIExposeData) => {
         box = floor.box;
       }
 
+      console.log("楼层范围", box.bound.z_min, box.bound.z_max);
       return {
         ...floor,
         box,
         taggings: data.taggings
           .filter((item) => {
+            console.log("tag高度", item.position.z);
             return (
               item.position.z === undefined ||
               (item.position.z >= box.bound.z_min &&
@@ -296,17 +301,22 @@ const drawLayerResource = async (
         mat: tf.m,
       });
     } else {
-      let svgAttach: any = {};
+      let attach: any = {
+        width: item.size ? item.size.width : 100,
+        height: item.size ? item.size.height : 100,
+      };
       if (item.url.includes(".svg")) {
-        svgAttach = {
+        attach = {
           ...iconDefaultStyle,
           stroke: "#000000",
           fill: null,
-          width: item.size ? item.size.width : 100,
-          height: item.size ? item.size.height : 100,
         };
         try {
-          svgAttach = await getIconStyle(item.url, item.size?.width, item.size?.height)
+          attach = await getIconStyle(
+            item.url,
+            item.size?.width,
+            item.size?.height
+          );
         } catch {}
       }
 
@@ -318,7 +328,7 @@ const drawLayerResource = async (
         lock: import.meta.env.DEV ? false : true,
         mat: tf.m,
         cornerRadius: 0,
-        ...svgAttach,
+        ...attach,
       });
     }
   }

+ 22 - 0
src/utils/shared.ts

@@ -401,4 +401,26 @@ export function getSupportedFont(fonts: string[]) {
   }
   ctx.font = defaultFont;
   return fonts[fonts.length - 1]; // 返回最后一个回退字体
+}
+
+export const repeatedlyOnly = <T extends (...args: any[]) => any>(fn: T) => {
+  let empty = uuid()
+  let prevResult: any = empty
+  const pack = (...args: any[]) => {
+    if (prevResult === empty) {
+      const result = fn(...args)
+      if (result instanceof Promise) {
+        prevResult = result
+        return result.then(r => {
+          prevResult = empty
+          return r
+        });
+      } else {
+        return result
+      }
+    } else {
+      return prevResult
+    }
+  }
+  return pack as T
 }