bill 3 mesi fa
parent
commit
988df36568

+ 2 - 1
.env.jmdev

@@ -5,7 +5,8 @@ VITE_ENTRY_EXAMPLE='./main.ts'
 VITE_MOCK_ENV=jmtest
 
 VITE_STATIC='http://192.168.0.25'
-VITE_OSS_ROOT="/oss/"
+VITE_OSS='/oss/'
+VITE_OSS_ROOT="/rootOss/"
 VITE_MESH_OSS='/meshOSS/'
 VITE_MESH_API='/meshAPI/'
 VITE_CLOUD_API='/cloudAPI/'

+ 1 - 0
.env.jmtest

@@ -5,6 +5,7 @@ VITE_ENTRY_EXAMPLE='./main.ts'
 
 
 VITE_OSS_ROOT="http://192.168.0.25/"
+VITE_OSS='http://192.168.0.25/oss/'
 VITE_MESH_OSS='http://192.168.0.25/oss/'
 VITE_MESH_API='http://192.168.0.25/'
 VITE_CLOUD_API='http://192.168.0.25/'

+ 1 - 1
index.html

@@ -2,7 +2,7 @@
 <html lang="en">
   <head>
     <meta charset="UTF-8" />
-    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+    <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title><%- title %></title>
   </head>

File diff suppressed because it is too large
+ 1 - 0
public/icons/polygon.svg


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

@@ -63,7 +63,7 @@ const { shape, tData, operateMenus, describes, data } = useComponentStatus<
   // alignment(data, mat) {
   //   return matResponse({ mat, data, increment: true });
   // },
-  transformType: "line",
+  // transformType: "line",
   getRepShape(): Line {
     return new Line({
       fill: themeColor,

+ 7 - 0
src/core/components/circle/circle.vue

@@ -26,6 +26,7 @@ import { cloneRepShape, useCustomTransformer } from "@/core/hook/use-transformer
 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";
 
 const props = defineProps<{ data: CircleData }>();
 const emit = defineEmits<{
@@ -60,6 +61,12 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus<
         initRadius = { x: repShape.radiusX(), y: repShape.radiusY() };
         return {
           shape: repShape,
+          update(data, shape) {
+            repShape.radiusX(data.radiusX);
+            repShape.radiusY(data.radiusY);
+            setShapeTransform(repShape, new Transform(data.mat));
+            initRadius = { x: repShape.radiusX(), y: repShape.radiusY() };
+          },
         };
       },
       beforeHandler(data, mat) {

+ 1 - 2
src/core/components/image/temp-image.vue

@@ -15,7 +15,7 @@
 
 <script lang="ts" setup>
 import { defaultStyle, ImageData } from "./index.ts";
-import { computed, ref, watch } from "vue";
+import { computed, ref, watch, watchEffect } from "vue";
 import { getImage } from "@/utils/resource.ts";
 import { Transform } from "konva/lib/Util";
 import { Group } from "konva/lib/Group";
@@ -26,7 +26,6 @@ const props = defineProps<{ data: ImageData; addMode?: boolean }>();
 const data = computed(() => ({ ...defaultStyle, ...props.data }));
 const image = ref<HTMLImageElement | null>(null);
 const shape = ref<DC<Group>>();
-
 defineExpose({
   get shape() {
     return shape.value;

+ 26 - 22
src/core/components/index.ts

@@ -10,7 +10,7 @@ import * as image from "./image";
 import * as table from "./table";
 import * as serial from "./serial";
 import * as group from "./group";
-import * as sequentLine from './sequent-line'
+import * as sequentLine from "./sequent-line";
 
 import { SLineData } from "./sequent-line";
 import { ArrowData } from "./arrow";
@@ -45,19 +45,24 @@ const _components = {
   table,
   serial,
   group,
-  sequentLine
+  sequentLine,
 };
 
-export const components = _components as Components
-
+export const components = _components as any as Components;
+type CompAttach<key extends ShapeType> = {
+  delItem?: (
+    store: DrawStore,
+    data: DrawItem<key>,
+    childrenId?: string
+  ) => void;
+  useDraw?: () => void;
+  getSnapInfos?: (items: DrawItem<key>) => ComponentSnapInfo[];
+  GroupComponent: (props: { data: DrawItem[] }) => any;
+  getPredefine?: (attrKey: keyof DrawItem<key>) => any;
+};
 export type Components = {
-  [key in keyof typeof _components]: (typeof _components)[key] & {
-    delItem?: (store: DrawStore, data: DrawItem<key>) => void
-    useDraw?: () => void
-    getSnapInfos?: (items: DrawItem<key>) => ComponentSnapInfo[];
-    GroupComponent: (props: { data: DrawItem[] }) => any;
-    getPredefine?: (attrKey: keyof DrawItem<key>) => any
-  };
+  [key in keyof typeof _components]: Omit<(typeof _components)[key], keyof CompAttach<key>> &
+    CompAttach<key>
 };
 export type ComponentValue<
   T extends ShapeType,
@@ -76,8 +81,8 @@ export type DrawDataItem = {
   image: ImageData;
   table: TableData;
   serial: SerialData;
-  group: GroupData,
-  sequentLine: SLineData
+  group: GroupData;
+  sequentLine: SLineData;
 };
 export type ShapeType = keyof DrawDataItem;
 
@@ -101,23 +106,22 @@ export type InteractiveTo<T extends ShapeType> = (args: {
   viewTransform: Transform;
   store: DrawStore;
   history: DrawHistory;
-  drawing?: boolean
+  drawing?: boolean;
 }) => DrawItem<T> | undefined;
 
 export type InteractiveFix<T extends ShapeType> = (args: {
   data: DrawItem<T>;
   info: AddMessage<T>;
-  notdraw?: boolean
+  notdraw?: boolean;
   viewTransform: Transform;
   store: DrawStore;
   history: DrawHistory;
 }) => DrawItem<T>;
 
 export type MatResponseProps<T extends ShapeType> = {
-  data: DrawItem<T>, 
-  mat: Transform, 
-  increment?: boolean,
-  operType?: TransformerVectorType
-  store?: DrawStore
-  
-}
+  data: DrawItem<T>;
+  mat: Transform;
+  increment?: boolean;
+  operType?: TransformerVectorType;
+  store?: DrawStore;
+};

+ 15 - 0
src/core/components/line/index.ts

@@ -5,6 +5,8 @@ import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts";
 import { Transform } from "konva/lib/Util";
 import { inRevise, onlyId, rangMod } from "@/utils/shared.ts";
 import { MathUtils } from "three";
+import { DrawStore } from "@/core/store/index.ts";
+import { getInitCtx, normalLineData } from "./use-draw.ts";
 
 
 export { default as Component } from "./line.vue";
@@ -151,3 +153,16 @@ export const getPredefine = (key: keyof LineData) => {
     return { proportion: true };
   }
 };
+
+
+export const delItem = (store: DrawStore, data: LineData, childId: string) => {
+  const ndx = data.lines.findIndex(item => item.id === childId)
+  if (!~ndx) return;
+
+  const delLine = data.lines[ndx]
+  const ctx = getInitCtx()
+  ctx.del.lines[delLine.id] = delLine
+  data.lines.splice(ndx, 1)
+  normalLineData(data, ctx);
+  store.setItem('line', {value: data, id: data.id})
+}

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

@@ -5,7 +5,7 @@
     :opacity="isDrawIng ? 0.5 : 1"
     :points="points"
     :closed="false"
-    :id="data.id"
+    :id="line.id"
     :disablePoint="!canEdit || mode.include(Mode.readonly)"
     :ndx="0"
     @dragstart="dragstartHandler(points.map((item) => item.id))"

+ 11 - 0
src/core/components/line/use-draw.ts

@@ -373,5 +373,16 @@ export const normalLineData = (data: LineData, ctx: NLineDataCtx) => {
     }
   }
 
+  const pointIds = Object.values(ctx.del.lines).flatMap(item => [item.a, item.b])
+  const linePointIds = data.lines.flatMap(item => [item.a, item.b])
+
+  for (let id of pointIds) {
+    if (!linePointIds.includes(id)) {
+      const ndx = data.points.findIndex(p => p.id === id)
+      console.log('delPoint', ndx)
+      ~ndx && data.points.splice(ndx, 1)
+    }
+  }
+
   return deduplicateLines(data);
 };

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

@@ -52,7 +52,7 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
     "stroke",
     "strokeWidth",
     // "dash",
-    "opacity",
+    // "opacity",
     //  "ref", "zIndex"
   ],
 });

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

@@ -2,6 +2,7 @@
   <v-line
     ref="line"
     :config="{
+      id: id,
       strokeWidth: data.strokeWidth,
       opacity: opacity || 0,
       stroke: data.stroke,

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

@@ -24,7 +24,6 @@ export const getMouseStyle = (data: TriangleData) => {
   const strokeStatus = data.stroke && getMouseColors(data.stroke);
   const strokeWidth = data.strokeWidth;
 
-  console.log(data)
   return {
     default: {
       fill: data.fill,

+ 46 - 22
src/core/hook/use-expose.ts

@@ -11,7 +11,11 @@ import { useMode, useOperMode } from "./use-status";
 import { Stage } from "konva/lib/Stage";
 import { useInteractiveProps } from "./use-interactive.ts";
 import { useStore } from "../store/index.ts";
-import { useGetViewBoxPositionPixel, useSetViewport, useViewer } from "./use-viewer.ts";
+import {
+  useGetViewBoxPositionPixel,
+  useSetViewport,
+  useViewer,
+} from "./use-viewer.ts";
 import { useGlobalResize, useListener } from "./use-event.ts";
 import { useInteractiveDrawShapeAPI } from "./use-draw.ts";
 import { useHistory } from "./use-history.ts";
@@ -27,7 +31,7 @@ import { useResourceHandler } from "./use-fetch.ts";
 import { useConfig } from "./use-config.ts";
 import { useSelectionRevise } from "./use-selection.ts";
 import { useFormalLayer, useGetFormalChildren } from "./use-layer.ts";
-import { components } from "../components/index.ts";
+import { components, DrawItem } from "../components/index.ts";
 import { useProportion } from "./use-proportion.ts";
 import { ShapeType } from "@/index.ts";
 import { useGetDXF } from "./use-dxf.ts";
@@ -84,7 +88,9 @@ export const useShortcutKey = () => {
 
       const addCount = quitDrawShape();
       // 钢笔工具需要右键两次才退出,右键一次相当于完成
-      const isDots = ['dots', 'single-dots'].includes(components[iProps.type].addMode);
+      const isDots = ["dots", "single-dots"].includes(
+        components[iProps.type].addMode
+      );
       if (isDots && addCount > 0) {
         setTimeout(() => {
           enterDrawShape(iProps.type, iProps.preset, iProps.operate?.single);
@@ -102,7 +108,7 @@ export const useShortcutKey = () => {
     "keydown",
     (ev) => {
       if (ev.target !== document.body) return;
-      
+
       if (ev.key === "z" && ev.ctrlKey) {
         history.hasUndo.value && history.undo();
       } else if (ev.key === "y" && ev.ctrlKey) {
@@ -112,27 +118,46 @@ export const useShortcutKey = () => {
         // history.saveLocal();
       } else if (ev.key === "Delete" || ev.key === "Backspace") {
         // 删除
-        
+
         const isSelect = status.selects.length;
         const shapes = isSelect ? status.selects : status.actives;
-        const delItems = shapes.map((shape) => {
-          const id = shape.id();
-          if (!id) return;
-          const item = store.getItemById(id)
-          const type = store.getType(id);
-          if (!item?.disableDelete && type) {
-            return [type, item] as const
-          }
-        }).filter(item => !!item);
-        history.onceTrack(() => {
-
-          delItems.forEach(([type, item]) => {
-            if (components[type as ShapeType].delItem) {
-              components[type as ShapeType].delItem!(store, item as any)
+        const delItems = shapes
+          .map((shape) => {
+            let curId = shape.id();
+            if (!curId) return;
+            let id: string;
+            let item: DrawItem | undefined;
+            let type: ShapeType | undefined;
+            do {
+              id = shape.id();
+              item = store.getItemById(id);
+              type = store.getType(id);
+              if (item && type) {
+                break;
+              }
+            } while ((shape = shape.parent as any));
+            if (!type) return;
+            if (id === curId) {
+              if (!item?.disableDelete && type) {
+                return [type, item, undefined] as const;
+              }
             } else {
-              store.delItem(type as ShapeType, item!.id);
+              return [type, item, curId] as const;
             }
           })
+          .filter((item) => !!item);
+        history.onceTrack(() => {
+          delItems.forEach(([type, item, childId]) => {
+            if (!childId) {
+              if (components[type as ShapeType].delItem) {
+                components[type as ShapeType].delItem!(store, item as any);
+              } else {
+                store.delItem(type as ShapeType, item!.id);
+              }
+            } else {
+              components[type as ShapeType].delItem!(store, item as any, childId);
+            }
+          });
         });
         if (delItems.length) {
           if (isSelect) {
@@ -254,7 +279,6 @@ export const useExpose = installGlobalVar(() => {
     });
   };
 
-  
   return {
     ...useInteractiveDrawShapeAPI(),
     get stage() {
@@ -279,6 +303,6 @@ export const useExpose = installGlobalVar(() => {
     config: useConfig(),
     mountMenus: useMountMenusAttachs(),
     proportion: useProportion(),
-    getDXF: useGetDXF()
+    getDXF: useGetDXF(),
   };
 });

+ 29 - 13
src/core/hook/use-transformer.ts

@@ -1,5 +1,5 @@
 import { useMouseShapeStatus } from "./use-mouse-status.ts";
-import { computed, Ref, ref, toRaw, watch } from "vue";
+import { computed, Ref, ref, toRaw, watch, watchEffect } from "vue";
 import { DC, EntityShape } from "../../deconstruction";
 import {
   installGlobalVar,
@@ -78,10 +78,10 @@ export const useTransformer = installGlobalVar(() => {
     $g.add($text);
     $node.parent!.add($g);
     setShapeTransform($g, $node.getTransform());
-    $g.y($g.y() - 2 * $text.fontSize());
+    $g.y($g.y() - 4 * $text.fontSize());
 
     const updateText = () => {
-      const rotation = transformer.rotation() % 360;
+      const rotation = (transformer.rotation() + 360) % 360;
       $text.rotation(-rotation).text(` ${round(rotation, 1)}°`);
     };
 
@@ -94,18 +94,19 @@ export const useTransformer = installGlobalVar(() => {
   });
 
   const cleanups: (() => void)[] = [];
+  const getData = useGetComponentData()
   const viewer = useViewer();
   getSvgContent("./icons/m_rotate.svg").then((svgContent) => {
     const svg = parseSvgContent(svgContent);
-    const group = new Group({listening: false});
+    const group = new Group({ listening: false });
     const rotateRect = transformer.findOne<Rect>(".rotater")!;
     const size = 8;
     rotateRect.scale({ x: 2, y: 2 });
 
-    const bg = new Circle({ radius: 6, fill: themeColor, x: 0.5, y: 0.5 })
-    group.add(bg)
+    const bg = new Circle({ radius: 6, fill: themeColor, x: 0.5, y: 0.5 });
+    group.add(bg);
     svg.paths.forEach((path) => {
-      const $path = new Path({ ...path, fill: '#ffffff' });
+      const $path = new Path({ ...path, fill: "#ffffff" });
       const scale = size / svg.width;
       $path.scale({ x: scale, y: scale });
       $path.offset({ x: svg.width / 2, y: svg.height / 2 });
@@ -120,12 +121,26 @@ export const useTransformer = installGlobalVar(() => {
       group.y(group.y() + 8);
       group.visible(rotateRect.visible());
     };
-    transformer.on("transform.updateRotate", () => setTimeout(update));
-    viewer.viewer.bus.on("transformChange", update);
+    viewer.viewer.bus.on("transformChange", update)
+
+    const stopShapeJoin = watch(
+      () => transformer.queueShapes.value[0],
+      (shape, _b, onCleanup) => {
+        if (shape) {
+          const data = getData(computed(() => shape))
+          update();
+          shape.on("bound-change", update);
+          onCleanup(() => shape.off("bound-change", update));
+          onCleanup(watch(data, () => setTimeout(update)))
+        }
+      },
+      { immediate: true }
+    );
+
     cleanups.push(
-      () => transformer.off("transform.updateRotate"),
       watch(() => transformer.queueShapes.value, update, { flush: "sync" }),
-      () => viewer.viewer.bus.off("transformChange", update)
+      () => viewer.viewer.bus.off("transformChange", update),
+      stopShapeJoin
     );
   });
 
@@ -326,7 +341,6 @@ export const useShapeTransformer = <T extends EntityShape>(
   const transformer = useTransformer();
   const transformIngShapes = useTransformIngShapes();
   const viewTransform = useViewerTransform();
-  const getComponentData = useGetComponentData();
   const can = useCan();
 
   const init = ($shape: T) => {
@@ -455,8 +469,9 @@ export const useShapeTransformer = <T extends EntityShape>(
         );
 
         const stopLeaveUpdate = watch(
-          () => getComponentData($shape).value,
+          data,
           () => {
+            console.log("update");
             rep.update && rep.update();
           },
           { flush: "post", deep: true }
@@ -704,6 +719,7 @@ export const useLineTransformer = <T extends LineTransformerData>(
         ? repShape
         : (repShape as unknown as Group).findOne<Line>(".line")!;
       const update = (data: T) => {
+        console.error("update");
         const attitude = new Transform(data.attitude);
         const inverMat = attitude.copy().invert();
         setShapeTransform(repShape, attitude);

+ 2 - 0
src/core/hook/use-viewer.ts

@@ -229,6 +229,8 @@ export const useSetViewport = () => {
           x: rect.x + rect.width,
           y: rect.y + rect.height,
         };
+
+    viewer.setViewMat(new Transform())
     viewer.setBound({
       targetBound: {
         ...lt,

+ 1 - 1
src/example/components/header/actions.ts

@@ -94,7 +94,7 @@ export const getHeaderActions = (draw: Draw) => {
               draw.config.showGrid = false
               const pop = draw.mode.push(Mode.readonly)
               await nextTick()
-              saveAs(await getImage(draw, 'image/jpeg'), "canvas.png");
+              saveAs(await getImage(draw, 'image/jpeg'), "canvas.jpg");
               pop()
               draw.config.showGrid = oldShowGrid
             })

+ 1 - 1
src/example/components/slide/actions.ts

@@ -38,7 +38,7 @@ export const draw: MenuItem = {
     { icon: "rectangle", ...genDrawItem("rectangle"), single: true },
     { icon: "circle", ...genDrawItem("circle"), single: true },
     { icon: "triangulartriangular", ...genDrawItem("triangle"), single: true },
-    { icon: "line", ...genDrawItem("polygon") },
+    { icon: "polygon", ...genDrawItem("polygon") },
   ],
 };
 

+ 1 - 1
src/example/constant.ts

@@ -42,7 +42,6 @@ export const iconGroups = [
           { icon: "SingleSofa", name: "单人沙发" },
           { icon: "TeaTable", name: "茶几" },
           { icon: "Carpet", name: "地毯" },
-          { icon: "Carpet", name: "地毯" },
           { icon: "Plant", name: "植物" },
           { icon: "DiningTable", name: "餐桌" },
         ],
@@ -111,4 +110,5 @@ export const aiIconMap = {
   SingleWindow: 'cad-chuang',
   BayWindow: 'cad-piaochuang',
   FrenchWindow: 'cad-luodichuang',
+  Chair: 'Desk'
 }

+ 66 - 45
src/example/platform/platform-draw.ts

@@ -13,7 +13,9 @@ const scaleResource = (info: AIExposeData, scale: number) => {
   const floors = info.floors.map((item) => ({
     ...item,
     geos: item.geos.map((geo) =>
-      geo.map((p) => ({ x: p.x * scale, y: p.y * scale, z: p.z * scale }))
+      geo.map((p) => {
+        return { x: p.x * scale, y: p.y * scale, z: p.z * scale }
+      })
     ),
     box: item.box && {
       ...item.box,
@@ -38,26 +40,32 @@ const scaleResource = (info: AIExposeData, scale: number) => {
             y: item.position.y * scale,
             z: item.position.z * scale,
           },
+          size: item.size
+            ? {
+                width: item.size!.width * scale,
+                height: item.size!.height * scale,
+              }
+            : undefined,
         };
       } else if (item.subgroup !== undefined) {
-        const floor = floors.find(
-          (floor) => floor.subgroup === item.subgroup
-        );
+        const floor = floors.find((floor) => floor.subgroup === item.subgroup);
         if (!floor || !floor.box) return;
         const w = floor.box.bound.x_max - floor.box.bound.x_min;
         const h = floor.box.bound.y_max - floor.box.bound.y_min;
-        
+
         return {
           ...item,
           position: {
-            x: (floor.box.bound.x_min + w * item.position.x) ,
-            y: (floor.box.bound.y_min + h * item.position.y) ,
-            z: (floor.box.bound.z_min + 0.001) ,
-          },
-          size: {
-            width: item.size!.width * w ,
-            height: item.size!.height * h ,
+            x: floor.box.bound.x_min + w * item.position.x,
+            y: floor.box.bound.y_min + h * item.position.y,
+            z: floor.box.bound.z_min + 0.001,
           },
+          size: item.size
+            ? {
+                width: item.size!.width * w,
+                height: item.size!.height * h,
+              }
+            : undefined,
         };
       }
     })
@@ -99,9 +107,13 @@ const getResourceLayers = (data: AIExposeData) => {
         box,
         taggings: data.taggings
           .filter((item) => {
-            console.log(item, item.position.z, box.bound, 
-              item.position.z > box.bound.z_min &&
-              item.position.z <= box.bound.z_max)
+            // console.log(
+            //   item,
+            //   item.position.z,
+            //   box.bound,
+            //   item.position.z > box.bound.z_min &&
+            //     item.position.z <= box.bound.z_max
+            // );
             return (
               item.position.z > box.bound.z_min &&
               item.position.z <= box.bound.z_max
@@ -125,46 +137,49 @@ const drawLayerResource = (
   const images: any[] = [];
   const createTime = Date.now();
 
-  let sGeo = draw.store.getTypeItems('line')[0]
-  let geo: LineData = sGeo ? sGeo : {
-    ...getBaseItem(),
-    lines: [],
-    points: [],
-    polygon: [],
-    attitude: [1, 0, 0, 1, 0, 0],
-    createTime: createTime,
-  }
-  const geoCtx = getInitCtx()
+  let sGeo = draw.store.getTypeItems("line")[0];
+  let geo: LineData = sGeo
+    ? sGeo
+    : {
+        ...getBaseItem(),
+        lines: [],
+        points: [],
+        polygon: [],
+        attitude: [1, 0, 0, 1, 0, 0],
+        createTime: createTime,
+      };
+  const geoCtx = getInitCtx();
 
   layerResource.geos.forEach((item) => {
     bound.update(item);
     if (item.length < 1) return;
 
-    let a: string = onlyId(), b: string
-    let i = 0
+    let a: string = onlyId(),
+      b: string;
+    let i = 0;
     for (i = 0; i < item.length - 1; i++) {
-      b = onlyId()
-      const lId = onlyId()
-      const l = {  id: onlyId(), a, b, ...defaultStyle }
-      const p = { id: a, ...item[i] }
-      geoCtx.add.points[a] = p
-      geoCtx.add.lines[lId] = l
-      geo.points.push(p)
-      geo.lines.push(l)
-      a = b
+      b = onlyId();
+      const lId = onlyId();
+      const l = { id: onlyId(), a, b, ...defaultStyle };
+      const p = { id: a, ...item[i] };
+      geoCtx.add.points[a] = p;
+      geoCtx.add.lines[lId] = l;
+      geo.points.push(p);
+      geo.lines.push(l);
+      a = b;
     }
-    const p = { id: b!, ...item[i] }
-    geoCtx.add.points[b!] = p
-    geo.points.push(p)
+    const p = { id: b!, ...item[i] };
+    geoCtx.add.points[b!] = p;
+    geo.points.push(p);
   });
   draw.history.onceTrack(() => {
-    geo = normalLineData(geo, geoCtx)
+    geo = normalLineData(geo, geoCtx);
     if (sGeo) {
-      draw.store.setItem('line', {id: geo.id, value: geo });  
+      draw.store.setItem("line", { id: geo.id, value: geo });
     } else {
-      draw.store.addItem('line', geo);
+      draw.store.addItem("line", geo);
     }
-  })
+  });
 
   if (layerResource.thumb) {
     const box = layerResource.box;
@@ -191,15 +206,20 @@ const drawLayerResource = (
   images.push(
     ...layerResource.taggings.map((item, ndx) => {
       bound.update(item.position);
+      const tf = new Transform()
+        .translate(item.position.x, item.position.y)
+      if (item.rotate) {
+        tf.rotate(item.rotate)
+      }
       return {
         ...getBaseItem(),
         ...iconDefaultStyle,
         name: item.name,
-        fill: '#000000',
+        fill: item.url.includes(".svg") ? "#000000" : undefined,
         createTime: createTime + layerResource.geos.length + ndx,
         url: item.url,
         lock: import.meta.env.DEV ? false : true,
-        mat: [1, 0, 0, 1, item.position.x, item.position.y],
+        mat: tf.m,
         width: item.size ? item.size.width : 100,
         height: item.size ? item.size.height : 100,
         // width: 30,
@@ -208,6 +228,7 @@ const drawLayerResource = (
       };
     })
   );
+
   draw.store.addItems(
     "icon",
     images.filter((item) => item.url.includes(".svg"))

+ 19 - 9
src/example/platform/platform-resource.ts

@@ -1,7 +1,8 @@
 import { Pos, Size } from "@/utils/math";
 import { extractConnectedSegments } from "@/utils/polygon";
-import { validNum } from "@/utils/shared";
+import { round, validNum } from "@/utils/shared";
 import { aiIconMap, iconGroups } from "../constant";
+import { Euler, Quaternion } from "three";
 
 export enum SCENE_TYPE {
   fuse = "fuse",
@@ -41,6 +42,7 @@ export type Taging = {
   url: string;
   position: Pos & { z: number };
   size?: Size;
+  rotate?: number
   name?: string;
   pixel?: boolean;
   subgroup?: string;
@@ -202,8 +204,10 @@ export const taggingGets = {
         .then((url) => fetch(url))
         .then((res) => res.json())
         .catch(() => []);
-      signages.forEach((signage: any) => {
-        if (!validNum(signage.pos[0]) || !validNum(signage.pos[1])) return;
+
+
+      const reqs = signages.map((signage: any) => {
+        if (!validNum(signage.pos[0]) || !validNum(signage.pos[2])) return;
         const getIcon =
           signage.icon.indexOf("style-") === 0
             ? getSceneApi('ossRoot', `/sdk/images/billboard/${signage.icon}.png`)
@@ -214,13 +218,20 @@ export const taggingGets = {
               url,
               position: {
                 x: signage.pos[0],
-                y: signage.pos[1],
-                z: signage.pos[0],
+                y: signage.pos[2],
+                z: signage.pos[1] < 0 ? (Math.ceil(signage.pos[1]) * 10) / 10 : (Math.floor(signage.pos[1]) * 10) / 10,
               },
+              rotate: 0,
+              size: {
+                width: signage.width * (signage.scaleRatio / 100),
+                height: signage.height* (signage.scaleRatio / 100)
+              }
             });
           })
           .catch(() => {});
       });
+
+      await Promise.all(reqs)
     }
 
     await getSceneApi(
@@ -230,6 +241,7 @@ export const taggingGets = {
       .then((url) => fetch(url))
       .then((res) => res.json())
       .then((datas) => {
+        console.error(datas)
         for (const data of datas) {
           const reg = data.imagePath.match(/floor_(\d)\.png/);
           const subgroup = reg ? Number(reg[1]) : undefined;
@@ -248,6 +260,7 @@ export const taggingGets = {
                 ? (aiIconMap as any)[shape.category]
                 : shape.category;
             let name = "";
+            console.log(icon)
             for (const group of iconGroups) {
               for (const itemGroup of group.children) {
                 for (const item of itemGroup.children) {
@@ -257,6 +270,7 @@ export const taggingGets = {
                 }
               }
             }
+            console.error(name, pos)
             if (!name) return;
             tags.push({
               position: pos,
@@ -309,10 +323,6 @@ export const lineGets = {
     const reqs = floors
       .filter((item: any) => !floorName || item.name === floorName)
       .map((floor: any) => {
-        console.log(
-          floor,
-          bounds.find((i: any) => i.subgroup === floor.subgroup)
-        );
         const bound = {
           ...(floor.cadInfo.cadBoundingBox || {}),
           ...(bounds.find((i: any) => i.subgroup === floor.subgroup)?.bound ||

+ 2 - 0
vite.config.ts

@@ -33,6 +33,8 @@ export default ({ mode }: any) => {
     }
   }
 
+  console.log(proxy)
+
   return defineConfig({
     base: './',
     resolve: {