這里給大家分享我在網(wǎng)上總結(jié)出來的一些知識,希望對大家有所幫助
?
仿貝殼地圖畫圈找房功能實現(xiàn)(高德地圖)
前言
在最近租房時,看到貝殼找房上線了一個地圖畫圈找房的功能,感覺很是新奇。接觸地圖開發(fā)也有很長一段時間了,以前大部分都是基于web pc端開發(fā),所以一般遇到這種圈選,繪制多邊形圓形都是直接基于官方API直接修改使用的,對于PC端鼠標(biāo)操作來說,現(xiàn)有的交互用起來已經(jīng)很不錯了,但是對于H5移動端來說,只能通過手指觸摸來模擬鼠標(biāo)滑動,直接使用現(xiàn)有的API對于移動端交互體驗來說并不是特別好。因此,看到了貝殼找房上這一新穎的功能,確實讓我眼前一亮。話不多說,直接開搞,自己手動實現(xiàn)一個看看。有需要的小伙伴可以直接查看源碼demo:gitee.com/fcli/map-ed…
效果圖如下:
實現(xiàn)思路
剛看到這個功能時,腦海里閃過一個想法,點成線、線成面。既然是線,那肯定是由一堆點組成的,那最終的圈選的面,也是由線包圍起來的。然后一頓噼里啪啦操作,當(dāng)我在PC端模擬的時候發(fā)現(xiàn),并沒有那么絲滑,這不經(jīng)讓我思考如此絲滑的滑動體驗是怎么實現(xiàn)的,難道是通過畫板canvas之類的,然后通過獲取繪制的圈范圍再和地圖經(jīng)緯度重合計算。事實證明,我完全想多了,當(dāng)我把它放到H5上時,發(fā)現(xiàn)操作起來很絲滑,繪制的線段也是平滑的,這讓我醍醐灌頂。一頓測試發(fā)現(xiàn)PC端監(jiān)聽 mouseMove
事件并沒有移動端的touchmove
事件的觸發(fā)的那么頻繁,像是瀏覽器有節(jié)流之類的操作。
主要代碼
地圖初始化
首先,我使用vue3腳手架,所以在引入地圖時與官方demo不太一樣,通過createElement將地圖API加載到頁面上,并在地圖加載完畢后再觸發(fā)對應(yīng)的地圖操作。
onMounted(() => { //創(chuàng)建了一個回調(diào)函數(shù),高德地圖加載完畢會調(diào)用 window.onload = () => { // 所有關(guān)于地圖的邏輯全部都要寫在這個回調(diào)里面 // 保證高德地圖加載完畢 myMap.value = new AMap.Map('map', { resizeEnable: true, center: [121.429516, 31.151997], zoom: 13 }); drawMap(); }; // key是申請的值 let url = 'https://webapi.amap.com/maps?v=2.0&key=0cc611512938634634bac0969fdef3c1'; //創(chuàng)建一個 script dom元素 let jsapi = document.createElement('script'); //設(shè)定script標(biāo)簽屬性 jsapi.src = url; //將API文件引入頁面中,加載完畢以后會調(diào)用函數(shù) document.head.appendChild(jsapi); })
監(jiān)聽繪開始制地圖
當(dāng)開始繪制地圖時,先將地圖固定,即:不可縮放、不可拖動... 同時將之前繪制的圖層remove
myMap.value.on('touchstart', () => { myMap.value.setStatus({ showIndoorMap: false, dragEnable: false, keyboardEnable: false, doubleClickZoom: false, zoomEnable: false, rotateEnable: false }); if (lastPolyLine.value) { myMap.value.remove(lastPolyLine.value) } if (polygonAfterDraw.value) { myMap.value.remove(polygonAfterDraw.value) } lastPolyLine.value = null; polyPointArray.value = []; isMouseDown.value = true; });
監(jiān)聽繪制過程
當(dāng)開始繪制時,監(jiān)聽touchmove
事件,記錄每次move觸發(fā)的點并保存,通過這些點的集合繪制多邊形,每次繪制多邊形之前清除之前繪制的線段,在視覺上就能看到一條連續(xù)的線。
myMap.value.on('touchmove', (e: any) => { if (isMouseDown.value) { const point = [e.lnglat.lng, e.lnglat.lat] polyPointArray.value.push(point); if (lastPolyLine.value) { myMap.value.remove(lastPolyLine.value) } const polyline = new AMap.Polyline({ path: polyPointArray.value, //多邊形輪廓 isOutline: true, strokeColor: "#3366FF", strokeOpacity: 1, strokeWeight: 2, // 折線樣式還支持 'dashed' strokeStyle: "solid", // strokeStyle是dashed時有效 strokeDasharray: [15, 5], lineJoin: 'round', lineCap: 'round', zIndex: 50, }); myMap.value.add([polyline]) lastPolyLine.value = polyline; } })
繪制結(jié)束
繪制結(jié)束,使用線段的點生成一個面的范圍,通過這個范圍就能獲取到范圍內(nèi)的信息了,最后恢復(fù)地圖正常狀態(tài)。文章來源:http://www.zghlxwxcb.cn/news/detail-747383.html
document.addEventListener('touchend', () => { if (isMouseDown.value) { // 退出畫線狀態(tài) isMouseDown.value = false; // 添加多邊形覆蓋物,設(shè)置為禁止點擊 polygonAfterDraw.value = new AMap.Polygon({ fillOpacity: 0.5, fillColor: '#7bccc4', strokeOpacity: 1, strokeColor: '#3366FF', strokeWeight: 4, strokeStyle: 'solid', strokeDasharray: [5, 5], //多邊形數(shù)據(jù) path: polyPointArray.value //多邊形輪廓 }); myMap.value.add(polygonAfterDraw.value); if (lastPolyLine.value) { myMap.value.remove(lastPolyLine.value) } myMap.value.setStatus({ showIndoorMap: true, dragEnable: true, keyboardEnable: true, doubleClickZoom: true, zoomEnable: true, rotateEnable: true }); } });
本文轉(zhuǎn)載于:
https://juejin.cn/post/7306146705971085350
如果對您有所幫助,歡迎您點個關(guān)注,我會定時更新技術(shù)文檔,大家一起討論學(xué)習(xí),一起進步。
?文章來源地址http://www.zghlxwxcb.cn/news/detail-747383.html
到了這里,關(guān)于記錄--仿貝殼地圖畫圈找房功能實現(xiàn)(高德地圖)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!