mar3d的widget移植到自己的项目使用

前言

····如果了解mars3D(火星科技)三维开发平台的人都应该知道mars3D项目中的widget模块。该模块的好处主要就是为了快速实现gis项目中常见的一些工具面板,满足定制化开发的需求。同时可以在复杂的场景下非常清晰的管理功能模块之间的互斥关系,管理内存,完成不同的功能模块之间的解耦,并且可以实现功能模块之间的交互。

····我在网上也找了相关的文章,如何将widget模块移植到自己的项目中,但发现都没有详细的介绍,基本讲的都是该模块的使用或者很笼统,大家有兴趣也可以参考一下两篇文章:
mars3d基于react版本的widget使用
mars3d基于vue3.0的widget使用

·····回归正题,要想使用,前提不得是移植到自己的项目中去,我移植的项目主要采用vite+vue3+ts,以下就是移植的主要步骤。

1将widget文件复制到自己的项目中

widget的核心文件主要放在src/common的文件夹下,直接将common文件夹都拷贝到自己项目的src文件下:
移植到src文件夹下

2在HelloWord组件当前路径下新建widget.vue组件

widget.vue组件代码如下(或可直接把整个文件复制过来):

<template>
  <component :is="widget.component" v-bind="getWidgetAttr(widget)" />
</template>
<script lang="ts">
import { useAttrs, defineComponent, provide } from "vue"
import type { Widget } from "@tp/common/store/widget"

export default defineComponent({
  name: "tp-widget",
  props: ["widget"],
  setup(props) {
    const attrs = useAttrs()

    provide("getCurrentWidget", () => {
      return props.widget.name
    })

    const getWidgetAttr = (widget: Widget) => {
      let attr = {}
      if (widget.meta && widget.meta.props) {
        attr = {
          ...attr,
          ...widget.meta.props
        }
      }
      if (widget.data && widget.data.props) {
        attr = {
          ...attr,
          ...widget.data.props
        }
      }
      return attr
    }

    return {
      attrs,
      getWidgetAttr
    }
  }
})
</script>

HelloWord.vue组件中做相应的修改,如下:

<template>
  <ConfigProvider :locale="locale">
    <div class="mars-main-view" id="mars-main-view">
      <div id="centerDiv" class="centerDiv-container">
        <tp-map @onload="marsOnload" />
      </div>
      <template v-if="loaded">
        <template v-for="comp in widgets" :key="comp.key">
          <tp-widget v-if="openAtStart.includes(comp.name) && comp.visible" v-model:visible="comp.visible" :widget="comp" />
        </template>
      </template>
    </div>
  </ConfigProvider>
</template>
  
<script setup lang="ts">
/**
 * 渲染主入口
 * @copyright 火星科技 mars3d.cn
 * @author 火星吴彦祖 2022-02-19
 */
import zhCN from "ant-design-vue/es/locale/zh_CN"
import { provide, ref, computed } from "vue"
import { ConfigProvider } from "ant-design-vue"
import { useWidgetStore } from "@tp/common/store/widget"
import TpMap from "../tp-work/TpMap.vue"
import TpWidget from "./widget.vue"

const locale = zhCN

const widgetStore = useWidgetStore()

const widgets = computed(() => widgetStore.state.widgets)
const openAtStart = computed(() => widgetStore.state.openAtStart)



let mapInstance: any = null

provide("getMapInstance", () => {
  return mapInstance
})

const emit = defineEmits(["mapLoaded"])

const loaded = ref(false)
const marsOnload = (map: any) => {
  console.log("map构造完成")
  mapInstance = map
  emit("mapLoaded", mapInstance)
  loaded.value = true
}
</script>
  
<style lang="less" scoped>
.mars-main-view {
  height: 100%;
  width: 100%;
  position: relative;
}
.centerDiv-container {
  height: 100%;
  width: 100%;
  overflow: hidden;
}
</style>
  

widget本质就是一个vue组件

3在main.ts路径下新建一个widget-store.ts

widget-store.ts代码如下,主要用来控制组件的展示,同样可以直接复制过来。


import { defineAsyncComponent, markRaw } from "vue"
import { WidgetState } from "@tp/common/store/widget"
import { StoreOptions } from "vuex"

const store: StoreOptions<WidgetState> = {
  state: {
    widgets: [
      {
        component: markRaw(defineAsyncComponent(() => import("@tp/widget/test.vue"))),
        name: "query-poi",
        autoDisable: true
      }
    ],
    openAtStart: ["query-poi"]
  }
}

export default store

main.ts下进行导入

import { createApp } from "vue"
import App from "./App.vue"
import MarsUIInstall from "@tp/components/mars-ui"
import ElementPlus from "element-plus"
import "element-plus/dist/index.css"
import { injectState, key } from "@tp/common/store/widget"
import store from "./widget-store"

const app = createApp(App)

MarsUIInstall(app)
app.use(ElementPlus)
app.use(injectState(store), key)

app.mount("#app")

到此基本就移植完了,但此时还不能运行。最最最最最最重要的是,还需要一个vite.config.ts的配置,不然widget.js解析不了,我就是在这上面搞了好久。

4配置vite.config.ts(最最最重要的)

其配置如下:

 optimizeDeps: {
      include: ["@tp/common/store/widget"]
    },

需要在配置下添加这个进行预编译,这个时候还需要进行相应的包安装

"dependencies": {
     "vuex": "^4.0.2"
 }
 "devDependencies": {
    "uuid": "^8.3.2",
}
如果还缺少包,按提示安装吧

最后就可以随心所欲的用widget模块啦,完结,如果还不能整好,欢迎留言,我定答复。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Marzipano 3D 场景中判断一个点是否在给定区域,可以采用射线法或多边形顶点法。 射线法:通过 Marzipano 3D 场景中的 API 获取到需要判断区域的坐标系,然后获取鼠标点击事件的坐标,使用射线与区域的边相交的次数来判断点是否在区域内。具体实现方法如下: ```javascript viewer.addEventListener('click', function(event) { const coords = viewer.view().screenToCoordinates({x: event.clientX, y: event.clientY}); const isInside = isPointInsidePoly(coords, vertices); if (isInside) { // 点在区域内部 } else { // 点在区域外部 } }); function isPointInsidePoly(point, vertices) { let inside = false; const n = vertices.length; for (let i = 0, j = n - 1; i < n; j = i++) { const vi = vertices[i], vj = vertices[j]; const intersect = ((vi.y > point.y) != (vj.y > point.y)) && (point.x < (vj.x - vi.x) * (point.y - vi.y) / (vj.y - vi.y) + vi.x); if (intersect) inside = !inside; } return inside; } ``` 多边形顶点法:同样通过 Marzipano 3D 场景中的 API 获取到需要判断区域的坐标系,然后获取鼠标点击事件的坐标,使用多边形的顶点连接起来形成一系列边,判断这个点是否在这些边的左侧。具体实现方法如下: ```javascript viewer.addEventListener('click', function(event) { const coords = viewer.view().screenToCoordinates({x: event.clientX, y: event.clientY}); const isInside = isPointInsidePoly(coords, vertices); if (isInside) { // 点在区域内部 } else { // 点在区域外部 } }); function isPointInsidePoly(point, vertices) { let inside = false; const n = vertices.length; for (let i = 0, j = n - 1; i < n; j = i++) { const vi = vertices[i], vj = vertices[j]; const intersect = ((vi.y > point.y) != (vj.y > point.y)) && (point.x < (vj.x - vi.x) * (point.y - vi.y) / (vj.y - vi.y) + vi.x); if (intersect) inside = !inside; } return inside; } ``` 以上是两种常见的方法,具体实现可以根据实际情况选择适合的方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值