Forráskód Böngészése

fix: 修改需求

bill 2 éve
szülő
commit
79a48b8f16

+ 100 - 0
src/components/edit-fix-point/index.vue

@@ -0,0 +1,100 @@
+<template>
+  <div class="edit-fix-point" @touchstart.stop>
+    <div class="header">
+      <h3>添加名称</h3>
+      <ui-icon type="close" ctrl @click="$emit('quit')" />
+    </div>
+    <ui-input
+      type="text"
+      :modelValue="text"
+      @update:modelValue="(text) => $emit('update:text', text)"
+      width="100%"
+      maxlength="20"
+      class="search-fix"
+    />
+    <div class="select">
+      <span>常用名称</span>
+      <p
+        v-for="option in options"
+        :key="option"
+        :class="{ active: option === text }"
+        @click="$emit('update:text', option)"
+      >
+        {{ option }}
+      </p>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { ref } from "vue";
+
+defineProps<{ text: string }>();
+defineEmits<{ (e: "quit"): void; (e: "update:text", v: string): void }>();
+
+const dom = ref<HTMLDivElement>();
+defineExpose(dom);
+
+const options = [
+  "轿车 / 平面",
+  "客车 / 平面",
+  "客车 / 侧面",
+  "货车 / 平面",
+  "牵引车 / 平面",
+  "正三轮机动车 / 平面",
+  "自行车",
+  "伤体",
+  "牲畜",
+  "散落物",
+  "岗台",
+  "桥",
+];
+</script>
+
+<style lang="scss" scoped>
+.edit-fix-point {
+  position: absolute;
+  left: 0;
+  top: 0;
+  bottom: 0;
+  overflow-y: auto;
+  z-index: 2;
+  background-color: #161a1a;
+  width: 240px;
+  padding: 10px;
+
+  .header {
+    margin-bottom: 21px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    h3 {
+      font-size: 16px;
+      color: #fff;
+    }
+  }
+
+  .select {
+    span,
+    p {
+      color: #fff;
+    }
+    p {
+      padding: 14px 6px;
+      font-size: 14px;
+      position: relative;
+
+      &.active {
+        background: var(--colors-primary-base);
+        margin: 0 -10px;
+        padding: 14px 16px;
+      }
+    }
+    span {
+      display: inline-block;
+      font-size: 12px;
+      padding: 24px 6px 6px;
+    }
+  }
+}
+</style>

+ 24 - 24
src/graphic/Geometry/Text.js

@@ -1,16 +1,16 @@
-import VectorType from '../enum/VectorType.js';
-import Geometry from './Geometry.js';
-import { mathUtil } from '../Util/MathUtil.js';
-import { coordinate } from '../Coordinate.js';
-import Constant from '../Constant.js';
-import Style from '@/graphic/CanvasStyle/index.js';
+import VectorType from "../enum/VectorType.js";
+import Geometry from "./Geometry.js";
+import { mathUtil } from "../Util/MathUtil.js";
+import { coordinate } from "../Coordinate.js";
+import Constant from "../Constant.js";
+import Style from "@/graphic/CanvasStyle/index.js";
 
 //不靠墙
 export default class Text extends Geometry {
   constructor(center, vectorId) {
     super();
     this.center = center;
-    this.value = '文本';
+    this.value = "文本";
     this.angle = 0;
     this.color = Style.Text.fillStyle;
     this.fontSize = Style.Text.fontSize;
@@ -20,37 +20,37 @@ export default class Text extends Geometry {
   }
 
   getBound(ctx) {
-    ctx.save()
-    ctx.font = `${
-      this.fontSize * coordinate.ratio
-    }px Microsoft YaHei`;
+    ctx.save();
+    ctx.font = `${this.fontSize * coordinate.ratio}px Microsoft YaHei`;
     const text = ctx.measureText(this.value);
     const height = text.actualBoundingBoxAscent + text.actualBoundingBoxDescent;
     const info = { width: text.width, height };
     const screen = coordinate.getScreenXY(this.center);
     const center = {
-      y: screen.y + Style.Point.radius,
+      y: screen.y + Style.Point.radius + 4 * coordinate.ratio,
       x: screen.x,
-    }
-    const p1 =  {
+    };
+    const p1 = {
       x: center.x - info.width / 2,
-      y: center.y
-    }
+      y: center.y,
+    };
     const p2 = {
       x: center.x + info.width / 2,
-      y: center.y
-    }
+      y: center.y,
+    };
     const p3 = {
       x: center.x + info.width / 2,
-      y: center.y + info.height
-    }
+      y: center.y + info.height,
+    };
     const p4 = {
       x: center.x - info.width / 2,
-      y: center.y + info.height
-    }
-    ctx.restore()
+      y: center.y + info.height,
+    };
+    ctx.restore();
 
-    return [p1, p2, p3, p4].map(pos => coordinate.getXYFromScreenNotRatio(pos))
+    return [p1, p2, p3, p4].map((pos) =>
+      coordinate.getXYFromScreenNotRatio(pos)
+    );
   }
   getAngle() {
     return this.angle;

+ 48 - 20
src/graphic/Renderer/Draw.js

@@ -1144,35 +1144,63 @@ export default class Draw {
 
   // 文字
   drawText(vector) {
-    console.log(vector);
     this.context.save();
-    help.setVectorStyle(this.context, vector);
+    const [_, foo] = help.setVectorStyle(this.context, vector);
     this.context.fillStyle = vector.color;
+    this.context.textBaseline = "bottom";
     this.context.font = `${
       vector.fontSize * coordinate.ratio
     }px Microsoft YaHei`;
-    const bound = help.getTextCenter(this.context, vector.value);
-
-    // console.log(vector)
-    const screen = coordinate.getScreenXY(vector.center);
-    this.drawTextByInfo(
-      // vector.center,
-      coordinate.getXYFromScreenNotRatio({
-        // y: screen.y + (bound.height + Style.Point.radius),
-        y: screen.y + (bound.height + Style.Point.radius),
-        x: screen.x - bound.width / 2,
-      }),
-      vector.value,
-      -(vector.angle || 0),
-      false
-    );
+    const bound = vector
+      .getBound(this.context)
+      .map(coordinate.getScreenXY.bind(coordinate));
 
-    this.context.restore();
+    this.context.fillText(vector.value, bound[3].x, bound[3].y);
 
+    if (foo) {
+      this.context.beginPath();
+      const padding = 2 * coordinate.ratio;
+      this.context.moveTo(bound[0].x - padding, bound[0].y - padding);
+      this.context.lineTo(bound[1].x + padding, bound[1].y - padding);
+      this.context.lineTo(bound[2].x + padding, bound[2].y + padding);
+      this.context.lineTo(bound[3].x - padding, bound[3].y + padding);
+      this.context.strokeStyle = "rgba(255, 153, 0, 1)";
+      this.context.fillStyle = "rgba(255, 153, 0, 0.30)";
+      this.context.lineWidth = 2 * coordinate.ratio;
+      this.context.setLineDash([6 * coordinate.ratio, 2 * coordinate.ratio]);
+      this.context.closePath();
+      this.context.stroke();
+      this.context.fill();
+    }
+    this.context.restore();
     vector.displayPoint &&
-      this.drawPoint({ ...vector.center, color: vector.color }, true);
+      this.drawPoint(
+        { ...vector.center, color: vector.color, fillColor: vector.color },
+        true
+      );
+
+    // const bound = help.getTextCenter(this.context, vector.value);
+
+    // // console.log(vector)
+    // const screen = coordinate.getScreenXY(vector.center);
+    // this.drawTextByInfo(
+    //   // vector.center,
+    //   coordinate.getXYFromScreenNotRatio({
+    //     // y: screen.y + (bound.height + Style.Point.radius),
+    //     y: screen.y + (bound.height + Style.Point.radius),
+    //     x: screen.x - bound.width / 2,
+    //   }),
+    //   vector.value,
+    //   -(vector.angle || 0),
+    //   false
+    // );
+
+    // this.context.restore();
+
+    // vector.displayPoint &&
+    //   this.drawPoint({ ...vector.center, color: vector.color }, true);
 
-    // vector.getBound(this.context).forEach(this.drawPoint.bind(this))
+    // vector.getBound(this.context).forEach(this.drawPoint.bind(this));
   }
 
   drawSVG(vector) {

+ 1 - 0
src/views/graphic/geos/text.vue

@@ -45,6 +45,7 @@ import { debounce } from "@/utils";
 import GeoActions from "@/graphic/enum/GeoActions";
 import Color from "@/components/color/index.vue";
 import VectorCategory from "@/graphic/enum/VectorCategory";
+import EditFixPoint from "@/components/edit-fix-point/index.vue";
 
 const props = defineProps<{ geo: FocusVector }>();
 const inputTextRef = ref();

+ 2 - 87
src/views/scene/covers/fixPoints.vue

@@ -23,30 +23,7 @@
     />
   </div>
 
-  <div class="edit-fix-point" v-if="edit" ref="dom" @touchstart.stop>
-    <div class="header">
-      <h3>添加名称</h3>
-      <ui-icon type="close" ctrl @click="edit = null" />
-    </div>
-    <ui-input
-      type="text"
-      v-model="edit.text"
-      width="100%"
-      maxlength="20"
-      class="search-fix"
-    />
-    <div class="select">
-      <span>常用名称</span>
-      <p
-        v-for="option in options"
-        :key="option"
-        :class="{ active: option === edit.text }"
-        @click="edit.text = option"
-      >
-        {{ option }}
-      </p>
-    </div>
-  </div>
+  <EditFixPoint v-if="edit" @quit="edit = null" v-model:text="edit.text" ref="dom" />
 </template>
 
 <script setup lang="ts">
@@ -54,25 +31,10 @@ import { fixPoints, FixPoint } from "@/store/fixPoint";
 import FixPointPanel from "./fixPoint.vue";
 import { ref, watch, watchEffect } from "vue";
 import { customMap } from "@/hook";
-import UiIcon from "@/components/base/components/icon/index.vue";
-import UiInput from "@/components/base/components/input/index.vue";
 import ActionMenus from "@/components/group-button/index.vue";
+import EditFixPoint from "@/components/edit-fix-point/index.vue";
 
 const edit = ref<FixPoint>();
-const options = [
-  "轿车 / 平面",
-  "客车 / 平面",
-  "客车 / 侧面",
-  "货车 / 平面",
-  "牵引车 / 平面",
-  "正三轮机动车 / 平面",
-  "自行车",
-  "伤体",
-  "牲畜",
-  "散落物",
-  "岗台",
-  "桥",
-];
 const activeActionMenus = [
   {
     key: "edit",
@@ -107,7 +69,6 @@ const menu = ref<HTMLDivElement>();
 watchEffect((onCleanup) => {
   if (edit.value && dom.value) {
     const handler = (ev) => {
-      console.log(ev.target);
       if (!dom.value.contains(ev.target) && !menu.value.contains(ev.target)) {
         edit.value = null;
       }
@@ -123,52 +84,6 @@ watchEffect((onCleanup) => {
 </script>
 
 <style lang="scss" scoped>
-.edit-fix-point {
-  position: absolute;
-  left: 0;
-  top: 0;
-  bottom: 0;
-  overflow-y: auto;
-  z-index: 2;
-  background-color: #161a1a;
-  width: 240px;
-  padding: 10px;
-
-  .header {
-    margin-bottom: 21px;
-    display: flex;
-    justify-content: space-between;
-    align-items: center;
-    h3 {
-      font-size: 16px;
-      color: #fff;
-    }
-  }
-
-  .select {
-    span,
-    p {
-      color: #fff;
-    }
-    p {
-      padding: 14px 6px;
-      font-size: 14px;
-      position: relative;
-
-      &.active {
-        background: var(--colors-primary-base);
-        margin: 0 -10px;
-        padding: 14px 16px;
-      }
-    }
-    span {
-      display: inline-block;
-      font-size: 12px;
-      padding: 24px 6px 6px;
-    }
-  }
-}
-
 .action-menus {
   position: absolute;
   bottom: var(--boundMargin);