Browse Source

fix: Merge branch 'master' into merge-selection

bill 2 months ago
parent
commit
5f82c48acf

+ 5 - 0
public/static/kankan.html

@@ -56,6 +56,10 @@
         server: host,
         resource: host + '/oss/'
       })
+      console.log(kankan.store)
+      kankan.store.on('floorcad', floor => {
+        console.log('floorcad', floor)
+      })
       kankan.Scene.on('loaded', () => {
         const player = kankan.core.get('Player')
         player.viewLinkManager.addEventListener('loaded', () => {
@@ -68,6 +72,7 @@
         
       })
       kankan.render()
+
     }
   </script>
 

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

@@ -0,0 +1,184 @@
+import { Transform } from "konva/lib/Util";
+import {
+  BaseItem,
+  generateSnapInfos,
+  getBaseItem,
+  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";
+import { Color } from "three";
+
+export const shapeName = "图例";
+export const defaultStyle = {
+  coverFill: '#000000',
+  coverOpcatiy: 0,
+  strokeScaleEnabled: false,
+  width: 80,
+  height: 80,
+};
+
+  type ColorCounts = [string, number][]
+  const colorsManage = (counts: ColorCounts, color: any) => {
+  if (!color) {
+    return;
+  }
+  const colorHex = new Color(color).getHexString()
+  const item = counts.find(([c]) => c === colorHex)
+  if (!item) {
+    counts.push([colorHex, 1])
+  } else {
+    item[1]++
+  }
+}
+const findColor = (counts: ColorCounts) => {
+  let ndx = -1
+  let max = 0
+  for (let i = 0; i < counts.length; i++) {
+    if (counts[i][1] >= max) {
+      ndx = i
+      max = counts[i][1]
+    }
+  }
+  if (~ndx) {
+    return `#${counts[ndx][0]}`
+  }
+}
+
+export const getIconStyle = async (url: string, width = defaultStyle.width, height = defaultStyle.height) => {
+  const svgContent = parseSvgContent(await getSvgContent(url));
+  if (width / height > svgContent.width / svgContent.height) {
+    width = svgContent.width / svgContent.height * height
+  } else {
+    height = svgContent.height / svgContent.width * width
+  }
+  const fillColorCounts: [string, number][] = []
+  const strokeColorCounts: [string, number][] = []
+
+  for (let i = 0; i < svgContent.paths.length; i++) {
+    colorsManage(fillColorCounts, svgContent.paths[i].fill)
+    colorsManage(strokeColorCounts, svgContent.paths[i].stroke)
+  }
+
+  const color = {
+    fill: findColor(fillColorCounts) || null,
+    stroke: findColor(strokeColorCounts) || null
+  };
+  if (!color.fill && !color.stroke) {
+    color.stroke = "#000000";
+  } 
+  return {
+    url,
+    width,
+    height,
+    ...color
+  }
+}
+
+export const addMode = "dot";
+
+export const getSnapInfos = (data: IconData) => {
+  return generateSnapInfos(getSnapPoints(data), true, false);
+};
+
+export const getSnapPoints = (data: IconData) => {
+  const tf = new Transform(data.mat);
+  const w = data.width || defaultStyle.width;
+  const h = data.height || defaultStyle.height;
+  const points = getRectSnapPoints(w, h);
+  return points.map((v) => tf.point(v));
+};
+
+export const getMouseStyle = (data: IconData) => {
+  const fillStatus = getMouseColors(data.coverFill || defaultStyle.coverFill);
+  const hCoverOpcaoty = data.coverOpcatiy ? data.coverOpcatiy : 0.3;
+
+  return {
+    default: {
+      coverFill: data.coverFill || defaultStyle.coverFill,
+      coverOpcatiy: data.coverOpcatiy || 0,
+    },
+    hover: { coverFill: fillStatus.hover, coverOpcatiy: hCoverOpcaoty },
+    select: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty  },
+    focus: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty  },
+    press: { coverFill: fillStatus.press, coverOpcatiy: hCoverOpcaoty },
+  };
+};
+
+export type IconData = Partial<typeof defaultStyle> &
+  BaseItem & Size & {
+    fill?: string | null;
+    stroke?: string | null;
+    name?: string
+    strokeWidth?: number;
+    coverFill?: string;
+    coverStroke?: string;
+    coverStrokeWidth?: number;
+    mat: number[];
+    url: string;
+    fixScreen?: FixScreen;
+  };
+
+export const dataToConfig = (data: IconData) => {
+  return {
+    ...defaultStyle,
+    ...data,
+  };
+};
+
+export const interactiveToData: InteractiveTo<"icon"> = ({
+  info,
+  preset = {},
+  viewTransform,
+  ...args
+}) => {
+  if (info.cur) {
+  console.error(preset)
+    return interactiveFixData({
+      ...args,
+      viewTransform,
+      info,
+      data: { ...getBaseItem(), ...preset } as unknown as IconData,
+    });
+  }
+};
+
+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;
+  }
+  return data;
+};
+
+
+
+
+export const matResponse = ({data, mat, increment}: MatResponseProps<'icon'>) => {
+  data.mat = increment ? mat.copy().multiply(new Transform(data.mat)).m : mat.m;
+  return data;
+}
+
+
+export const getPredefine = (key: keyof IconData) => {
+  if (key === 'fill' || key === 'stroke') {
+    return { canun: true }
+  }
+}

+ 4 - 186
src/core/components/icon/index.ts

@@ -1,186 +1,4 @@
-import { Transform } from "konva/lib/Util";
-import {
-  BaseItem,
-  generateSnapInfos,
-  getBaseItem,
-  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";
-import { Color } from "three";
-
-export { default as Component } from "./icon.vue";
-export { default as TempComponent } from "./temp-icon.vue";
-
-export const shapeName = "图例";
-export const defaultStyle = {
-  coverFill: '#000000',
-  coverOpcatiy: 0,
-  strokeScaleEnabled: false,
-  width: 80,
-  height: 80,
-};
-
-  type ColorCounts = [string, number][]
-  const colorsManage = (counts: ColorCounts, color: any) => {
-  if (!color) {
-    return;
-  }
-  const colorHex = new Color(color).getHexString()
-  const item = counts.find(([c]) => c === colorHex)
-  if (!item) {
-    counts.push([colorHex, 1])
-  } else {
-    item[1]++
-  }
-}
-const findColor = (counts: ColorCounts) => {
-  let ndx = -1
-  let max = 0
-  for (let i = 0; i < counts.length; i++) {
-    if (counts[i][1] >= max) {
-      ndx = i
-      max = counts[i][1]
-    }
-  }
-  if (~ndx) {
-    return `#${counts[ndx][0]}`
-  }
-}
-
-export const getIconStyle = async (url: string, width = defaultStyle.width, height = defaultStyle.height) => {
-  const svgContent = parseSvgContent(await getSvgContent(url));
-  if (width / height > svgContent.width / svgContent.height) {
-    width = svgContent.width / svgContent.height * height
-  } else {
-    height = svgContent.height / svgContent.width * width
-  }
-  const fillColorCounts: [string, number][] = []
-  const strokeColorCounts: [string, number][] = []
-
-  for (let i = 0; i < svgContent.paths.length; i++) {
-    colorsManage(fillColorCounts, svgContent.paths[i].fill)
-    colorsManage(strokeColorCounts, svgContent.paths[i].stroke)
-  }
-
-  const color = {
-    fill: findColor(fillColorCounts) || null,
-    stroke: findColor(strokeColorCounts) || null
-  };
-  if (!color.fill && !color.stroke) {
-    color.stroke = "#000000";
-  } 
-  return {
-    url,
-    width,
-    height,
-    ...color
-  }
-}
-
-export const addMode = "dot";
-
-export const getSnapInfos = (data: IconData) => {
-  return generateSnapInfos(getSnapPoints(data), true, false);
-};
-
-export const getSnapPoints = (data: IconData) => {
-  const tf = new Transform(data.mat);
-  const w = data.width || defaultStyle.width;
-  const h = data.height || defaultStyle.height;
-  const points = getRectSnapPoints(w, h);
-  return points.map((v) => tf.point(v));
-};
-
-export const getMouseStyle = (data: IconData) => {
-  const fillStatus = getMouseColors(data.coverFill || defaultStyle.coverFill);
-  const hCoverOpcaoty = data.coverOpcatiy ? data.coverOpcatiy : 0.3;
-
-  return {
-    default: {
-      coverFill: data.coverFill || defaultStyle.coverFill,
-      coverOpcatiy: data.coverOpcatiy || 0,
-    },
-    hover: { coverFill: fillStatus.hover, coverOpcatiy: hCoverOpcaoty },
-    select: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty  },
-    focus: { coverFill: fillStatus.select, coverOpcatiy: hCoverOpcaoty  },
-    press: { coverFill: fillStatus.press, coverOpcatiy: hCoverOpcaoty },
-  };
-};
-
-export type IconData = Partial<typeof defaultStyle> &
-  BaseItem & Size & {
-    fill?: string | null;
-    stroke?: string | null;
-    name?: string
-    strokeWidth?: number;
-    coverFill?: string;
-    coverStroke?: string;
-    coverStrokeWidth?: number;
-    mat: number[];
-    url: string;
-    fixScreen?: FixScreen;
-  };
-
-export const dataToConfig = (data: IconData) => {
-  return {
-    ...defaultStyle,
-    ...data,
-  };
-};
-
-export const interactiveToData: InteractiveTo<"icon"> = ({
-  info,
-  preset = {},
-  viewTransform,
-  ...args
-}) => {
-  if (info.cur) {
-    return interactiveFixData({
-      ...args,
-      viewTransform,
-      info,
-      data: { ...getBaseItem(), ...preset } as unknown as IconData,
-    });
-  }
-};
-
-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;
-  }
-  return data;
-};
-
-
-
-
-export const matResponse = ({data, mat, increment}: MatResponseProps<'icon'>) => {
-  data.mat = increment ? mat.copy().multiply(new Transform(data.mat)).m : mat.m;
-  return data;
-}
-
-
-export const getPredefine = (key: keyof IconData) => {
-  if (key === 'fill' || key === 'stroke') {
-    return { canun: true }
-  }
-}
+export * from './icon.ts'
+import TempComponent from "./temp-icon.vue";
+import Component from "./icon.vue";
+export { TempComponent, Component }

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

@@ -8,7 +8,7 @@
 </template>
 
 <script lang="ts" setup>
-import { defaultStyle, IconData } from "./index.ts";
+import { defaultStyle, IconData } from "./icon.ts";
 import { computed, ref, watch } from "vue";
 import { getSvgContent, parseSvgContent, SVGParseResult } from "@/utils/resource.ts";
 import { Group } from "konva/lib/Group";

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

@@ -4,6 +4,7 @@
       :config="{
         ...data,
         ...config,
+        shadowForStrokeEnabled: true,
         id: undefined,
         zIndex: undefined,
       }"

+ 51 - 51
src/core/renderer/renderer.vue

@@ -1,63 +1,63 @@
 <template>
+  <div
+    class="draw-layout"
+    @contextmenu.prevent
+    :style="{ cursor: cursorStyle }"
+    ref="layout"
+    :class="{ temp: tempStatus }"
+  >
+    <div class="mount-mask" :id="DomOutMountId" />
     <div
-      class="draw-layout"
-      @contextmenu.prevent
-      :style="{ cursor: cursorStyle }"
-      ref="layout"
-      :class="{ temp: tempStatus }"
+      class="draw-content"
+      :style="fix && { width: size?.width + 'px', height: size?.height + 'px' }"
     >
-      <div class="mount-mask" :id="DomOutMountId" />
-      <div
-        class="draw-content"
-        :style="fix && { width: size?.width + 'px', height: size?.height + 'px' }"
-      >
-        <div class="mount-mask" :id="DomMountId"></div>
+      <div class="mount-mask" :id="DomMountId"></div>
 
-        <v-stage ref="stage" :config="size" v-if="layout">
-          <v-layer :config="viewerConfig" id="formal">
+      <v-stage ref="stage" :config="size" v-if="layout">
+        <v-layer :config="viewerConfig" id="formal">
+          <v-group>
             <v-group>
-              <v-group>
-                <Back />
-              </v-group>
-              <v-group>
-                <BackGrid v-if="expose.config.showGrid" />
-              </v-group>
-            </v-group>
-            <v-group :id="DataGroupId">
-              <component
-                :is="GroupComponentMap[type]"
-                v-for="type in types"
-                :type="type"
-                :key="type"
-              />
+              <Back />
             </v-group>
             <v-group>
-              <component
-                v-for="part in mountParts.value"
-                :is="part.comp"
-                :key="part.props.key"
-                v-bind="part.props"
-              />
+              <BackGrid v-if="expose.config.showGrid" />
             </v-group>
-          </v-layer>
-          <!--	临时组,提供临时绘画,以及高频率渲染	-->
-          <v-layer :config="viewerConfig" id="temp">
-            <template v-if="mode.include(Mode.draw)">
-              <TempShapeGroup v-for="type in types" :type="type" :key="type" />
-            </template>
-          </v-layer>
-          <v-layer id="helper">
-            <!-- <ActiveBoxs /> -->
-            <SnapLines />
-            <SplitLine v-if="expose.config.showLabelLine" />
-            <Compass v-if="config.showCompass" />
-            <layers v-if="store.layers.length > 1" />
-            <Debugger v-if="isDev" />
-            <Border />
-          </v-layer>
-        </v-stage>
-      </div>
+          </v-group>
+          <v-group :id="DataGroupId">
+            <component
+              :is="GroupComponentMap[type]"
+              v-for="type in types"
+              :type="type"
+              :key="type"
+            />
+          </v-group>
+          <v-group>
+            <component
+              v-for="part in mountParts.value"
+              :is="part.comp"
+              :key="part.props.key"
+              v-bind="part.props"
+            />
+          </v-group>
+        </v-layer>
+        <!--	临时组,提供临时绘画,以及高频率渲染	-->
+        <v-layer :config="viewerConfig" id="temp">
+          <template v-if="mode.include(Mode.draw)">
+            <TempShapeGroup v-for="type in types" :type="type" :key="type" />
+          </template>
+        </v-layer>
+        <v-layer id="helper">
+          <!-- <ActiveBoxs /> -->
+          <SnapLines />
+          <SplitLine v-if="expose.config.showLabelLine" />
+          <Compass v-if="config.showCompass" />
+          <layers v-if="store.layers.length > 1" />
+          <Debugger v-if="isDev" />
+          <Border />
+        </v-layer>
+      </v-stage>
     </div>
+  </div>
 </template>
 
 <script lang="ts" setup>

+ 2 - 0
src/example/fuse/views/defStyle.ts

@@ -2,6 +2,7 @@ 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 polygonDefStyle } from "@/core/components/polygon";
 import { defaultStyle as arrowDefStyle } from "@/core/components/arrow";
 import {
   defaultStyle as serialDefStyle,
@@ -87,6 +88,7 @@ export const tabCustomStyle = (p: PaperKey, draw: Draw) => {
       tableStrokeWidth: getRealPixel(0.5, p),
       repColCount: 2,
     } as any),
+    setDefStyle(polygonDefStyle, { strokeWidth: getRealPixel(0.5, p) }),
     setDefStyle(tableDefStyle, { strokeWidth: getRealPixel(0.5, p) }),
     setDefStyle(rectDefStyle, { strokeWidth: getRealPixel(0.5, p) }),
     setDefStyle(circleDefStyle, { strokeWidth: getRealPixel(0.5, p) }),

+ 2 - 0
src/example/fuse/views/tabulation/gen-tab.ts

@@ -41,6 +41,7 @@ export const transformPaper = (
 
 export const getCoverPaperScale = (cover: ImageData, paperKey: PaperKey) => {
   let pixelScale = (cover.widthRaw! / cover.width) * cover.proportion!.scale;
+  console.log(cover.width, cover.height)
   const realPixelScale = paperConfigs[paperKey].scale;
   return realPixelScale * pixelScale;
 };
@@ -49,6 +50,7 @@ export const setCoverPaperScale = (cover: ImageData, paperKey: PaperKey, scale:
   const realPixelScale = paperConfigs[paperKey].scale;
   cover.width = cover.widthRaw! / ((scale / realPixelScale) /cover.proportion!.scale)
   cover.height = (cover.heightRaw! / cover.widthRaw!) * cover.width
+  console.log(cover.width, cover.height)
 }
 
 export const genTabulationData = async (paperKey: PaperKey, compass?: number, cover?: TabCover | null) => {

+ 10 - 6
src/example/fuse/views/tabulation/header.vue

@@ -31,6 +31,7 @@ import { Mode } from "@/constant/mode.ts";
 import { overviewId, tabulationId } from "@/example/env.ts";
 import { listener } from "@/utils/event.ts";
 import { router } from "../../router.ts";
+import { paperConfigs } from "@/example/components/slide/actions.ts";
 
 const props = defineProps<{ title: string }>();
 
@@ -81,7 +82,7 @@ const actions = [
       handler: async () => {
         const ef = await selectExposeFormat();
         const format = "image/jpeg";
-        let [rect, fileBlob] = await getCoverImage(format);
+        let [_, fileBlob] = await getCoverImage(format);
         const filename = props.title;
         let ext = "jpg";
 
@@ -93,13 +94,16 @@ const actions = [
         }
 
         if (ef.format === "PDF") {
+          const paperKey = tabulationData.value?.paperKey || "a4";
+          const paperSize = paperConfigs[paperKey].size;
           const url = URL.createObjectURL(fileBlob);
           const img = await getResourceImage(url);
-          const pdf = new jsPDF(rect.width > rect.height ? "l" : "p", "px", [
-            rect.width,
-            rect.height,
-          ]);
-          pdf.addImage(img, format, 0, 0, rect.width, rect.height);
+          const pdf = new jsPDF({
+            orientation: paperSize[0] > paperSize[1] ? "landscape" : "portrait",
+            unit: "mm",
+            format: paperKey,
+          });
+          pdf.addImage(img, format, 0, 0, paperSize[0], paperSize[1]);
           fileBlob = pdf.output("blob");
           ext = "pdf";
           URL.revokeObjectURL(url);