在制作区域地图时,往往我们会因为没有地图的坐标数据,无法使用Echarts来绘制地图,这时候我们可以使用HTML的usemap属性来完成地图效果。比如鼠标指到指定的地图区域,该区域高亮显示,然后显示该区域的一些基本信息,还有一些点击事件处理等等。
示例图片:
一、HTML的usemap属性
img标签的usemap属性:它可以指定一个map标签
map标签:地图集合。必须包含name属性
area标签:区域坐标集合。shape指区域的形状,包括矩形rect、圆形circle、多边形polygon;coords表示该区域的坐标集合。也可以指定href,点击跳转到指定页面。
<img src="planets.jpg" border="0" usemap="#planetmap" alt="Planets" />
<map name="planetmap" id="planetmap">
<area shape="circle" coords="180,139,14" href ="venus.html" alt="Venus" />
<area shape="circle" coords="129,161,10" href ="mercur.html" alt="Mercury" />
<area shape="rect" coords="0,0,110,260" href ="sun.html" alt="Sun" />
</map>
详情查看W3School说明
二、素材准备
1. 图片素材
既然是基于img的usermap来做地图热区,那么必须要要有对应的图片素材。例如:中国地图图片、选择北京市高亮的图片、选择贵州省高亮的图片、选择广州省高亮的图片等等,这些图片的未选中的内容位置不变,因为是根据坐标来完成的。
2. 地理围栏坐标
我们需要每一个地图块的地理围栏坐标,才能实现鼠标移动到指定的区域,做出相应的变化。
使用MapEdit工具获取:
- 点“文件”-“新建HTML文档(打开图像)”,打开一张你要制作成锚点链接的图片;
- 在“工具”里选择一种作用范围,比如“矩形”、“圆形”或“多边形”,然后就可以用鼠标在图片上画出作用范围了;
- 连续点击鼠标左键形成一个闭环,拖动鼠标选定一个范围;
- 自动弹出一个文本框,填写“ALT文本”,比如 北京,表示该区域的名称;
- 所有区域选择完毕后,Ctrl+S 保存。
MapEdit下载地址:百度网盘,提取码h9w4
当然你也可以使用其他的方式获取围栏坐标。比如使用ps、Dreamweaver,甚至用Python智能分析获取都是可以的。
三、代码实现
imgMap.vue的代码实现:
<template>
<div class="img-map">
<img :src="mapSrc" usemap="#img-map" alt="" style="border-style:none" @mouseover="mouseoverArea"/>
<map id="img-map" name="img-map">
<area v-for="item in mapData" :key="item.id" shape="poly" :coords="item.coords" @mouseover.prevent="hoverArea(item, $event)" @click="clickArea(item, $event)" />
</map>
<div class="popup" v-show="showPopup" v-loading="loadingWeather" :style="styles">
<p style="font-weight: bold;">{{currentWeather.city}}</p>
<ul>
<li>
<img :src="currentWeather.daySrc"/>
<p>{{currentWeather.daytemp}} ℃</p>
</li>
<li>
<img :src="currentWeather.nightSrc"/>
<p>{{currentWeather.nighttemp}} ℃</p>
</li>
</ul>
<p style="text-align: center"><label>风级:</label> {{currentWeather.daypower}} ~ {{currentWeather.nightpower}}</p>
</div>
</div>
</template>
<script>
import mapData from './mapData.json'
import weatherData from './weatherData.json'
import defaultMap from 'assets/images/map/1.png'
import noWeater from 'assets/images/weather/no_weather.png'
import getWeather from 'api/getWeather'
const POPUP_WIDTH = 130
const POPUP_HEIGHT = 100
export default {
props: {
defaultArea: {
type: String,
default: ''
}
},
data() {
return {
mapData,
weatherData,
mapSrc: defaultMap,
tempArea: defaultMap,
noWeater,
showPopup: false,
loadingWeather: false,
currentWeather: {},
styles: null
}
},
created() {
this.mapData.forEach(item => {
item.weather = null
})
if (this.defaultArea !== '') {
const obj = this.mapData.find(o => o.id === this.defaultArea)
if (obj) this.mapSrc = obj.mapSrc
}
},
methods: {
hoverArea(area, event) {
// 切换图片
this.mapSrc = area.mapSrc
// 控制弹窗显示的位置
this.styles = {
top: event.clientY - POPUP_HEIGHT - 35 + 'px',
left: event.clientX - POPUP_WIDTH / 2 - 25 + 'px'
}
this.showPopup = true
this.getWeatherData(area)
this.$emit('hoverArea', area)
},
clickArea(area, event) {
this.mapSrc = area.mapSrc
this.tempArea = area.mapSrc
this.$emit('clickArea', area)
},
mouseoverArea () {
this.showPopup = false
this.mapSrc = this.tempArea
},
getWeatherData (area) {
const index = this.mapData.findIndex(o => o.id === area.id)
if (index > -1 && this.mapData[index].weather == null) {
this.loadingWeather = true
getWeather(area.title, 'all').then(data => {
const temp = data.casts[0]
temp.city = data.city
for (let i = 0; i < this.weatherData.length; i++) {
if (temp.dayweather === this.weatherData[i].name) {
temp.daySrc = this.weatherData[i].src
break
}
}
for (let i = 0; i < this.weatherData.length; i++) {
if (temp.nightweather === this.weatherData[i].name) {
temp.nightSrc = this.weatherData[i].src
break
}
}
this.mapData[index].weather = temp // 为了保证一个地区只获取一次天气数据
this.currentWeather = temp
this.loadingWeather = false
}).catch(errMsg => {
this.loadingWeather = false
})
} else if (index > -1 && this.mapData[index].weather != null) {
this.currentWeather = this.mapData[index].weather
}
}
}
}
</script>
<style lang="stylus" scoped>
@import '~assets/css/variable.styl'
.img-map
user-select none
.popup
width 130px
height 100px
padding 9px
font-size $font-size-small
position fixed
top 20px
left 180px
background #fff
border 1px solid $color-border
filter drop-shadow(0 0 3px #999)
border-radius 5px
&:before
content ''
position absolute
left 50%
top 100%
transform translateX(-50%)
border 9px solid transparent
border-top-color #999
z-index 1
&:after
content ''
position absolute
left 50%
top calc(100% - 1px)
transform translateX(-50%)
// border-left 6px solid transparent
// border-right 9px solid transparent
border 9px solid transparent
border-top-color #fff
z-index 2
ul
display flex
margin-top 3px
margin-bottom 7px
li
width 50%
text-align center
&:last-child
border-left 1px solid $color-border
margin-left -1px
img
width 40px
p
margin-top -4px
</style>
每一个区域的属性配置:
[
{
"id": "ba062c32fdf611e7ba2d00163e0c27f8",
"title": "凯里市",
"mapSrc": "./static/images/map/10.png",
"coords": "93,126,103,125,114,134,122,134,128,141,135,143,142,141,150,144,162,144,167,144,168,149,163,158,166,168,161,178,166,193,163,199,155,203,142,211,134,206,121,208,102,207,110,201,112,195,110,190,110,183,103,177,101,173,89,169,84,167,85,153,83,146,85,139,90,129,94,126,95,126,93,127"
},
{
"id": "ba5287a7fdf611e7ba2d00163e0c27f8",
"title": "丹寨县",
"mapSrc": "./static/images/map/16.png",
"coords": "79,228,78,235,72,241,69,258,76,265,85,274,94,277,98,289,113,295,127,294,136,298,137,304,139,296,133,291,136,278,136,267,129,262,130,248,122,233,121,226,116,224,119,217,120,209,101,207,99,210,94,210,85,219,84,225,77,225,69,228"
},
{
"id": "ba9da079fdf611e7ba2d00163e0c27f8",
"title": "麻江县",
"mapSrc": "./static/images/map/11.png",
"coords": "21,160,28,154,51,153,52,156,62,159,66,160,70,160,82,163,84,167,93,170,102,174,103,178,110,183,110,190,113,195,109,201,102,205,101,209,98,210,93,211,86,218,84,223,84,225,77,225,70,228,60,226,50,217,47,206,40,202,33,205,22,203,18,203,17,195,10,191,11,174,21,168,20,160"
},
{
"id": "baeb0926fdf611e7ba2d00163e0c27f8",
"title": "黄平县",
"mapSrc": "./static/images/map/5.png",
"coords": "100,12,108,13,112,16,115,17,119,21,122,30,130,32,134,34,137,41,141,43,143,48,150,49,152,57,153,64,145,74,143,75,143,81,150,88,153,93,153,101,157,104,158,108,165,112,170,113,175,118,179,126,179,133,179,135,171,137,169,141,162,143,149,144,141,141,133,143,129,141,123,135,113,134,103,125,103,116,90,115,85,116,84,108,77,103,77,95,86,85,91,82,91,75,91,60,97,54,102,34,99,26,95,18,98,16"
},
{
"id": "bb357191fdf611e7ba2d00163e0c27f8",
"title": "施秉县",
"mapSrc": "./static/images/map/4.png",
"coords": "150,48,153,42,156,40,158,33,158,28,163,24,173,22,183,25,186,29,189,31,189,38,192,41,199,50,207,57,208,61,204,66,205,75,206,79,201,87,201,96,194,104,194,116,198,117,200,119,209,121,214,124,218,130,220,133,228,133,230,138,230,142,236,148,236,151,233,153,231,156,224,157,218,151,212,148,208,142,198,138,196,134,192,131,186,135,179,134,180,125,175,116,170,112,162,109,157,104,153,100,153,92,143,80,144,74,154,63,153,57"
},
{
"id": "bb842d8ffdf611e7ba2d00163e0c27f8",
"title": "镇远县",
"mapSrc": "./static/images/map/3.png",
"coords": "189,33,198,31,210,31,213,33,221,34,222,37,232,36,237,36,241,41,245,44,249,51,245,58,247,64,253,63,257,68,260,75,267,80,273,78,278,79,283,84,286,86,288,92,298,95,302,89,306,93,309,101,310,106,305,109,298,113,298,119,300,121,292,124,280,123,272,118,272,113,265,109,252,113,247,114,242,124,239,125,237,134,240,143,238,147,230,142,229,136,227,132,219,130,214,124,209,120,200,118,195,115,195,103,202,96,201,85,207,81,205,65,208,58,198,49,194,42,189,38,190,32"
},
{
"id": "bbce67dffdf611e7ba2d00163e0c27f8",
"title": "岑巩县",
"mapSrc": "./static/images/map/2.png",
"coords": "220,30,226,27,229,29,234,25,252,26,280,9,288,10,295,17,304,20,310,25,317,27,327,28,332,32,341,34,347,47,344,58,333,63,319,60,313,59,312,68,306,72,307,77,299,80,301,90,299,95,286,92,286,85,278,79,271,76,266,80,261,75,258,68,253,63,247,63,247,55,249,51,245,44,236,35,228,37,222,36,219,33,220,29,221,30,220,29"
},
{
"id": "bc198ca9fdf611e7ba2d00163e0c27f8",
"title": "三穗县",
"mapSrc": "./static/images/map/7.png",
"coords": "305,119,313,120,318,126,324,133,330,137,333,143,329,151,330,154,329,158,325,158,316,157,314,159,301,160,298,158,284,162,266,165,259,162,252,161,244,154,235,152,237,148,241,144,238,134,239,125,244,122,247,114,262,110,268,110,273,120,282,124,298,123,304,119"
},
{
"id": "bc64498bfdf611e7ba2d00163e0c27f8",
"title": "天柱县",
"mapSrc": "./static/images/map/6.png",
"coords": "314,116,320,112,324,113,325,114,330,109,347,110,353,119,357,122,360,121,381,111,393,110,403,120,403,136,407,147,413,154,418,169,408,178,407,182,403,181,398,180,399,184,404,191,406,204,400,208,398,211,382,215,374,214,371,211,362,210,361,201,353,198,346,196,339,198,335,201,317,205,313,202,303,196,301,187,296,181,306,173,309,176,321,168,326,160,330,156,329,150,333,143,329,136,313,120"
},
{
"id": "bcaf466bfdf611e7ba2d00163e0c27f8",
"title": "锦屏县",
"mapSrc": "./static/images/map/12.png",
"coords": "266,244,273,251,282,255,286,257,289,255,300,255,307,261,315,261,323,265,324,270,347,271,356,272,365,267,368,259,369,254,374,250,375,238,370,229,366,226,365,221,368,216,372,214,372,211,361,210,360,203,355,197,353,198,347,196,336,202,325,204,316,206,310,203,302,196,303,191,300,187,296,185,296,181,289,188,287,197,284,198,285,211,281,215,282,229,274,240,262,243"
},
{
"id": "bcfa6f1bfdf611e7ba2d00163e0c27f8",
"title": "黎平县",
"mapSrc": "./static/images/map/13.png",
"coords": "228,340,238,347,246,347,260,354,263,360,274,361,279,359,287,353,297,369,297,377,300,389,300,401,298,406,305,414,306,417,321,417,330,406,336,386,345,383,351,374,351,369,362,361,366,355,374,348,370,331,366,316,376,305,378,294,369,288,359,290,351,295,347,294,346,280,356,272,338,270,324,269,320,263,307,261,299,255,289,254,287,256,277,253,270,250,265,243,259,239,243,243,233,247,237,252,234,260,223,264,224,273,214,288,216,295,215,303,220,306,230,314,232,325,229,338"
},
{
"id": "bd44cca9fdf611e7ba2d00163e0c27f8",
"title": "从江县",
"mapSrc": "./static/images/map/17.png",
"coords": "129,404,128,411,136,414,137,423,142,423,146,429,146,435,158,441,161,456,168,462,169,470,180,473,185,473,192,461,193,450,192,440,189,431,194,430,199,424,208,417,215,416,218,427,219,434,231,438,245,440,263,448,268,448,273,444,272,434,272,421,279,413,282,405,273,397,249,403,241,395,247,392,260,392,268,394,275,389,287,395,297,404,299,401,298,387,296,373,296,367,288,354,280,358,273,361,261,360,260,354,246,348,237,347,228,341,229,332,231,326,218,325,216,328,203,332,205,351,208,358,198,363,191,370,178,367,169,375,166,384,154,391,151,395,133,392,127,393"
},
{
"id": "bd8f5cd4fdf611e7ba2d00163e0c27f8",
"title": "榕江县",
"mapSrc": "./static/images/map/14.png",
"coords": "135,313,119,323,119,334,112,341,113,352,114,361,118,369,120,379,123,384,125,390,130,393,134,392,143,393,148,394,152,394,156,388,167,382,170,374,177,365,187,369,191,369,199,361,207,358,208,356,204,352,203,340,204,331,211,329,217,327,221,324,230,325,230,315,219,305,213,303,216,295,215,286,224,271,223,264,233,259,237,253,234,247,221,247,219,244,195,247,182,238,176,238,175,244,171,248,171,259,168,270,160,275,156,281,155,293,144,304,138,304"
},
{
"id": "bdda2928fdf611e7ba2d00163e0c27f8",
"title": "雷山县",
"mapSrc": "./static/images/map/15.png",
"coords": "139,303,144,305,155,293,158,280,168,271,171,261,170,252,175,245,176,238,173,233,176,227,177,218,172,208,167,203,169,196,164,196,159,203,154,203,143,210,139,210,134,206,120,208,118,218,118,223,120,224,125,237,130,248,129,262,136,266,136,280,135,294,139,295,139,304,139,302"
},
{
"id": "be25afc0fdf611e7ba2d00163e0c27f8",
"title": "台江县",
"mapSrc": "./static/images/map/9.png",
"coords": "212,151,214,160,218,164,220,165,221,178,219,179,217,184,206,188,206,197,213,205,214,210,213,215,212,219,205,226,184,225,177,221,174,213,173,209,167,203,168,195,165,192,162,186,163,175,166,169,164,160,169,151,168,143,172,138,181,135,192,132,198,138,205,141,211,148,211,151,212,152"
},
{
"id": "be702db5fdf611e7ba2d00163e0c27f8",
"title": "剑河县",
"mapSrc": "./static/images/map/8.png",
"coords": "177,225,177,227,174,233,174,237,183,238,195,247,213,245,220,244,221,247,236,246,260,238,262,242,271,242,275,238,281,229,280,213,284,211,283,199,286,197,288,187,296,181,297,178,306,173,309,175,319,169,325,160,324,158,317,158,315,160,302,160,297,159,265,167,260,163,254,163,247,159,244,154,234,153,232,157,223,157,213,149,212,152,217,162,221,165,221,178,217,184,206,189,206,197,213,205,213,210,212,219,205,226,184,224,176,221"
}
]