Parcourir la source

fix: 添加固定icon功能

bill il y a 2 mois
Parent
commit
415c751039

+ 6 - 0
public/icons/men_p_l.svg

@@ -0,0 +1,6 @@
+<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M26.5 19.5C26.5 19.5 24.2143 12 19.5 9C14.7857 5.99996 7.5 6.5 7.5 6.5" stroke="black"/>
+<path fix="true" d="M31.5 19.5H26.5V24.5H31.5L31.5 19.5Z" stroke="black"/>
+<path fix="true" d="M5.5 19.5H0.5V24.5H5.5L5.5 19.5Z" stroke="black"/>
+<path fix="true" d="M7.5 6.5H5.5V20.5H7.5L7.5 6.5Z" stroke="black"/>
+</svg>

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

@@ -6,7 +6,6 @@ import {
   getRectSnapPoints,
 } from "../util.ts";
 import { getMouseColors } from "@/utils/colors.ts";
-import { FixScreen } from "@/utils/bound.ts";
 import { InteractiveFix, InteractiveTo, MatResponseProps } from "../index.ts";
 import { Size } from "@/utils/math.ts";
 import { getSvgContent, parseSvgContent } from "@/utils/resource.ts";
@@ -127,7 +126,6 @@ export type IconData = Partial<typeof defaultStyle> &
     coverStrokeWidth?: number;
     mat: number[];
     url: string;
-    fixScreen?: FixScreen;
   };
 
 export const dataToConfig = (data: IconData) => {
@@ -157,22 +155,9 @@ export const interactiveToData: InteractiveTo<"icon"> = ({
 export const interactiveFixData: InteractiveFix<"icon"> = ({
   data,
   info,
-  viewTransform,
 }) => {
-  if (data.fixScreen) {
-    if ("x" in info.cur! && "y" in info.cur!) {
-      // 存储屏幕坐标
-      const screen = viewTransform.point(info.cur!);
-      data.fixScreen = {
-        left: screen.x,
-        top: screen.y,
-      };
-    }
-    data.mat = [1, 0, 0, 1, 0, 0];
-  } else {
-    const mat = new Transform().translate(info.cur!.x, info.cur!.y);
-    data.mat = mat.m;
-  }
+  const mat = new Transform().translate(info.cur!.x, info.cur!.y);
+  data.mat = mat.m;
   return data;
 };
 

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

@@ -17,17 +17,12 @@ import { useComponentStatus } from "@/core/hook/use-component.ts";
 import {
   PropertyUpdate,
   Operate,
-  mergeDescribes,
 } from "../../html-mount/propertys/index.ts";
 import { Transform } from "konva/lib/Util";
-import originDescribes from "../../html-mount/propertys/describes.json";
-import { ref, watchEffect } from "vue";
-import { MathUtils } from "three";
 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 { useMouseShapeStatus } from "@/core/hook/use-mouse-status.ts";
 
 const props = defineProps<{ data: IconData }>();
 const emit = defineEmits<{
@@ -40,7 +35,7 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
   emit,
   props,
   getMouseStyle,
-  transformType: props.data.fixScreen ? undefined : "custom",
+  transformType: "custom",
   customTransform(callback, shape, data) {
     let prevInvMat: Transform;
     return useCustomTransformer(shape, data, {
@@ -91,21 +86,4 @@ const { shape, tData, data, operateMenus, describes } = useComponentStatus({
     "strokeScaleEnabled",
   ],
 });
-
-const status = useMouseShapeStatus(shape);
-if (props.data.fixScreen) {
-  const other = ref({ rotate: 0 });
-  mergeDescribes(other, {}, ["rotate"], describes);
-  describes.rotate = {
-    ...originDescribes.rotate,
-    sort: 3,
-    get value() {
-      const deg = new Transform(data.value.mat).decompose().rotation % 360;
-      return Math.round(deg);
-    },
-    set value(val) {
-      data.value.mat = new Transform().rotate(MathUtils.degToRad(val)).m;
-    },
-  } as any;
-}
 </script>

+ 10 - 19
src/core/components/icon/temp-icon.vue

@@ -2,7 +2,12 @@
   <v-group :config="groupConfig" v-if="groupConfig && svg" ref="shape">
     <v-group :config="initDecMat" name="rep-position">
       <v-rect :config="rectConfig" name="repShape" />
-      <v-path v-for="config in pathConfigs" :config="config" name="icon-path" />
+      <Path
+        v-for="config in pathConfigs"
+        :config="(config as any)"
+        :mat="mat"
+      />
+      <!-- <v-path v-for="config in pathConfigs" :config="config" name="icon-path" /> -->
     </v-group>
   </v-group>
 </template>
@@ -14,10 +19,9 @@ import { getSvgContent, parseSvgContent, SVGParseResult } from "@/utils/resource
 import { Group } from "konva/lib/Group";
 import { DC } from "@/deconstruction.js";
 import { Transform } from "konva/lib/Util";
-import { useViewerInvertTransform, useViewSize } from "@/core/hook/use-viewer.ts";
-import { getFixPosition } from "@/utils/bound.ts";
 import { useStore } from "@/core/store/index.ts";
 import { useHistory } from "@/core/hook/use-history.ts";
+import Path from "./temp-path.vue";
 
 const props = defineProps<{ data: IconData; addMode?: boolean }>();
 const svg = ref<SVGParseResult | null>(null);
@@ -37,13 +41,12 @@ watch(
   async (url) => {
     svg.value = null;
     const svgContent = await getSvgContent(url);
-
     const content = parseSvgContent(svgContent);
     if (content.paths.length === 0) {
       svg.value = null;
-      console.error(props.data.url, content, "路径数据不正确不是svg");
       history.preventTrack(() => store.delItem("icon", props.data.id));
     } else {
+      console.log(content);
       svg.value = content;
     }
   },
@@ -71,7 +74,6 @@ const pathConfigs = computed(() => {
     ...path,
     ...data.value,
     id: undefined,
-    lineWidth: 1000,
     zIndex: undefined,
     offset: { x: svg.value!.x, y: svg.value!.y },
   }));
@@ -84,21 +86,10 @@ const initDecMat = computed(() => {
     .decompose();
 });
 
-const viewInvTransform = useViewerInvertTransform();
-const size = useViewSize();
+const mat = computed(() => new Transform(data.value.mat));
 const groupConfig = computed(() => {
-  let mat = new Transform(data.value.mat);
-
-  if (data.value.fixScreen) {
-    if (!size.value) return {};
-    const pos = getFixPosition(data.value.fixScreen, data.value, size.value);
-    pos.x += data.value.width / 2;
-    pos.y += data.value.height / 2;
-    mat = viewInvTransform.value.copy().translate(pos.x, pos.y).multiply(mat);
-  }
-
   return {
-    ...mat.decompose(),
+    ...mat.value.decompose(),
     zIndex: undefined,
     listening: data.value.listening,
     id: data.value.id,

+ 32 - 0
src/core/components/icon/temp-path.vue

@@ -0,0 +1,32 @@
+<template>
+  <v-path :config="config" name="icon-path" />
+
+  <v-path :config="props.config" name="icon-path" />
+</template>
+
+<script lang="ts" setup>
+import { parseSvgContent } from "@/utils/resource";
+import { Transform } from "konva/lib/Util";
+import { computed } from "vue";
+
+const props = defineProps<{
+  config: ReturnType<typeof parseSvgContent>["paths"][0];
+  mat: Transform;
+}>();
+
+const config = computed(() => {
+  if (!props.config.fix) {
+    return props.config;
+  }
+  // return props.config;
+  const inv = props.mat.copy().invert();
+  const invDec = inv.decompose();
+  const config = {
+    ...props.config,
+    ...invDec,
+    x: 0,
+    y: 0,
+  };
+  return config;
+});
+</script>

+ 2 - 6
src/core/helper/split-line.vue

@@ -96,13 +96,9 @@ const center = computed(() => {
 });
 
 const compsInfo = useComponentsAttach(
-  (type, item) => {
+  (type, item): Pos[] => {
     if (config.labelLineConfig.showShapeTypes.includes(type)) {
-      if (type === "icon" && (item as any).fixScreen) {
-        return [];
-      } else {
-        return components[type].getSnapPoints(item as any);
-      }
+      return components[type].getSnapPoints(item as any);
     } else {
       return [];
     }

+ 7 - 0
src/example/constant.ts

@@ -21,6 +21,7 @@ export const iconGroups: IconGroup[] = [
         name: "门",
         children: [
           { wall: true, icon: "men_l", name: "左开门" },
+          
           { wall: true, icon: "men", name: "右开门" },
           { wall: true, icon: "shuangkaimen", name: "双开门" },
           { wall: true, icon: "yimen", name: "移门" },
@@ -167,3 +168,9 @@ export const styleIconMap = {
   "style-16": "danke_o",
   "style-17": "chelunhenji_o",
 };
+
+if (import.meta.env.DEV) {
+  iconGroups[0].children[0].children.push(
+    { wall: true, icon: "men_p_l", name: "百分比左开门" },
+  )
+}

+ 3 - 0
src/utils/resource.ts

@@ -67,6 +67,7 @@ export type SVGPath = {
   stroke?: string;
   strokeWidth?: number;
   data: string;
+  fix: boolean
 };
 export type SVGParseResult = Size & Pos & {
   paths: SVGPath[];
@@ -100,11 +101,13 @@ export let parseSvgContent = (svgContent: string): SVGParseResult => {
       const fill = path.getAttribute("fill")!;
       const data = path.getAttribute("d")!;
       const stroke = path.getAttribute("stroke")!;
+      const fix = path.getAttribute("fix") === "true";
       const strokeWidth = path.getAttribute("stroke-width")!;
       return {
         fill,
         data,
         stroke,
+        fix,
         strokeWidth: (strokeWidth && Number(strokeWidth)) || 1,
       };
     });