浏览代码

制作场景ui

bill 2 年之前
父节点
当前提交
7f03d27fa3

+ 2 - 0
src/assets/pc.scss

@@ -12,4 +12,6 @@
   --taggle-btn-width: 30px;
 
   --body-right-margin: 20px;
+
+  --boundMargin: 24px
 }

+ 36 - 0
src/components/button-pane/index.vue

@@ -0,0 +1,36 @@
+<template>
+  <div class="button-pane" :style="style">
+    <slot />
+  </div>
+</template>
+
+<script setup lang="ts">
+import {computed} from "vue";
+
+const props = withDefaults(
+  defineProps<{ dire?: 'row' | 'column', size?: number }>(),
+  { dire: 'row', size: 64 }
+);
+
+const style = computed(() => {
+  const isRow = props.dire === 'row';
+  const bound = isRow ? { height: `${64}px` } : { width: `${64}px` }
+
+  return {
+    padding: isRow ? `4px ${props.size / 2}px` : `${props.size / 2}px 4px`,
+    borderRadius: `${props.size / 2}px`,
+    ...bound,
+    flexDirection: props.dire
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.button-pane {
+  position: absolute;
+  z-index: 1;
+  background-color: var(--editor-menu-back);
+  display: flex;
+  align-items: center;
+}
+</style>

+ 0 - 18
src/components/graphic-action/index.vue

@@ -1,18 +0,0 @@
-<template>
-  <div class="graphic-action">
-    <slot />
-  </div>
-</template>
-
-<style lang="scss" scoped>
-.graphic-action {
-  position: absolute;
-  z-index: 1;
-  height: 64px;
-  border-radius: 32px;
-  background-color: var(--editor-menu-back);
-  padding: 4px 16px;
-  display: flex;
-  align-items: center;
-}
-</style>

+ 73 - 0
src/components/group-button/index.vue

@@ -0,0 +1,73 @@
+<template>
+  <ButtonPane class="menus" :size="size" :dire="dire">
+    <div
+      v-for="menu in menus"
+      :key="menu.key"
+      class="menu"
+      :style="menuStyle"
+      :class="{ active: activeKey === menu.key, dire }"
+      @click="menu.onClick && menu.onClick(menu)"
+    >
+      <ui-icon type="close" class="icon"/>
+      <p v-if="menu.text">{{ menu.text }}</p>
+    </div>
+  </ButtonPane>
+</template>
+
+<script setup lang="ts">
+import ButtonPane from '@/components/button-pane/index.vue'
+import UiIcon from "@/components/base/components/icon/index.vue";
+import {computed} from "vue";
+
+type Menu =  {
+  key: any,
+  text?: string,
+  icon?: string,
+  onClick?: (menu: Menu) => void
+}
+
+const props = withDefaults(
+  defineProps<{ menus: Menu[], activeKey?: any, dire?: 'row' | 'column', size?: number }>(),
+  {dire: 'row', size: 64}
+)
+
+const menuStyle = computed(() => {
+  const offset = props.size / 4;
+  return props.dire === 'row' ? { marginRight: offset + "px" } : { marginBottom: offset + 'px' }
+})
+</script>
+
+<style lang="scss" scoped>
+.menu {
+  width: 56px;
+  display: flex;
+  flex-direction: column;
+  cursor: pointer;
+  height: 100%;
+  text-align: center;
+  transition: color .3s ease;
+  color: #fff;
+
+  &.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>

+ 9 - 3
src/graphic/CanvasStyle/default.js

@@ -1,7 +1,6 @@
 const Road = {
   strokeStyle: "#939393",
-  lineWidth: 8,
-  realLineWidth: 2
+  lineWidth: 1,
 };
 
 const RoadEdge = {
@@ -58,7 +57,7 @@ const Point = {
 };
 
 const RoadPoint = {
-  ...Point,
+  ...Point
 };
 
 const CurveRoadPoint = {
@@ -71,6 +70,12 @@ const ControlPoint = {
   radius: 8,
 };
 
+const Circle = {
+  strokeStyle: "red",
+  fillStyle: "rgba(0,0,0,0)",
+  lineWidth: 2,
+};
+
 const Measure = {
   txt: "rgba(255,255,255,1)", //画墙/选墙的时候 测量值的颜色
   strokeStyle: "rgba(255,255,255,1)",
@@ -139,6 +144,7 @@ export default {
   CurveLan,
   Point,
   BaseLine,
+  Circle,
   Text,
   ControlPoint,
   CurveRoadPoint,

+ 1 - 1
src/graphic/CanvasStyle/focus.js

@@ -2,7 +2,7 @@ import def from "./default.js";
 
 const Road = {
   ...def.Road,
-  realLineWidth: 4,
+  lineWidth: 2,
   strokeStyle: "#3290FF",
 };
 

+ 1 - 1
src/graphic/CanvasStyle/select.js

@@ -2,7 +2,7 @@ import def from "./default.js";
 
 const Road = {
   ...def.Road,
-  realLineWidth: 4,
+  lineWidth: 2,
   strokeStyle: "#3290FF",
 };
 

+ 25 - 53
src/graphic/Renderer/Draw.js

@@ -35,7 +35,11 @@ const help = {
   setVectorStyle(ctx, vector, geoType = vector.geoType) {
     const styles = help.getVectorStyle(vector, geoType);
     for (const style in styles) {
-      ctx[style] = styles[style];
+      if (typeof styles[style] === "function") {
+        styles[style](ctx, vector)
+      } else {
+        ctx[style] = styles[style];
+      }
     }
     return styles;
   },
@@ -136,24 +140,21 @@ export default class Draw {
   }
 
   drawRoad(vector, isTemp) {
-    if (vector.display && vector.midDivide && vector?.midDivideWidth) {
+    if (vector.display) {
       const ctx = this.context;
-      const startScreen = coordinate.getScreenXY(vector.midDivide.start);
-      const endScreen = coordinate.getScreenXY(vector.midDivide.end);
-      const draw = () => {
+      const draw = (midDivide) => {
+        const startScreen = coordinate.getScreenXY(midDivide.start);
+        const endScreen = coordinate.getScreenXY(midDivide.end);
         ctx.beginPath();
         ctx.moveTo(startScreen.x, startScreen.y);
         ctx.lineTo(endScreen.x, endScreen.y);
         ctx.stroke();
-      };
+      }
 
       ctx.save();
-      const vectorStyle = help.setVectorStyle(ctx, vector);
-      ctx.lineWidth = vector.midDivideWidth;
-      draw();
-      ctx.strokeStyle = Style.bgColor;
-      ctx.lineWidth = vector.midDivideWidth - vectorStyle.realLineWidth;
-      draw();
+      help.setVectorStyle(ctx, vector);
+      vector.midDivide.leftMidDivide && draw(vector.midDivide.leftMidDivide);
+      vector.midDivide.rightMidDivide && draw(vector.midDivide.rightMidDivide);
       ctx.restore();
     }
 
@@ -354,22 +355,22 @@ export default class Draw {
     this.drawPoint(vector);
   }
 
+  drawCircle(element) {
+    this.drawPoint({
+      ...element.center,
+      radius: element.radius,
+      geoType: element.geoType
+    })
+  }
+
   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");
+    const style = help.setVectorStyle(ctx, vector, vector.geoType || "Point");
+    const radius = (vector.radius || style.radius) * coordinate.ratio
+    ctx.save()
     ctx.beginPath();
-    ctx.arc(
-      pt.x,
-      pt.y,
-      Style.Point.radius * coordinate.ratio,
-      0,
-      Math.PI * 2,
-      true
-    );
+    ctx.arc(pt.x, pt.y, radius, 0, Math.PI * 2, true);
     ctx.stroke();
     ctx.fill();
     ctx.restore();
@@ -398,35 +399,6 @@ export default class Draw {
     ctx.restore();
   }
 
-  drawCircle(element) {
-    let radius = null;
-    const twoPi = Math.PI * 2;
-    const pt = coordinate.getScreenXY(element);
-    this.context.save();
-    if (element.name == ElementEvents.AddingPoint) {
-      radius = Style.Element.AddingPoint.radius * coordinate.ratio;
-      this.context.strokeStyle = Style.Element.AddingPoint.strokeStyle;
-      this.context.fillStyle = Style.Element.AddingPoint.fillStyle;
-    } else if (element.name == ElementEvents.StartSymbolPoints) {
-      radius = Style.Element.StartSymbolPoints.radius * coordinate.ratio;
-      this.context.strokeStyle = Style.Element.StartSymbolPoints.strokeStyle;
-      this.context.fillStyle = Style.Element.StartSymbolPoints.fillStyle;
-    } else if (element.name == ElementEvents.EndSymbolPoints) {
-      radius = Style.Element.EndSymbolPoints.radius * coordinate.ratio;
-      this.context.strokeStyle = Style.Element.EndSymbolPoints.strokeStyle;
-      this.context.fillStyle = Style.Element.EndSymbolPoints.fillStyle;
-    } else if (element.name == "pano") {
-      radius = Style.Pano.radius * coordinate.ratio;
-      this.context.strokeStyle = Style.Pano.strokeStyle;
-      this.context.fillStyle = Style.Pano.fillStyle;
-      this.context.lineWidth = Style.Pano.lineWidth;
-    }
-    this.context.beginPath();
-    this.context.arc(pt.x, pt.y, radius, 0, twoPi, true);
-    this.context.stroke();
-    this.context.fill();
-    this.context.restore();
-  }
 
   drawLine(element) {
     const start = element.getType === VectorType.Line

+ 1 - 1
src/graphic/Service/RoadService.js

@@ -854,7 +854,7 @@ export default class RoadService {
     const distance1 = mathUtil.getDistance(startJoin1, mid);
     const distance2 = mathUtil.getDistance(startJoin2, mid);
 
-    let laneStart, laneEnd, line, join;
+    let laneStart, laneEnd, join;
 
     if (!dir || dir == "start") {
       if (distance1 > distance2) {

+ 1 - 4
src/hook/useLaser.ts

@@ -112,10 +112,7 @@ export const setupLaser = async (
   await loadSetupLaser();
   return new Promise<SDK>((resolve) => {
     sdk = sdkFactory(props as any);
-    sdk.scene.on("allLoaded", () => {
-      (window as any).laserLoaded = true;
-      resolve(sdk);
-    });
+    sdk.scene.on("allLoaded", () => resolve(sdk));
   }).then((sdk) => {
     relationStore(sdk, props.store);
     for (const fn of listenLoaded) {

+ 3 - 1
src/hook/useLoading.ts

@@ -12,6 +12,8 @@ export const useLoading = <T, K extends (...args: any) => Promise<T>>(
   Loading.show()
 
   const ret = typeof fn === 'function' ? fn() : fn
-  ret.finally(() => Loading.hide())
+  ret.finally(() => {
+    Loading.hide()
+  })
   return ret
 }

+ 1 - 1
src/preset/app.vue

@@ -28,7 +28,7 @@ const Component = computed(() => {
 if (!params.m) {
   setup.status = StatusEum.un;
   loaded.value = true;
-} else { 
+} else {
   baseInitStore()
     .then(() => (loaded.value = true))
     .catch((e) => {

+ 0 - 5
src/preset/main.vue

@@ -173,16 +173,11 @@ onMounted(async () => {
   try {
     const sdk = await useLoading(
       setupLaser({
-        mapCompany: "default",
         sceneSelector: sceneRef.value,
-        mapSelector: mapRef.value,
         num: useParams().m,
-        version: "V4",
-        gps: { x: 113.59590263492103, y: 22.36672184864973 },
         store: store,
         isDebug: useParams().test,
         webSite: webSite.value,
-        isLocal: false,
         axios,
         basePath: currentApp.basePath,
       })

+ 2 - 0
src/router/constant.ts

@@ -8,6 +8,7 @@ export const readyRouteName = {
   hotspot: "hotspot",
   measure: "measure",
   graphic: "graphic",
+  scene: "scene"
 } as const;
 
 export const writeRouteName = {
@@ -38,6 +39,7 @@ export const readyRouteMeta: RouteMetaRaw = {
   [readyRouteName.hotspot]: { title: ui18n.t("hotspot.name") },
   [readyRouteName.measure]: { title: ui18n.t("measure.name") },
   [readyRouteName.graphic]: { title: "绘图" },
+  [readyRouteName.scene]: { title: "绘图" },
 };
 
 export const writeRouteMeta: RouteMetaRaw<typeof modeFlags.LOGIN> = {

+ 6 - 0
src/router/info.ts

@@ -75,6 +75,12 @@ export const writeRoutesRaw: RoutesRaw<typeof modeFlags.LOGIN> = [
     meta: readyRouteMeta.graphic,
     component: () => import("@/views/graphic/index.vue"),
   },
+  {
+    path: "/scene",
+    name: readyRouteName.scene,
+    meta: readyRouteMeta.scene,
+    component: () => import("@/views/scene/index.vue"),
+  },
 ];
 
 export type RoutesRef<T extends ModeFlag = any> = ComputedRef<{

+ 0 - 1
src/sdk/index.ts

@@ -50,7 +50,6 @@ export const sdkFactory = (props: SDKProps): SDK => {
     el: presetCoverElement(laser.scene.el),
     sdkEl: laser.scene.el,
   });
-
   return {
     ...laser,
     sceneCarry: sceneCarry,

+ 7 - 0
src/sdk/laser/index.ts

@@ -7,6 +7,13 @@ let staticPrefix;
 export const setStaticPrefix = (ver) => (staticPrefix = ver);
 
 export const laserFactory = (props: LaserSDKProps, store?: Store): LaserSDK => {
+  console.log({
+
+    dom: props.sceneEl,
+    number: props.num,
+    staticPrefix,
+    ...props,
+  })
   const laser = enter({
     dom: props.sceneEl,
     number: props.num,

+ 5 - 2
src/views/graphic/index.vue

@@ -22,7 +22,7 @@ import MainPanel from '@/components/main-panel/index.vue'
 import ChildMenus from "@/views/graphic/childMenus.vue";
 import Header from './header.vue'
 import Container from './container.vue'
-import GraphicAction from '@/components/graphic-action/index.vue'
+import GraphicAction from '@/components/button-pane/index.vue'
 import UiIcon from "@/components/base/components/icon/index.vue";
 import VectorMenus from './vectorMenus.vue'
 
@@ -46,7 +46,10 @@ const {
   }),
 )
 
-const focusMenus = computed(() => focusMenuRaw[currentVector.value?.type])
+const focusMenus = computed(() => {
+  console.warn(focusMenuRaw[currentVector.value?.type])
+  return focusMenuRaw[currentVector.value?.type]
+})
 const isFull = computed(() => customMap.sysView === 'full' )
 </script>
 

+ 6 - 49
src/views/graphic/vectorMenus.vue

@@ -1,20 +1,11 @@
 <template>
-  <GraphicAction
+  <ActionMenus
     class="menus"
+    :menus="store.menus"
+    :active-key="store.activeMenuKey.value"
+    dire="row"
     :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"
@@ -23,9 +14,7 @@
 </template>
 
 <script setup lang="ts">
-import GraphicAction from '@/components/graphic-action/index.vue'
-import UiIcon from "@/components/base/components/icon/index.vue";
-
+import ActionMenus from '@/components/group-button/index.vue'
 import { MenusRaw, generateMixMenus } from "@/views/graphic/menus";
 import {computed} from "vue";
 
@@ -46,38 +35,6 @@ const store = computed(() => generateMixMenus(
   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>

+ 55 - 0
src/views/scene/container.vue

@@ -0,0 +1,55 @@
+<template>
+  <div class="canvas-layout">
+    <div class="scene-canvas" ref="sceneLayoutRef" />
+  </div>
+</template>
+
+<script setup lang="ts">
+import {onMounted, ref} from "vue";
+import {setupLaser, useLoading, useParams} from "@/hook";
+import {store} from "@/store";
+import {webSite} from "@/store/setup";
+import {currentApp} from "@/store/app";
+import { axios } from "@/dbo";
+import { Loading } from '@kankan/components/index'
+
+const sceneLayoutRef = ref<HTMLCanvasElement>();
+
+onMounted(() => {
+  useLoading(
+    setupLaser({
+      sceneSelector: sceneLayoutRef.value,
+      num: useParams().m,
+      store: store,
+      isDebug: useParams().test,
+      webSite: webSite.value,
+      axios,
+      basePath: currentApp.basePath,
+    })
+  );
+
+  setTimeout(() => {
+    Loading.hideAll()
+  }, 1000)
+});
+</script>
+
+<style scoped lang="scss">
+.canvas-layout {
+  width  : 100%;
+  height : 100%;
+  position: relative;
+  z-index: 0;
+}
+
+.scene-canvas {
+  width : 100%;
+  height: 100%;
+}
+
+.dire-canvas {
+  position: absolute;
+  right: 0;
+  top: 0;
+}
+</style>

+ 9 - 0
src/views/scene/index.vue

@@ -0,0 +1,9 @@
+<template>
+  <Container />
+  <Mode />
+</template>
+
+<script lang="ts" setup>
+import Container from "./container.vue"
+import Mode from './mode.vue'
+</script>

+ 48 - 0
src/views/scene/mode.vue

@@ -0,0 +1,48 @@
+<template>
+  <GroupButton
+    class="tabs"
+    :menus="menus"
+    :active-key="activeKey"
+  />
+</template>
+
+<script lang="ts" setup>
+import GroupButton from '@/components/group-button/index.vue'
+import {Mode} from "@/sdk";
+import {computed, ref, watchEffect} from "vue";
+import {customMap} from "@/hook";
+
+const tabs = [
+  {
+    mode: Mode.pano,
+    icon: "show_pic_n",
+    activeIcon: "show_pic_s",
+  },
+  {
+    mode: Mode.cloud,
+    icon: "show_dot_n",
+    activeIcon: "show_dot_s",
+  },
+];
+
+const activeKey = ref(tabs[0].mode);
+const menus = computed(() =>
+  tabs.map(tab => ({
+    icon: tab.mode === activeKey.value ? tab.activeIcon : tab.icon,
+    key: tab.mode,
+    onClick: () => activeKey.value = tab.mode
+  }))
+)
+
+watchEffect(() => {
+  console.log(activeKey.value)
+  customMap.mode = activeKey.value
+})
+</script>
+
+<style lang="scss" scoped>
+.tabs {
+  left: var(--boundMargin);
+  bottom: var(--boundMargin);
+}
+</style>