echarts实现伪3D立体地图+标点涟漪效果

分享一个基于echarts实现的伪3D地图并实现自定义坐标点和坐标点涟漪效果,实现效果如下:

要实现上图中的效果,我们需要配置三种type的echarts图,即:map、effectScatter、scatter,废话不多说,我们直接开干!(echarts版本:^5.4.0,vue版本:2.x)

初始化

初始化部分代码比较简单,不过还是有几点需要注意:

  • 我这里的地图渲染是借助DataV生成的,绘制地图的方法不是唯一,选择最适合你当前业务场景或你自己用起来最顺手的一种即可;
  • initMap方法中接收的info参数是我这边服务端传递的数据,主要是需要标注的坐标点的经纬度和坐标点名称;
  • mapData中对应的key:name、value等是按照echarts文档中散点图和涟漪图配置项进行配置的而不是随意定义的;

代码如下:

xml 复制代码
<template>
    <div class="map-box">
      <div ref="map3d" style="width: 100%; height: 100%;" />
    </div>
</template>
<script>
    import * as echarts from 'echarts'
    data() {
      return {
        // 考点标记图片
        examSite: require('@/assets/screen/exam-site.png')
      }
    },
    methods: {
        /**
         * 初始化地图
         * @param info 坐标点信息
         */
        async initMap(info) {
            const mapJson = (await axios.get('https://geo.datav.aliyun.com/areas_v3/bound/152500_full.json')).data
            const mapChart = echarts.init(this.$refs.map3d)
            mapChart.showLoading()
            // 注册地图
            echarts.registerMap('MapAddress', mapJson)
            const { organizationName, latitude, longitude } = info
            // 地图点坐标,用于散点图和涟漪图
            const mapData = [
              {
                name: organizationName,
                value: [longitude, latitude],
                type: 'normal',
                img: this.examSite
              }
            ]
            const option = { ... }
            mapChart.setOption(option)
            mapChart.hideLoading()
            window.addEventListener('resize', function() {
                 mapChart.resize()
            })
        }
    }
</script>

到这里我们初始化就完成了,其实页面上啥也没有-_-,与其说是初始化,不如说是前期的一些参数接收和配置,接下来才是重头戏

地图配置项

我们在文件目录中新建一个叫做mapOptions的js文件来专门放置地图的一些配置项。

yaml 复制代码
export const mapOptions = {
  // 地理坐标系组件
  geo: [
    {
      // registerMap注册的地图名称
      map: 'MapAddress',
      // 是否可缩放
      roam: false,
      // 地图层级
      zlevel: 5,
      label: {
        normal: {
          show: false
        },
        emphasis: {
          show: false
        }
      },
      left: 10,
      right: 0,
      top: 0,
      bottom: 20,
      itemStyle: {
        areaColor: '#01215c',
        borderWidth: 3,
        borderColor: '#9ffcff',
        // 阴影颜色
        shadowColor: 'rgba(9, 140, 255, 0.9)',
        shadowBlur: 14
      },
      // 高亮样式
      emphasis: {
        itemStyle: {
          areaColor: '#01215c'
        }
      }
    },
    // 这一个是为了仿3D地图,故创建一个低层级的一模一样的地图
    {
      map: 'MapAddress',
      roam: false,
      zlevel: 4,
      label: {
        normal: {
          show: false
        },
        emphasis: {
          show: false
        }
      },
      left: 10,
      right: 0,
      top: 0,
      bottom: 20,
      itemStyle: {
        areaColor: '#01215c',
        shadowColor: '#9ffcff',
        shadowOffsetX: 0,
        shadowOffsetY: 6
      }
    }
  ]
}

在代码中可以看到,我在geo中配置了两个相同的地图,仅仅是改变了层级和itemStyle的配置,然后我们将这个mapOptions文件引入进我们地图组件的option里面

ini 复制代码
const option = {
    ...mapOptions
}

就可以得到下图效果:

此时可以看到边框就会有出现立体效果了,所以说这是伪3D,因为我们是基于平面来实现的。但是现在很明显地图太亮了,并且地图内部的边框和边缘的边框是一样粗的,很影响感观,所以我们对这个地图进行样式上的一些优化。

series type: 'map'

对于地图内容样式的一些优化很简单,大家对照echarts官网中series,type: 'map'的配置项文档对照来看就能看懂,所以不需要过多描述,我认为需要注意的配置项也写了注释。

yaml 复制代码
const option = {
    ...mapOptions,
    series: [
        // map
        {
          type: 'map',
          map: 'MapAddress',
          zlevel: 5,
          // 这个参数用于 scale 地图的长宽比
          aspectScale: 0.75,
          left: 10,
          right: 0,
          top: 0,
          bottom: 20,
          label: {
            normal: {
              show: false
            },
            emphasis: {
              show: false,
              textStyle: {
                color: '#fff'
              }
            }
          },
          roam: false,
          itemStyle: {
            areaColor: '#01215c',
            borderColor: 'rgba(61, 197, 225)',
            borderWidth: 1
          },
          emphasis: {
            disabled: true,
            itemStyle: {
              areaColor: '#01215c'
            }
          },
          // 图形是否不响应和触发鼠标事件,默认为 false,即响应和触发鼠标事件。
          silent: true
        }
    ]

当我们写完了上面的配置后,就会发现我们的地图变得稍微好看了一些,至少中间的边框不会那么粗了。

地图我们渲染好了后就该标记坐标点了,这里我们用到的是scatter散点图,也是对照官方文档进行配置项的编写,同样很简单。

series type: 'scatter'

散点图的配置项直接接着上面map的配置项后面写就可以了,同样我也将type: 'scatter'的文档地址放在这里:echarts.apache.org/zh/option.h...

javascript 复制代码
// 散点图
{
  type: 'scatter',
  coordinateSystem: 'geo',
  zlevel: 6,
  itemStyle: {
    color: '#f00',
    opacity: 1
  },
  // 自定义点样式
  symbol: (value, params) => {
    return `image://${params.data.img}`
  },
  // 动态改变点大小
  symbolSize: (value, params) => {
    return params.data.type === 'normal' ? [130, 30] : [127, 30]
  },
  // 点偏移量
  symbolOffset: [45, -15],
  label: {
    show: true,
    formatter: (params) => {
      return params.data.name
    },
    color: '#fff',
    fontSize: 16,
    align: 'center',
    offset: [10, 0]
  },
  z: 9999,
  data: mapData
}

现在我们就可以看到我们自定义图标的坐标点已经渲染在了地图上,解释一下代码中的动态改变点大小,其实是一种很粗糙的处理方式,考虑到我们坐标点名称长度可能会不一样,所以对symbolSize做了处理,这个处理仅仅是满足我当前的项目。

最后我们将涟漪图配置项按照上面的方式写入代码:

series type: 'effectScatter'

css 复制代码
// 波纹涟漪
{
  type: 'effectScatter',
  coordinateSystem: 'geo',
  zlevel: 5,
  symbol: 'circle',
  rippleEffect: {
    color: '#FDD835',
    number: 2,
    scale: 8,
    brushType: 'fill'
  },
  itemStyle: {
    color: '#FDD835'
  },
  data: mapData
}

至此,我们就能实现文章开头的效果了!

内容不少,但不难,主要就是echarts的配置项,对照官方文档慢慢写就能写出来

写在最后

🥰🥰🥰感谢能看到最后的jym,这篇文章主要是记录自己在项目实现地图的过程,方便以后在其他项目中要用到时可以随时查找,写的不好望多多谅解😅,如果对你们也能有一定的帮助那我就太太太太荣幸了🤘

相关推荐
John.liu_Test28 分钟前
js下载excel示例demo
前端·javascript·excel
Yaml441 分钟前
智能化健身房管理:Spring Boot与Vue的创新解决方案
前端·spring boot·后端·mysql·vue·健身房管理
PleaSure乐事43 分钟前
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
前端·javascript·react.js·前端框架·webstorm·antdesignpro
哟哟耶耶43 分钟前
js-将JavaScript对象或值转换为JSON字符串 JSON.stringify(this.SelectDataListCourse)
前端·javascript·json
getaxiosluo44 分钟前
react jsx基本语法,脚手架,父子传参,refs等详解
前端·vue.js·react.js·前端框架·hook·jsx
理想不理想v1 小时前
vue种ref跟reactive的区别?
前端·javascript·vue.js·webpack·前端框架·node.js·ecmascript
知孤云出岫1 小时前
web 渗透学习指南——初学者防入狱篇
前端·网络安全·渗透·web
贩卖纯净水.1 小时前
Chrome调试工具(查看CSS属性)
前端·chrome
栈老师不回家2 小时前
Vue 计算属性和监听器
前端·javascript·vue.js
前端啊龙2 小时前
用vue3封装丶高仿element-plus里面的日期联级选择器,日期选择器
前端·javascript·vue.js