技术标签: 仿链家地图找房
前一段时间我应公司的需求开发了类似链家地图找房的功能,然而我发现现在市面上,对于链家地图找房功能的完整实现相关的文章还是比较稀缺的,亦或是功能还不够完善,出于这个方面,我觉得把自己对于链家地图找房功能的完整实现分享出来还是很有必要的,包括其中的画圈找房,以及如何将整个地图找房拆分成一个个组件。
起步
1、效果预览图
2、准备工作
技术栈
vue全家桶 + vue-baidu-map + BMapLib
其中 vue-baidu-map 是第三方库,已经封装好了部分组件,直接用就行;BMapLib是百度开源库
组件拆分
地图容器组件:
区域气泡组件(自定义覆盖物):
区域边界组件:
周边房源气泡组件(自定义覆盖物):
周边房源详情覆盖物组件(自定义覆盖物):
画圈找房区域气泡组件:
画圈找房路径组件:
画圈找房提示组件:
周边房源总数提示组件:
地图初始化
首先,我们要做的就是地图初始化,这里用到的是 baidu-map 组件,
复制代码
参数说明:
center 表示地图的中心点坐标,例如{ lng: 116.404, lat: 39.915 }
zoom 表示地图的缩放等级
scroll-wheel-zoom 表示是否开启滚轮缩放
ready事件表示地图加载完成后需要的操作,例如设置地图中心点坐标 center,或者是获取 BMap、map 类等等
handler ({ BMap, map }) {
// lng, lat 表示你要设置的经纬度
this.$set(this.center, 'lng', lng)
this.$set(this.center, 'lat', lat)
console.log(BMap) // just console.log(BMap)
console.log(map) // just console.log(map)
}
复制代码
在这里,我是先定位获取当前省份的经纬度,通过事件传递,然后设置 center
handler ({BMap, map}) {
this.initGeo()
},
initGeo () {
connect.$on('cityGeoOk', data => {
this.$set(this.center, 'lng', data[0])
this.$set(this.center, 'lat', data[1])
})
}
复制代码
至于 vue 跨组件的通信就好比打电话一样,需要一个基站,所以新建一个js文件(这里我命名为 connect)
import Vue from 'vue'
export default new Vue()
复制代码
然后在组件中引入即可,通过 connect.$emit('event', data) 派发一个事件,然后通过 connect.$on('event', data => {}) 侦听事件。
最后,还需要设置一下地图容器 baidu-map 的缩放等级(我设置的是12,具体可自己调整)和高度,不然是看不见效果的
.bm-view{
height: 100%; /* for example */
}
复制代码
效果如下:
区域气泡显示
在地图初始化之后,接下来就是如何将不同的区域显示在地图上了,这里我用到的是 bm-overlay 组件,并且将其二次封装成 zoneOverlay 组件。
v-for="(item, index) in zoneGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item">
复制代码
zoneGeoPoints 表示区域数组,从后台接口获取,元素为对象,属性包括区域的经纬度等信息。
// zoneOverlay.vue
ref="customOverlay"
class="zone"
pane="labelPane"
@draw="draw">
{ {text.name}}
{ {text.houseCnt}}套
export default {
props: ['text', 'position', 'active'],
watch: {
position: {
handler () {
this.$refs.customOverlay.reload()
},
deep: true
}
},
methods: {
draw ({el, BMap, map}) {
const {lng, lat} = this.position
const pixel = map.pointToOverlayPixel(new BMap.Point(lng, lat))
el.style.left = pixel.x - 42 + 'px'
el.style.top = pixel.y - 42 + 'px'
}
}
}
.zone
transition: background-color .15s ease-in-out
display: flex
align-items: center
width: 84px
height: 84px
background-color: rgba(58,126,255,0.9)
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
color: #fff
font-size: 12px
text-align: center
padding: 10px
position: absolute
border-radius: 50%
box-shadow: 0 0 4px #999
box-sizing: border-box
&:hover
z-index: 1
background-color: rgba(240,65,52,.9)
color: #fff
div
display: flex
flex-wrap: wrap
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
justify-content: space-between
p
overflow: hidden
text-overflow: ellipsis
white-space: nowrap
width: 100%
text-align: center
line-height: 16px
复制代码
el.style.left = pixel.x - 42 + 'px'
el.style.top = pixel.y - 42 + 'px'
是为了让气泡覆盖物正中心在其坐标点的位置,因为css的宽高均为84px,效果如下:
区域气泡的交互
区域气泡显示之后,现在让我们为他们增加点交互吧~
就是鼠标滑入某个区域气泡的时候,该气泡高亮,滑出的时候恢复,一开始我用的是mouseover和mouseleave事件,让 zone-overlay 动态绑定class,但是我发现气泡背景色的变化没有缓动效果,
v-for="(item, index) in zoneGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item"
:class="zoneIndex === index ?'active':''"
@mouseover.native="selectZone(item, index)"
@mouseleave.native="cancelZone">
export default {
data () {
return {
zoneIndex: ''
}
},
methods: {
selectZone (item, index) {
this.zoneIndex = index
},
cancelZone () {
this.zoneIndex = ''
}
}
}
复制代码
修饰符native是为了让组件变成普通html标签,不然不会触发mouseover和mouseleave事件,效果如下:
为了增加缓动效果,后来我换用了css的hover伪类,取消鼠标事件,为了让大家看的清晰点,这里我设置了1s的缓动时间,
// zoneOverlay.vue
.zone
transition: background-color 1s ease-in-out
&:hover
z-index: 1
background-color: rgba(240,65,52,.9)
color: #fff
复制代码
效果如下:
再来点交互吧
我们希望当地图的缩放等级大于某一个值时,区域气泡消失,而小于该值时,区域气泡又出现,就像链家一样,在这个过程中我们就要实时获取地图当前的缩放等级 zoom,vue-baidu-map 给我们提供了一个api syncCenterAndZoom,具体使用如下:
v-for="(item, index) in zoneGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item">
复制代码// 双向绑定 zoom
// ZOOMBOUNDARY 为常量,表示区域气泡消失或显示的 zoom 临界值
// const ZOOMBOUNDARY = 15
syncCenterAndZoom (e) {
this.zoom = e.target.getZoom()
this.showZone = this.zoom < ZOOMBOUNDARY
}
复制代码
效果如下:
区域边界的显示
区域边界用到的是 bm-boundary 组件,当鼠标划入某个区域气泡时,该区域的边界出现,而当鼠标滑出某个区域气泡时,该区域的边界消失,
复制代码
参数说明:
name 表示区域(行政区)的名字,例如上海市黄浦区,北京市朝阳区
strokeWeight 表示区域边界的边框宽度
strokeColor 表示区域边界的边框颜色
fillColor 表示区域边界的填充颜色
fillOpacity 表示区域边界的填充颜色透明度
v-for="(item, index) in zoneGeoPoints" :key="index"
:position="{lng: item.lng, lat: item.lat}"
:text="item"
@mouseover.native="selectZone(item, index)"
@mouseleave.native="cancelZone">
export default {
data () {
return {
showBoundary: false
}
},
methods: {
selectZone (item, index) {
this.zoneBoundary = `${this.posCity}${item.name}` // 行政区名字,只供参考
this.showBoundary = true
},
cancelZone () {
this.zoneBoundary = ''
this.showBoundary = false
}
}
}
复制代码
效果如下:
至此,有关区域的实现和交互基本结束~
由于地图找房的功能稍微复杂,所以我将其分为几个部分,这样也能够更清楚如何一步步实现此功能,至于后续部分还请大家慢慢等待啦~
写得不好的地方请轻喷~感谢阅读
上一篇博文距离现在已经四个月了,一直想写些什么无奈工作比较忙碌。我的恩师老王在毕业聚餐那天带着一声酒气告诉我一定要把博客坚持写下去,所以今天下决心要开始这个新的篇章。之所以想要从头写一个关于JavaScript的系列是由于以下几个原因:1.JavaScript是Web程序员的核心技术2.很多人会使用JQuery写不错的特效却对JS中的继承、原型了解不多,本文旨在让本菜和大家一起提升“内...
特征提取SURF特征: http://www.vision.ee.ethz.ch/software/index.de.html(当然这只是其中之一)LBP特征(一种纹理特征):http://www.comp.hkbu.edu.hk/~icpr06/tutorials/Pietikainen.htmlFast Corner Detection(OpenCV中的Fast算法):FASTCorner Detection -- Edward Rosten机器视觉A simple object de
在开发中,我们经常会遇到使用Frame来工作,而且有时是为了跟其他网站集成,应用到多域的情况下,而Iframe是不能保存Session的。因此,网上可以找到很多相关的文章,如果网站可以采用设置Web.Config中的配置:<sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" s...
>>> from django_redis import get_redis_connection>>> r = get_redis_connection()>>> r.set('test', 1)Traceback (most recent call last): File "<console>", line 1, in <module> File "build/bdist.linux-x86_64/egg/red
1. 系统默认状态下不同ecore的引用是根据
ABAP子程序(Subrouting)是包含在程序中的一段具有一定功能的代码,能够将某个功能作为一个小程序包含在主程序中,以方便程序分析及阅读。特别是一此程序中多次用到的功能,可以简化代码,增加程序的可读性且便于维护。 1.子程序的定义 通过FORM...ENDFORM语名可以实现子程序的定义,通过PERFORM语句来实现子程序的调用。 [For Exa...
前言在我们编写程序并运行的时候,编译器给我们一个错觉:程序编译的顺序与编写的顺序是一致的。但是实际上,为了提高性能,编译器和处理器常常会对指令进行重排序。重排序主要分为两类:编译器优化的重排序、指令级别并行的重排序和内存系统的重排序。所以我们编写好Java源代码之后,会经过以上三个重排序,到最终的指令序列。我们这里提到的Java内存...
RK3566基于linux系统调试EEPROM
1.首先String不属于8种基本数据类型,String是一个对象。 因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。2.new String()和new String("")都是申明一个新的空字符串,是空串不是null;3.String str=”kvill”; String str=new Str
基于高通QCS平台的UEFI爬坑之旅开始爬坑之旅见闻UEFI介绍UEFI工程文件高通UEFI组成实现输出Log如何使用I2C由于项目要求,开始接触高通QCS平台上的UEFI,需求是产品通电后要通过I2C点亮LED,反馈给用户。接到任务后就正式开始这段艰难的爬坑之旅。爬坑之旅见闻UEFI介绍UEFI工程文件高通UEFI组成实现输出Log如何使用I2C文章将持续更新,谢谢支持!!!...
HTML内容多,学习过程更像是学习英语。很多内容学过很长时间后就会遗忘,重新复习起来,整理些精华给自己看。这次复习我选择了慕课网。很多内容都是在慕课网上摘抄,给自己整理成笔记。1.元素实际大小=border+padding+width/height2.块级元素 独占一行 可设置宽高 内联元素 可与其他元素占同一行 不能设置宽高 内联块元素
去年10月下旬正式工作,转眼间1年多的时光已经过去,借此博客对这1年的经历做个总结。趁机梳理下思路,继续前行。 去年7月份毕业,找工作并不是很顺利,于是趁机先了个驾照,10月23号才终于找到第一份工作,当时并没有过多奢求,也知道自己没什么本事,只想学点东西,涨点经验,所以并没有什么要求,勿打勿撞的在一家小网络公司做了ASP程序员,拿着800块钱的底薪在杭州这种高消费的