Explorar o código

定制系统主色调

bill %!s(int64=2) %!d(string=hai) anos
pai
achega
f9e480cd82

+ 4 - 4
src/components/base/assets/scss/_base-vars.scss

@@ -1,9 +1,9 @@
 
 :root {
   --colors-primary-fill: 255, 255, 255;
-  --colors-primary-base-fill: 0, 200, 175;
+  --colors-primary-base-fill: 50, 144, 255;
   --colors-primary-base: rgb(var(--colors-primary-base-fill));
-  --colors-primary-hover: #008B7A;
+  --colors-primary-hover: rgba(var(--colors-primary-base-fill), 0.8);
   --colors-primary-click: #005046;
 
   --colors-color: #999;
@@ -39,14 +39,14 @@
   --editor-head-filter: blur(0px);
   --editor-head-height: 50px;
   
-  --editor-head-back: rgba(20, 20, 20, 0.86);
+  --editor-head-back: #252828;
 
   --editor-menu-filter: var(--editor-head-filter);
   --editor-menu-width: 80px;
   --editor-menu-left: 0px;
   --editor-menu-right: 0px;
   --editer-menu-fill: 27, 27, 28;
-  --editor-menu-back: rgba(var(--editer-menu-fill), 0.8);
+  --editor-menu-back: #161A1A;
   --editor-menu-active-back: rgba(var(--colors-primary-fill), 0.06);
   --editor-men-color: rgba(255,255,255,0.7);
 

+ 1 - 1
src/components/base/assets/scss/components/_button.scss

@@ -70,7 +70,7 @@
     opacity: 1;
 
     &:hover {
-        background-color: #4DD8C7 !important;
+        background-color: var(--colors-primary-hover) !important;
     }
     &:active {
         background-color: var(--colors-primary-hover) !important;

+ 50 - 40
src/graphic/CanvasStyle/default.js

@@ -1,34 +1,40 @@
 const Road = {
-  strokeStyle: "rgba(255,0,0,0.5)",
-  lineWidth: 4,
-  error: {
-    strokeStyle: "rgba(255,0,0,0.5)",
-    fillStyle: "rgba(255,0,0,0.8)",
-  },
-};
+  strokeStyle: "#939393",
+  lineWidth: 8,
+  realLineWidth: 2,
+  // error: {
+  //   strokeStyle: "rgba(255,0,0,0.5)",
+  //   fillStyle: "rgba(255,0,0,0.8)",
+  // },
+}
 
 const RoadEdge = {
   ...Road,
   lineWidth: 1,
-  // globalAlpha: 0.3
-};
+  strokeStyle: "#000",
+}
 
 const Lane = {
   ...RoadEdge,
-  dash: [15, 15],
-};
+  lineWidth: 1,
+  strokeStyle: "#000",
+  dash: [8, 8]
+}
 
-const CurveRoad = { ...Road };
+const CurveRoad = {
+  ...Road,
+}
 
 const CurveRoadEdge = {
   ...CurveRoad,
-  ...RoadEdge,
-};
+  ...RoadEdge
+}
 
 const CurveLan = {
-  ...Lane,
-  ...CurveRoadEdge,
-};
+  ...CurveRoad,
+  ...Lane
+}
+
 
 const Tag = {
   strokeStyle: "rgb(255,255,255,1)",
@@ -36,7 +42,7 @@ const Tag = {
   strokeStyle_adding: "rgba(243, 255, 0, 0.8)",
   fillStyle_adding: "rgba(243, 255, 0, 0.8)",
   lineWidth: 1,
-};
+}
 
 const CanvasFont = {
   font: "14px Microsoft YaHei",
@@ -46,69 +52,72 @@ const CanvasFont = {
   textBaseline: "middle",
   miterLimit: 10,
   direction: "ltr",
-};
+}
 
 const Point = {
-  strokeStyle: "green",
-  fillStyle: "rgb(0, 200, 175)",
+  strokeStyle: "#3290FF",
+  fillStyle: "#fff",
   radius: 4,
-};
+  lineWidth: 4,
+}
 
 const RoadPoint = {
-  ...Point,
-};
+  ...Point
+}
 
 const CurvePoint = {
-  ...Point,
-};
+  ...Point
+}
 
 const ControlPoint = {
   ...Point,
-  radius: 8,
-};
+  radius: 8
+}
 
 const Text = {
   ...Tag,
   ...CanvasFont,
   font: "12px Microsoft YaHei",
-};
+  fillStyle: "rgba(0,0,0,0.7)",
+  strokeStyle: "rgba(0,0,0,0.7)",
+}
 
 const Measure = {
   txt: "rgba(255,255,255,1)", //画墙/选墙的时候 测量值的颜色
   strokeStyle: "rgba(255,255,255,1)",
   lineWidth: 1,
-};
+}
 
 const Element = {
   AddingPoint: {
     radius: 4,
-    fillStyle: "yellow",
-    strokeStyle: "green",
+      fillStyle: "yellow",
+      strokeStyle: "green",
   },
   NewRoad: {
     lineWidth: 4,
-    strokeStyle: "rgba(100,100,100,0.3)",
-    errorStrokeStyle: "rgb(250,63,72,0.3)",
+      strokeStyle: "rgba(100,100,100,0.3)",
+      errorStrokeStyle: "rgb(250,63,72,0.3)",
   },
   CheckLinesX: {
     lineWidth: 2,
-    strokeStyle: "#CED806",
+      strokeStyle: "#CED806",
   },
   CheckLinesY: {
     lineWidth: 2,
-    strokeStyle: "#CED806",
+      strokeStyle: "#CED806",
   },
   VCheckLinesX: {
     lineWidth: 2,
-    strokeStyle: "#CED806",
+      strokeStyle: "#CED806",
     //strokeStyle: 'rgba(100,149,237,0.5)',
   },
   VCheckLinesY: {
     lineWidth: 2,
-    strokeStyle: "#CED806",
+      strokeStyle: "#CED806",
     //strokeStyle: 'rgba(100,149,237,0.5)',
   },
-};
+}
 
 export default {
   Road,
@@ -126,4 +135,5 @@ export default {
   Measure,
   Element,
   RoadPoint,
-};
+  bgColor: "#fff"
+}

+ 26 - 23
src/graphic/CanvasStyle/focus.js

@@ -1,51 +1,54 @@
-import def from "./default.js";
+import def from './default.js'
 
 const Road = {
   ...def.Road,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  realLineWidth: 4,
+  strokeStyle: "#3290FF",
+}
 
 const CurveRoad = {
   ...def.CurveRoad,
-  ...Road,
-};
+  ...Road
+}
 
 const Tag = {
   ...def.Tag,
   strokeStyle: "#00C8AF",
   fillStyle: "#00C8AF",
-};
+}
 
 const Point = {
   ...def.Point,
-  lineWidth: 2,
-  fillStyle: "rgba(245, 255, 0, 1)",
-  strokeStyle: "rgba(245, 255, 255, 1)",
-};
+  fillStyle: "#3290FF",
+}
 
 const RoadPoint = {
   ...Point,
-};
+}
 
 const CurvePoint = {
   ...def.CurvePoint,
-  ...Point,
-};
+  ...Point
+}
 
 const ControlPoint = {
   ...def.ControlPoint,
   ...Point,
-};
+}
+
 
-const Edg = {
+const RoadEdge = {
   ...def.RoadEdge,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  lineWidth: 2,
+  strokeStyle: "#3290FF",
+}
 
 const CurveRoadEdge = {
-  ...def.CurveRoadEdge,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  ...def.CurveEdge,
+  lineWidth: 2,
+  strokeStyle: "#3290FF",
+}
+
 
 export default {
   Road,
@@ -55,6 +58,6 @@ export default {
   CurvePoint,
   ControlPoint,
   CurveRoad,
-  Edg,
-  CurveRoadEdge,
-};
+  RoadEdge,
+  CurveRoadEdge
+}

+ 22 - 21
src/graphic/CanvasStyle/select.js

@@ -1,51 +1,52 @@
-import def from "./default.js";
+import def from './default.js'
 
 const Road = {
   ...def.Road,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  realLineWidth: 4,
+  strokeStyle: "#3290FF",
+}
 
 const CurveRoad = {
   ...def.CurveRoad,
-  ...Road,
-};
+  ...Road
+}
 
 const Tag = {
   ...def.Tag,
   strokeStyle: "#00C8AF",
   fillStyle: "#00C8AF",
-};
+}
 
 const RoadEdge = {
   ...def.RoadEdge,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  lineWidth: 2,
+  strokeStyle: "#3290FF",
+}
 
 const CurveRoadEdge = {
   ...def.CurveRoadEdge,
-  strokeStyle: "rgba(243, 255, 0, 1)",
-};
+  lineWidth: 2,
+  strokeStyle: "#3290FF",
+}
 
 const Point = {
   ...def.Point,
-  lineWidth: 2,
-  fillStyle: "rgba(245, 255, 0, 1)",
-  strokeStyle: "rgba(245, 255, 255, 1)",
-};
+  fillStyle: "#3290FF",
+}
 
 const RoadPoint = {
-  ...Point,
-};
+  ...Point
+}
 
 const CurvePoint = {
   ...def.CurvePoint,
-  ...Point,
-};
+  ...Point
+}
 
 const ControlPoint = {
   ...def.ControlPoint,
   ...Point,
-};
+}
 
 export default {
   Road,
@@ -56,5 +57,5 @@ export default {
   ControlPoint,
   CurveRoad,
   RoadEdge,
-  CurveRoadEdge,
-};
+  CurveRoadEdge
+}

+ 37 - 27
src/graphic/Renderer/Draw.js

@@ -40,6 +40,7 @@ const help = {
     for (const style in styles) {
       ctx[style] = styles[style];
     }
+    return styles;
   },
   transformCoves(lines) {
     return lines.map((line) =>
@@ -148,13 +149,19 @@ export default class Draw {
       const ctx = this.context;
       const startScreen = coordinate.getScreenXY(startReal);
       const endScreen = coordinate.getScreenXY(endReal);
+      const draw = () => {
+        ctx.beginPath();
+        ctx.moveTo(startScreen.x, startScreen.y);
+        ctx.lineTo(endScreen.x, endScreen.y);
+        ctx.stroke();
+      }
 
       ctx.save();
-      help.setVectorStyle(ctx, vector);
-      ctx.beginPath();
-      ctx.moveTo(startScreen.x, startScreen.y);
-      ctx.lineTo(endScreen.x, endScreen.y);
-      ctx.stroke();
+      const vectorStyle = help.setVectorStyle(ctx, vector);
+      draw()
+      ctx.strokeStyle = Style.bgColor
+      ctx.lineWidth = vectorStyle.lineWidth - vectorStyle.realLineWidth
+      draw()
       ctx.restore();
     }
 
@@ -164,7 +171,7 @@ export default class Draw {
         vector.vectorId
       );
     }
-    this.drawEdge(vector, isTemp);
+    this.drawRoadEdge(vector, isTemp);
     vector.leftLanes && vector.leftLanes.forEach(this.drawLan.bind(this));
     vector.rightLanes && vector.rightLanes.forEach(this.drawLan.bind(this));
   }
@@ -188,14 +195,14 @@ export default class Draw {
     }
   }
 
-  drawEdge(vector, isTemp) {
+  drawRoadEdge(vector, isTemp) {
     //判断是否与road方向一致。角度足够小,路足够宽,有可能向量方向不一致
     const start = isTemp
       ? vector.start
       : dataService.getRoadPoint(vector.startId);
     const end = isTemp ? vector.end : dataService.getRoadPoint(vector.endId);
 
-    const drawEdgeChild = (edgeVector) => {
+    const drawRoadEdgeChild = (edgeVector) => {
       const flag = mathUtil.isSameDirForVector(
         start,
         end,
@@ -230,9 +237,9 @@ export default class Draw {
     ctx.save();
     isTemp && (ctx.globalAlpha = 0.3);
     help.setVectorStyle(ctx, leftEdge);
-    drawEdgeChild(leftEdge);
+    drawRoadEdgeChild(leftEdge);
     help.setVectorStyle(ctx, rightEdge);
-    drawEdgeChild(rightEdge);
+    drawRoadEdgeChild(rightEdge);
     ctx.restore();
 
     if (import.meta.env.DEV) {
@@ -245,14 +252,10 @@ export default class Draw {
 
   drawControlPoint(vector) {
     const start = coordinate.getScreenXY(
-      dataService
-        .getRoadEdge(vector.edgeInfo1.id)
-        .getPosition(vector.edgeInfo1.dir)
+      dataService.getRoadEdge(vector.edgeInfo1.id).getPosition(vector.edgeInfo1.dir)
     );
     const end = coordinate.getScreenXY(
-      dataService
-        .getRoadEdge(vector.edgeInfo2.id)
-        .getPosition(vector.edgeInfo2.dir)
+      dataService.getRoadEdge(vector.edgeInfo2.id).getPosition(vector.edgeInfo2.dir)
     );
     const pt2 = this.twoOrderBezier(
       0.5,
@@ -265,6 +268,7 @@ export default class Draw {
     const ctx = this.context;
     ctx.save();
     help.setVectorStyle(ctx, null, "RoadEdge");
+
     //曲线
     ctx.moveTo(start.x, start.y);
     ctx.quadraticCurveTo(pt.x, pt.y, end.x, end.y);
@@ -273,7 +277,6 @@ export default class Draw {
 
     ctx.save();
     ctx.beginPath();
-    console.log(vector);
     help.setVectorStyle(ctx, vector);
 
     ctx.arc(
@@ -292,14 +295,18 @@ export default class Draw {
   drawCurveRoad(vector) {
     const [coves] = help.transformCoves([vector.curves]);
     const ctx = this.context;
+
     ctx.save();
+    const vectorStyle = help.setVectorStyle(ctx, vector);
+    help.drawCoves(ctx, coves);
 
-    help.setVectorStyle(ctx, vector);
+    ctx.lineWidth = vectorStyle.lineWidth - vectorStyle.realLineWidth
+    ctx.strokeStyle = Style.bgColor
     help.drawCoves(ctx, coves);
     ctx.restore();
 
-    this.drawCurveEdge(dataService.getCurveRoadEdge(vector.rightEdgeId));
-    this.drawCurveEdge(dataService.getCurveRoadEdge(vector.leftEdgeId));
+    this.drawCurveRoadEdge(dataService.getCurveRoadEdge(vector.rightEdgeId));
+    this.drawCurveRoadEdge(dataService.getCurveRoadEdge(vector.leftEdgeId));
     vector.leftLanesCurves &&
       vector.leftLanesCurves.forEach(this.drawCurveLan.bind(this));
     vector.rightLanesCurves &&
@@ -310,13 +317,13 @@ export default class Draw {
     }
   }
 
-  drawCurveEdge(vector, isTemp) {
+  drawCurveRoadEdge(vector, isTemp) {
     const [coves] = help.transformCoves([vector.curves]);
     const ctx = this.context;
     ctx.save();
     help.setVectorStyle(ctx, vector);
     help.drawCoves(ctx, coves);
-    this.context.restore();
+    ctx.restore();
 
     if (import.meta.env.DEV) {
       vector.points.forEach(this.drawPoint.bind(this));
@@ -327,10 +334,11 @@ export default class Draw {
     const [coves] = help.transformCoves([lines]);
     const ctx = this.context;
     ctx.save();
+
     help.setVectorStyle(ctx, null, "CurveLan");
     ctx.setLineDash(Style.Lane.dash);
     help.drawCoves(ctx, coves);
-    this.context.restore();
+    ctx.restore();
 
     if (import.meta.env.DEV) {
       lines.map((line) => {
@@ -341,12 +349,15 @@ export default class Draw {
   }
 
   drawRoadPoint(vector) {
-    this.drawPoint(vector);
+    this.drawPoint(vector)
   }
   drawPoint(vector) {
     const pt = coordinate.getScreenXY({ x: vector.x, y: vector.y });
-
     const ctx = this.context;
+    const draw = () => {
+
+    }
+
     help.setVectorStyle(ctx, vector, vector.geoType || "Point");
     ctx.beginPath();
     ctx.arc(
@@ -409,7 +420,7 @@ export default class Draw {
   drawText(position, txt, angle) {
     const ctx = this.context;
     ctx.save();
-    help.setVectorStyle(null, "Text");
+    help.setVectorStyle(ctx, null,"Text");
 
     const pt = coordinate.getScreenXY(position);
     if (angle) {
@@ -509,7 +520,6 @@ export default class Draw {
       //根据文字的长度,更新标注范围
       let title = geometry.title;
       if (!hide && (title == null || title.trim() == "")) {
-        console.log(dataService.$app.config);
         // title = '请输入名称'
         title = dataService.$app.config.i18n("cad.input");
       }

+ 152 - 3
src/graphic/enum/UIEvents.js

@@ -1,12 +1,161 @@
 const UIEvents = {
-  Road: "road",
-  CurveRoad: "curveRoad",
+  // 画线
   Line: "line",
-  Tag: "tag", //这个是标注,暂时这样
+  // 图例
   Img: "backgroundImage",
+  // 测量
   MeasureLine: "measure",
+  // 文字
+  Tag: "tag", //这个是标注,暂时这样
+  // 放大镜
+  magnifier: "magnifier",
+
+  // ----------道路------------
+  // 单向单车道直路
+  OneEdgeOneLanRoad: "OneEdgeOneLanRoad",
+  // 单向双车道直路
+  OneEdgeTwoLanRoad: "OneEdgeTwoLanRoad",
+  // 单向三车道直路
+  OneEdgeThreeLanRoad: "OneEdgeTwoLanRoad",
+
+  // 双向单车道直路
+  TwoEdgeOneLanRoad: "TwoEdgeOneLanRoad",
+  // 双向双车道直路
+  TwoEdgeTwoLanRoad: "TwoEdgeTwoLanRoad",
+  // 双向三车道直路
+  TwoEdgeThreeLanRoad: "TwoEdgeThreeLanRoad",
+
+  // ----------道路结构-----------
+  // 支路
+  BranchRoad: "BranchRoad",
+  // 窄路
+  NarrowRoad: "NarrowRoad",
+  // 路肩
+  ShoulderRoad: "ShoulderRoad",
+  // 斑马线
+  ZebraCrossing: "ZebraCrossing",
+  // 桥
+  Bridge: "Bridge",
+  // 隧道
+  Tunnel: "Tunnel",
+  // 人行道
+  Sidewalk: "Sidewalk",
+  // 施工路段
+  ConstructionSection: "ConstructionSection",
+  // 下坡
+  Downhill: "Downhill",
+  // 上坡
+  Uphill: "Uphill",
+  // 路边水沟
+  RoadsideGutter: "RoadsideGutter",
+  // 道路与铁
+  RoadsAndRails: "RoadsAndRails",
+  // 消火栓井
+  FireHydrantWell: "FireHydrantWell",
+  // 雨水口
+  Gullies: "Gullies",
+  // 路面凹坑
+  RoadPotholes: "RoadPotholes",
+  // 路面凸出
+  ProtrudingRoad: "ProtrudingRoad",
+  // 路面积水
+  WaterOnTheRoad: "WaterOnTheRoad",
+
+  // ----------道路模板-----------
+  // s型弯路
+  SBend: "SBend",
+  // 丁字路口
+  TJunction: "TJunction",
+  // 五岔路口
+  FiveForks: "FiveForks",
+  // 出口匝道
+  ExitRamp: "ExitRamp",
+  // 十字路口
+  Crossroads: "Crossroads",
+  // 国道(路肩)
+  NationalHighwayShoulder: "NationalHighwayShoulder",
+  // 室内路段
+  IndoorSection: "IndoorSection",
+  // 弯道
+  Bend: "Bend",
+  // 急转弯道
+  SharpCurve: "SharpCurve",
+  // 六岔路口
+  SixForkIntersection: "SixForkIntersection",
+  // 宽变窄路段
+  WideNarrowRoad: "WideNarrowRoad",
+  // 直角弯道
+  Corner: "Corner",
+  // 进口砸到
+  ImportSmashedRoad: "ImportSmashedRoad",
+  // 高速收费站
+  HighSpeedTollBooth: "HighSpeedTollBooth",
+  // 高速港湾
+  HighSpeedHarbor: "HighSpeedHarbor",
+  // 高速路段
+  HighwaySection: "HighwaySection",
+
+
+  // ------------控制方法----------
+  // 回退
+  GoBack: "GoBack",
+  // 前进
+  GoAhead: "GoAhead",
+  // 清除
+  Clear: "clear",
+  // 底图开
+  BasemapOpen: "BasemapOpen",
+  // 底图关
+  BasemapClose: "BasemapClose",
+
+
+  // ------------选中组件时的UI控制-----------
+  // 加控制点
+  AddControlPoint: "AddControlPoint",
+  // 减控制点
+  MinusControlPoint: "MinusControlPoint",
+  // 复制
+  Copy: "copy",
+  // 删除
+  Delete: "delete",
+  // 单实线
+  SingleSolidLine: "SingleSolidLine",
+  // 单虚线
+  SingleDashedLine: "SingleDashedLine",
+  // 双实线
+  DoubleSolidLine: "DoubleSolidLine",
+  // 双虚线
+  DoubleDashedLine: "DoubleDashedLine",
+  // 折线
+  BrokenLine: "BrokenLine",
+  // 点画线
+  PointDrawLine: "PointDrawLine",
+  // 绿化带
+  Greenbelt: "Greenbelt",
+  // 加粗
+  Bold: "Bold",
+  // 变细
+  Thinning: "Thinning",
+  // 加支路
+  AddBranchRoad: "AddBranchRoad",
+  // 加窄路
+  AddNarrowRoad: "AddNarrowRoad",
+  // 加车道
+  AddLane: "AddLane",
+  // 减车道
+  DelLane: "DelLane",
+
+
+  Road: "road",
+  CurveRoad: "curveRoad",
+
+
 };
 
+
+
+
+
 // export const Furnitures = {
 //   TV: UIEvents.TV, //电视
 //   CombinationSofa: UIEvents.CombinationSofa, //组合沙发

+ 3 - 3
src/views/graphic/childMenus.vue

@@ -20,13 +20,13 @@
 </template>
 
 <script setup lang="ts">
-import { MenusRaw, findMainMenuByExtend } from "@/views/graphic/menus";
+import { MenusRaw, findMainMenuByAttr } from "@/views/graphic/menus";
 import UiIcon from "@/components/base/components/icon/index.vue";
 import { uiType } from '@/hook/useGraphic'
 import {computed} from "vue";
 
 const props = defineProps<{ menus: MenusRaw }>();
-const title = computed(() => findMainMenuByExtend(props.menus)?.text)
+const title = computed(() => findMainMenuByAttr(props.menus)?.text)
 
 defineEmits<{ (e: "quit") }>();
 
@@ -58,7 +58,7 @@ defineEmits<{ (e: "quit") }>();
 
   &:hover,
   &.active {
-    color: var(--color-main-hover);
+    color: var(--colors-primary-base);
   }
 
   &.active {

+ 16 - 8
src/views/graphic/header.vue

@@ -6,13 +6,10 @@
     </div>
 
     <div class="actions">
-      <ui-icon
-        class="action"
-        v-for="menu in menus"
-        :key="menu.key"
-        type="close"
-        ctrl
-      />
+      <div v-for="menu in menus" :key="menu.key" class="action fun-ctrl">
+        <ui-icon type="close" />
+        <p>{{ menu.text }}</p>
+      </div>
     </div>
 
     <div class="table">
@@ -42,9 +39,20 @@ const menus = generateByMenus(
   justify-content: center;
 }
 
-.actions .action {
+.actions {
+  display: flex;
+}
+.action {
   font-size: 20px;
   margin: 0 15px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  p {
+    font-size: 12px;
+    text-align: center;
+  }
 }
 
 .table,

+ 20 - 23
src/views/graphic/index.vue

@@ -13,6 +13,7 @@
         @click="customMap.sysView = isFull ? 'auto' : 'full'"
       />
     </GraphicAction>
+    <VectorMenus :menus="focusMenus" v-if="focusMenus" />
   </MainPanel>
 </template>
 
@@ -23,34 +24,30 @@ import Header from './header.vue'
 import Container from './container.vue'
 import GraphicAction from '@/components/graphic-action/index.vue'
 import UiIcon from "@/components/base/components/icon/index.vue";
+import VectorMenus from './vectorMenus.vue'
 
-import { computed, ref } from "vue";
-import { uiType, currentVector } from "@/hook/useGraphic";
+import {computed, watch, watchEffect} from "vue";
 import { customMap } from '@/hook'
-import { generateByMenus, findMainMenuByExtend, MenusRaw, UITypeExtend } from './menus'
+import { generateMixMenus, UITypeExtend, focusMenuRaw } from './menus'
+import { currentVector } from "@/hook/useGraphic";
 
-const isFull = computed(() => customMap.sysView === 'full' )
-const extendMenus = ref<MenusRaw>();
-const menus = generateByMenus((mainMenuRaw) => ({
-  title: mainMenuRaw.text,
-  name: mainMenuRaw.key,
-  isRoute: false,
-  icon: 'menu',
-  bottom:  mainMenuRaw.key === UITypeExtend.photo,
-  onClick: () => {
-    if (mainMenuRaw.extend) {
-      extendMenus.value = mainMenuRaw.extend
-    } else {
-      uiType.change(mainMenuRaw.key as any)
-    }
-  }
-}))
-const activeMenuKey = computed(() =>
-  extendMenus.value
-    ? findMainMenuByExtend(extendMenus.value)?.key
-    : uiType.current
+const {
+  child: extendMenus,
+  menus,
+  activeMenuKey
+} = generateMixMenus(
+  "extend",
+  (mainMenuRaw) => ({
+    title: mainMenuRaw.text,
+    name: mainMenuRaw.key,
+    isRoute: false,
+    icon: 'menu',
+    bottom:  mainMenuRaw.key === UITypeExtend.photo
+  }),
 )
 
+const focusMenus = computed(() => focusMenuRaw[currentVector.value?.type])
+const isFull = computed(() => customMap.sysView === 'full' )
 </script>
 
 <style lang="scss" scoped>

+ 148 - 55
src/views/graphic/menus.ts

@@ -1,11 +1,16 @@
-import {UIType} from "@/hook/useGraphic";
-import { toRaw } from 'vue'
+import {uiType, UIType, VectorType} from "@/hook/useGraphic";
+import {computed, Ref, ref, toRaw} from 'vue'
 
 export const UITypeExtend = {
   structure: "structure",
   template: "template",
+  road: "road",
   photo: "photo",
-  setup: "setup"
+  setup: "setup",
+  lineType: "lineType",
+  width: "width",
+  lock: "lock",
+  basemap: "Basemap"
 }
 
 export type MenuRaw = {
@@ -18,83 +23,127 @@ export type MenusRaw = Array<MenuRaw>
 
 
 export const structureMenusRaw = [
-  { key: UIType.CurveRoad, text: "支路" },
-  { key: UIType.CurveRoad, text: "窄路" },
-  { key: UIType.CurveRoad, text: "路肩" },
-  { key: UIType.CurveRoad, text: "斑马线" },
-  { key: UIType.CurveRoad, text: "桥" },
-  { key: UIType.CurveRoad, text: "隧道" },
-  { key: UIType.CurveRoad, text: "人行道" },
-  { key: UIType.CurveRoad, text: "施工路段" },
-  { key: UIType.CurveRoad, text: "下坡" },
-  { key: UIType.CurveRoad, text: "上坡" },
-  { key: UIType.CurveRoad, text: "路边水沟" },
-  { key: UIType.CurveRoad, text: "道路与铁..." },
-  { key: UIType.CurveRoad, text: "消火栓井" },
-  { key: UIType.CurveRoad, text: "雨水口" },
-  { key: UIType.CurveRoad, text: "路面凹坑" },
-  { key: UIType.CurveRoad, text: "路面凸出..." },
-  { key: UIType.CurveRoad, text: "路面积水" },
+  { key: UIType.BranchRoad, text: "支路" },
+  { key: UIType.NarrowRoad, text: "窄路" },
+  { key: UIType.ShoulderRoad, text: "路肩" },
+  { key: UIType.ZebraCrossing, text: "斑马线" },
+  { key: UIType.Bridge, text: "桥" },
+  { key: UIType.Tunnel, text: "隧道" },
+  { key: UIType.Sidewalk, text: "人行道" },
+  { key: UIType.ConstructionSection, text: "施工路段" },
+  { key: UIType.Downhill, text: "下坡" },
+  { key: UIType.Uphill, text: "上坡" },
+  { key: UIType.RoadsideGutter, text: "路边水沟" },
+  { key: UIType.RoadsAndRails, text: "道路与铁..." },
+  { key: UIType.FireHydrantWell, text: "消火栓井" },
+  { key: UIType.Gullies, text: "雨水口" },
+  { key: UIType.RoadPotholes, text: "路面凹坑" },
+  { key: UIType.ProtrudingRoad, text: "路面凸出..." },
+  { key: UIType.WaterOnTheRoad, text: "路面积水" },
 ]
 
 export const templateMenusRaw = [
-  { key: UIType.CurveRoad, text: "s型弯路" },
-  { key: UIType.CurveRoad, text: "丁字路口" },
-  { key: UIType.CurveRoad, text: "五岔路口" },
-  { key: UIType.CurveRoad, text: "出口匝道" },
-  { key: UIType.CurveRoad, text: "十字路口" },
-  { key: UIType.CurveRoad, text: "国道(路肩)" },
-  { key: UIType.CurveRoad, text: "室内路段" },
-  { key: UIType.CurveRoad, text: "弯道" },
-  { key: UIType.CurveRoad, text: "急转弯道" },
-  { key: UIType.CurveRoad, text: "六岔路口" },
-  { key: UIType.CurveRoad, text: "宽变窄路段" },
-  { key: UIType.CurveRoad, text: "直角弯道" },
-  { key: UIType.CurveRoad, text: "进口砸到" },
-  { key: UIType.CurveRoad, text: "高速收费站" },
-  { key: UIType.CurveRoad, text: "高速港湾" },
-  { key: UIType.CurveRoad, text: "高速路段" }
+  { key: UIType.SBend, text: "s型弯路" },
+  { key: UIType.TJunction, text: "丁字路口" },
+  { key: UIType.FiveForks, text: "五岔路口" },
+  { key: UIType.ExitRamp, text: "出口匝道" },
+  { key: UIType.Crossroads, text: "十字路口" },
+  { key: UIType.NationalHighwayShoulder, text: "国道(路肩)" },
+  { key: UIType.IndoorSection, text: "室内路段" },
+  { key: UIType.Bend, text: "弯道" },
+  { key: UIType.SharpCurve, text: "急转弯道" },
+  { key: UIType.SixForkIntersection, text: "六岔路口" },
+  { key: UIType.WideNarrowRoad, text: "宽变窄路段" },
+  { key: UIType.Corner, text: "直角弯道" },
+  { key: UIType.ImportSmashedRoad, text: "进口砸到" },
+  { key: UIType.HighSpeedTollBooth, text: "高速收费站" },
+  { key: UIType.HighSpeedHarbor, text: "高速港湾" },
+  { key: UIType.HighwaySection, text: "高速路段" }
 ]
 
 export const mainMenusRaw: MenusRaw = [
+  { key: UIType.CurveRoad, text: "弯路" },
+  { key: UIType.Road, text: "直路" },
   { key: UIType.Line, text: "画线" },
   {
-    key: UIType.Road,
+    key: UITypeExtend.road,
     text: "道路",
     children: [
-      { key: UIType.Road, text: "画线" },
-      { key: UIType.Road, text: "画线" },
-      { key: UIType.Road, text: "画线" },
-      { key: UIType.Road, text: "画线" },
-      { key: UIType.Road, text: "画线" },
-      { key: UIType.Road, text: "画线" },
+      { key: UIType.OneEdgeOneLanRoad, text: "单向单车道直路" },
+      { key: UIType.OneEdgeTwoLanRoad, text: "单向双车道直路" },
+      { key: UIType.OneEdgeThreeLanRoad, text: "单向三车道直路" },
+      { key: UIType.TwoEdgeOneLanRoad, text: "双向单车道直路" },
+      { key: UIType.TwoEdgeTwoLanRoad, text: "双向双车道直路" },
+      { key: UIType.TwoEdgeThreeLanRoad, text: "双向三车道直路" },
       { key: UITypeExtend.structure, text: "道路结构", extend: structureMenusRaw },
       { key: UITypeExtend.template, text: "道路模板", extend: templateMenusRaw },
     ]
   },
-  { key: UIType.CurveRoad, text: "弯路" },
-  { key: UIType.CurveRoad, text: "图例" },
+  { key: UIType.Img, text: "图例" },
   { key: UIType.MeasureLine, text: "测量" },
   { key: UIType.Tag, text: "文字" },
-  { key: UIType.MeasureLine, text: "放大镜" },
+  { key: UIType.magnifier, text: "放大镜" },
   { key: UITypeExtend.photo, text: "照片库" },
   { key: UITypeExtend.setup, text: "设置" },
 ];
 
 export const headActionMenuRaw = [
-  { key: UIType.Road, text: "画线" },
-  { key: UIType.Road, text: "画线" },
-  { key: UIType.Road, text: "画线" },
-  { key: UIType.Road, text: "画线" },
-  { key: UIType.Road, text: "画线" }
+  { key: UIType.GoBack, text: "回退" },
+  { key: UIType.GoAhead, text: "前进" },
+  { key: UIType.Clear, text: "清除" },
+  { key: UITypeExtend.basemap, text: "底图开关" },
 ]
 
+export const focusMenuRaw : { [key in string]: MenusRaw } = {
+  [VectorType.RoadEdge]: [
+    {
+      key: UITypeExtend.lineType,
+      text: "单实线",
+      children: [
+        { key: UIType.SingleSolidLine, text: "单实线" },
+        { key: UIType.SingleDashedLine, text: "单虚线" },
+        { key: UIType.DoubleSolidLine, text: "双实线" },
+        { key: UIType.DoubleDashedLine, text: "双虚线" },
+        { key: UIType.BrokenLine, text: "折线" },
+        { key: UIType.PointDrawLine, text: "点画线" },
+        { key: UIType.Greenbelt, text: "绿化带 " },
+      ]
+    },
+    {
+      key: UITypeExtend.width,
+      text: "宽度",
+      children: [
+        { key: UIType.Bold, text: "粗" },
+        { key: UIType.Thinning, text: "细" },
+
+      ]
+    },
+    { key: UIType.AddControlPoint, text: "加控制点" },
+    { key: UIType.MinusControlPoint, text: "减控制点" },
+    { key: UIType.Copy, text: "复制" },
+    { key: UIType.Delete, text: "删除" }
+  ],
+  [VectorType.Road]: [
+    { key: UITypeExtend.lineType, text: "锁定", },
+    { key: UIType.AddBranchRoad, text: "加支路" },
+    { key: UIType.AddNarrowRoad, text: "加窄路" },
+    { key: UIType.AddLane, text: "加车道" },
+    { key: UIType.DelLane, text: "减车道" },
+    { key: UIType.AddControlPoint, text: "加控制点" },
+    { key: UIType.MinusControlPoint, text: "减控制点" },
+    { key: UIType.Copy, text: "复制" },
+    { key: UIType.Delete, text: "删除" }
+  ],
+}
+
+focusMenuRaw[VectorType.CurveRoadEdge] = focusMenuRaw[VectorType.RoadEdge]
+focusMenuRaw[VectorType.CurveRoad] = focusMenuRaw[VectorType.Road]
 
 
 export const isUITypeExtend = (key: string) =>
   Object.values(UITypeExtend).some(v => v === key)
 
-type GenerateResult<T extends {}> = Array<T & { children: GenerateResult<T> }>;
+type GenerateResult<T extends {}, E = {}> = Array<T & { children: GenerateResult<T> } & E>;
 export const generateByMenus = <T>(
   generateFn: (men: MenuRaw) => T,
   mainMenus: MenusRaw = mainMenusRaw
@@ -104,15 +153,59 @@ export const generateByMenus = <T>(
     children: mainMenu.children ? generateByMenus(generateFn, mainMenu.children) : []
   }))
 }
-export const findMainMenuByExtend = (extend: MenusRaw, mainMenus = mainMenusRaw) => {
+export const findMainMenuByAttr = (
+  value: MenusRaw,
+  attr = "extend",
+  mainMenus = mainMenusRaw
+) => {
   for (const mainMenu of mainMenus) {
-    if (toRaw(mainMenu.extend) === toRaw(extend)) {
+    if (toRaw(mainMenu[attr]) === toRaw(value)) {
       return mainMenu
     } else if (mainMenu.children) {
-      const childMainMenu = findMainMenuByExtend(extend, mainMenu.children)
+      const childMainMenu = findMainMenuByAttr(value, attr, mainMenu.children)
       if (childMainMenu) {
         return childMainMenu;
       }
     }
   }
+}
+
+export type GenerateMinMenusResult<T extends {}, K extends keyof MenuRaw> =  {
+  menus: GenerateResult<T, { onClick: () => void }>,
+  child: Ref<MenuRaw[K]>,
+  activeMenuKey: Ref<string>
+}
+export const generateMixMenus = <T extends {}, K extends keyof MenuRaw>(
+  childKey: K,
+  generateFn: (men: MenuRaw) => T,
+  mainMenus: MenusRaw = mainMenusRaw
+): GenerateMinMenusResult<T, K> => {
+  const child = ref();
+  const menus = generateByMenus((menu) => ({
+    ...generateFn(menu),
+    onClick: () => {
+      if (menu[childKey]) {
+        if (toRaw(menu[childKey]) !== toRaw(child.value)) {
+          child.value = menu[childKey]
+          console.log("变成为", child.value)
+          return;
+        }
+      } else {
+        uiType.change(menu.key as any)
+      }
+      child.value = null
+    }
+  }), mainMenus)
+
+  const activeMenuKey = computed(() =>
+    child.value
+      ? findMainMenuByAttr(child.value, childKey, mainMenus)?.key
+      : uiType.current
+  )
+
+  return {
+    child,
+    menus,
+    activeMenuKey
+  };
 }

+ 83 - 0
src/views/graphic/vectorMenus.vue

@@ -0,0 +1,83 @@
+<template>
+  <GraphicAction
+    class="menus"
+    :style="{transform: `translate(-50%, calc(-${level}00% - ${level * 9}px))`}"
+  >
+    <div
+      v-for="menu in store.menus"
+      :key="menu.key"
+      class="menu"
+      :class="{ active: store.activeMenuKey.value === menu.key }"
+      @click="menu.onClick()"
+    >
+      <ui-icon type="close" class="icon" />
+      <p>{{ menu.text }}</p>
+    </div>
+  </GraphicAction>
+
+  <ui-graphic-vector-menus.vue
+    v-if="store.child.value"
+    :menus="store.child.value"
+    :level="level + 1"
+  />
+</template>
+
+<script setup lang="ts">
+import GraphicAction from '@/components/graphic-action/index.vue'
+import UiIcon from "@/components/base/components/icon/index.vue";
+
+import { MenusRaw, generateMixMenus } from "@/views/graphic/menus";
+import {computed} from "vue";
+
+const props = withDefaults(
+  defineProps<{ menus: MenusRaw, level?: number }>(),
+  { level: 1 }
+)
+const store = computed(() => generateMixMenus(
+  "children",
+  m => m,
+  props.menus
+))
+</script>
+
+<style lang="scss" scoped>
+.menus {
+  left: 50%;
+  top: 100%;
+  margin-top: -9px;
+}
+
+.menu {
+  width: 56px;
+  display: flex;
+  flex-direction: column;
+  cursor: pointer;
+  margin-right: 16px;
+  height: 100%;
+  text-align: center;
+  transition: color .3s ease;
+
+  &.active,
+  &:hover {
+    color: var(--colors-primary-base);
+  }
+  &.active {
+    background: rgba(255,255,255,0.1);;
+  }
+
+  .icon {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 20px;
+    flex: 1;
+  }
+
+  p {
+    line-height: 17px;
+    font-size: 12px;
+  }
+}
+</style>
+
+<script lang="ts"> export default { name: 'ui-graphic-vector-menus.vue' } </script>